diff options
| author | Trent Lloyd <lathiat@bur.st> | 2005-08-23 19:31:53 +0000 | 
|---|---|---|
| committer | Trent Lloyd <lathiat@bur.st> | 2005-08-23 19:31:53 +0000 | 
| commit | a417c80df67fd640a6f66fc4ef08c7f7ddc4bccd (patch) | |
| tree | da080a14abe966315007c054166e246de0f71cc7 | |
| parent | e5496ed08b66b68c487bce6dbf06504d2d1f42cd (diff) | |
 * Merge changes from trunk into netlink-abstraction
git-svn-id: file:///home/lennart/svn/public/avahi/branches/netlink-abstraction@428 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
| -rw-r--r-- | avahi-client/Makefile.am | 2 | ||||
| -rw-r--r-- | avahi-client/browser.c | 3 | ||||
| -rw-r--r-- | avahi-common/Makefile.am | 2 | ||||
| -rw-r--r-- | avahi-common/dbus.h | 3 | ||||
| -rw-r--r-- | avahi-core/iface.c | 18 | ||||
| -rw-r--r-- | avahi-core/iface.h | 2 | ||||
| -rw-r--r-- | avahi-core/server.c | 94 | ||||
| -rw-r--r-- | avahi-daemon/Server.introspect | 1 | ||||
| -rw-r--r-- | avahi-daemon/dbus-protocol.c | 481 | ||||
| -rw-r--r-- | avahi-daemon/main.c | 12 | ||||
| -rw-r--r-- | configure.ac | 13 | 
11 files changed, 552 insertions, 79 deletions
| diff --git a/avahi-client/Makefile.am b/avahi-client/Makefile.am index 1229862..cdc4442 100644 --- a/avahi-client/Makefile.am +++ b/avahi-client/Makefile.am @@ -41,7 +41,7 @@ libavahi_client_la_SOURCES = \  libavahi_client_la_CFLAGS = $(AM_CFLAGS) $(DBUS_CFLAGS)  libavahi_client_la_LIBADD = $(AM_LDADD) $(DBUS_LIBS) ../avahi-common/libavahi-common.la ../avahi-common/libdbus-common-pic.la -libavahi_client_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -version-info 0:0:0 +libavahi_client_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -version-info 1:0:1  client_test_SOURCES = client-test.c  client_test_CFLAGS = $(AM_CFLAGS)  diff --git a/avahi-client/browser.c b/avahi-client/browser.c index 5de4824..9a7438e 100644 --- a/avahi-client/browser.c +++ b/avahi-client/browser.c @@ -573,6 +573,9 @@ DBusHandlerResult avahi_service_browser_event (AvahiClient *client, AvahiBrowser          if (strcmp (b->path, path) == 0)              break; +    if (!b) +        goto fail; +      if (!dbus_message_get_args (                message, &error,                DBUS_TYPE_INT32, &interface, diff --git a/avahi-common/Makefile.am b/avahi-common/Makefile.am index 5556ff4..66e36d4 100644 --- a/avahi-common/Makefile.am +++ b/avahi-common/Makefile.am @@ -63,7 +63,7 @@ libavahi_common_la_SOURCES = \  	watch.h gccmacro.h  libavahi_common_la_CFLAGS = $(AM_CFLAGS) -libavahi_common_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -version-info 0:0:0 +libavahi_common_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -version-info 1:0:1  strlst_test_SOURCES = \  	strlst.c strlst.h \ diff --git a/avahi-common/dbus.h b/avahi-common/dbus.h index bcbbb99..cdfef4d 100644 --- a/avahi-common/dbus.h +++ b/avahi-common/dbus.h @@ -38,6 +38,9 @@ AVAHI_C_DECL_BEGIN  #define AVAHI_DBUS_INTERFACE_DOMAIN_BROWSER AVAHI_DBUS_NAME".DomainBrowser"  #define AVAHI_DBUS_INTERFACE_SERVICE_TYPE_BROWSER AVAHI_DBUS_NAME".ServiceTypeBrowser"  #define AVAHI_DBUS_INTERFACE_SERVICE_BROWSER AVAHI_DBUS_NAME".ServiceBrowser" +#define AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER AVAHI_DBUS_NAME".AddressResolver" +#define AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER AVAHI_DBUS_NAME".HostNameResolver" +#define AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER AVAHI_DBUS_NAME".ServiceResolver"  #define AVAHI_DBUS_ERR_FAILURE "org.freedesktop.Avahi.Failure"  #define AVAHI_DBUS_ERR_BAD_STATE "org.freedesktop.Avahi.BadStateError" diff --git a/avahi-core/iface.c b/avahi-core/iface.c index f5373e6..f9c3103 100644 --- a/avahi-core/iface.c +++ b/avahi-core/iface.c @@ -823,3 +823,21 @@ int avahi_interface_address_on_link(AvahiInterface *i, const AvahiAddress *a) {      return 0;  } + +int avahi_interface_has_address(AvahiInterfaceMonitor *m, AvahiIfIndex iface, const AvahiAddress *a) { +    AvahiInterface *i; +    AvahiInterfaceAddress *j; +     +    assert(m); +    assert(iface != AVAHI_IF_UNSPEC); +    assert(a); + +    if (!(i = avahi_interface_monitor_get_interface(m, iface, a->family))) +        return 0; + +    for (j = i->addresses; j; j = j->address_next) +        if (avahi_address_cmp(a, &j->address) == 0) +            return 1; + +    return 0; +} diff --git a/avahi-core/iface.h b/avahi-core/iface.h index c913a2e..b78c76a 100644 --- a/avahi-core/iface.h +++ b/avahi-core/iface.h @@ -138,4 +138,6 @@ int avahi_address_is_local(AvahiInterfaceMonitor *m, const AvahiAddress *a);  int avahi_interface_address_on_link(AvahiInterface *i, const AvahiAddress *a); +int avahi_interface_has_address(AvahiInterfaceMonitor *m, AvahiIfIndex iface, const AvahiAddress *a); +  #endif diff --git a/avahi-core/server.c b/avahi-core/server.c index 4c55edb..dbb861d 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -564,7 +564,7 @@ static void reflect_probe(AvahiServer *s, AvahiInterface *i, AvahiRecord *r) {              avahi_interface_post_probe(j, r, 1);  } -static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, uint16_t port, int legacy_unicast) { +static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, uint16_t port, int legacy_unicast, int from_local_iface) {      size_t n;      int is_probe; @@ -589,7 +589,7 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac              goto fail;          } -        if (!legacy_unicast) +        if (!legacy_unicast && !from_local_iface)              reflect_query(s, i, key);          if (avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT) == 0 && @@ -602,40 +602,44 @@ static void handle_query_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterfac          avahi_key_unref(key);      } -    /* Known Answer Suppression */ -    for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT); n > 0; n --) { -        AvahiRecord *record; -        int unique = 0; +    if (!legacy_unicast) { -        if (!(record = avahi_dns_packet_consume_record(p, &unique))) { -            avahi_log_warn("Packet too short (2)"); -            goto fail; -        } - -        if (handle_conflict(s, i, record, unique, a)) { -            avahi_response_scheduler_suppress(i->response_scheduler, record, a); -            avahi_record_list_drop(s->record_list, record); +        /* Known Answer Suppression */ +        for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_ANCOUNT); n > 0; n --) { +            AvahiRecord *record; +            int unique = 0; +             +            if (!(record = avahi_dns_packet_consume_record(p, &unique))) { +                avahi_log_warn("Packet too short (2)"); +                goto fail; +            } +             +            if (handle_conflict(s, i, record, unique, a)) { +                avahi_response_scheduler_suppress(i->response_scheduler, record, a); +                avahi_record_list_drop(s->record_list, record); +            } +             +            avahi_record_unref(record);          } -        avahi_record_unref(record); -    } - -    /* Probe record */ -    for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT); n > 0; n --) { -        AvahiRecord *record; -        int unique = 0; - -        if (!(record = avahi_dns_packet_consume_record(p, &unique))) { -            avahi_log_warn("Packet too short (3)"); -            goto fail; -        } - -        if (!avahi_key_is_pattern(record->key)) { -            reflect_probe(s, i, record); -            incoming_probe(s, record, i); +        /* Probe record */ +        for (n = avahi_dns_packet_get_field(p, AVAHI_DNS_FIELD_NSCOUNT); n > 0; n --) { +            AvahiRecord *record; +            int unique = 0; +             +            if (!(record = avahi_dns_packet_consume_record(p, &unique))) { +                avahi_log_warn("Packet too short (3)"); +                goto fail; +            } +             +            if (!avahi_key_is_pattern(record->key)) { +                if (!from_local_iface) +                    reflect_probe(s, i, record); +                incoming_probe(s, record, i); +            } +             +            avahi_record_unref(record);          } -         -        avahi_record_unref(record);      }      if (!avahi_record_list_is_empty(s->record_list)) @@ -647,7 +651,7 @@ fail:      avahi_record_list_flush(s->record_list);  } -static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a) { +static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInterface *i, const AvahiAddress *a, int from_local_iface) {      unsigned n;      assert(s); @@ -674,7 +678,8 @@ static void handle_response_packet(AvahiServer *s, AvahiDnsPacket *p, AvahiInter  /*             avahi_free(txt); */              if (handle_conflict(s, i, record, cache_flush, a)) { -                reflect_response(s, i, record, cache_flush); +                if (!from_local_iface) +                    reflect_response(s, i, record, cache_flush);                  avahi_cache_update(i->cache, record, cache_flush, a);                  avahi_response_scheduler_incoming(i->response_scheduler, record, cache_flush);              } @@ -877,10 +882,23 @@ static int is_mdns_mcast_address(const AvahiAddress *a) {      return avahi_address_cmp(a, &b) == 0;  } +static int originates_from_local_iface(AvahiServer *s, AvahiIfIndex iface, const AvahiAddress *a, uint16_t port) { +    assert(s); +    assert(iface != AVAHI_IF_UNSPEC); +    assert(a); + +    /* If it isn't the MDNS port it can't be generated by us */ +    if (port != AVAHI_MDNS_PORT) +        return 0; + +    return avahi_interface_has_address(s->monitor, iface, a); +} +  static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sockaddr *sa, AvahiAddress *dest, AvahiIfIndex iface, int ttl) {      AvahiInterface *i;      AvahiAddress a;      uint16_t port; +    int from_local_iface = 0;      assert(s);      assert(p); @@ -907,6 +925,10 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock          /* This originates from our local reflector, so let's ignore it */          return; +    /* We don't want to reflect local traffic, so we check if this packet is generated locally. */ +    if (s->config.enable_reflector) +        from_local_iface = originates_from_local_iface(s, iface, &a, port); +      if (avahi_dns_packet_is_valid(p) < 0) {          avahi_log_warn("Recieved invalid packet.");          return; @@ -935,7 +957,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock          if (legacy_unicast)              reflect_legacy_unicast_query_packet(s, p, i, &a, port); -        handle_query_packet(s, p, i, &a, port, legacy_unicast); +        handle_query_packet(s, p, i, &a, port, legacy_unicast, from_local_iface);  /*         avahi_log_debug("Handled query"); */      } else { @@ -962,7 +984,7 @@ static void dispatch_packet(AvahiServer *s, AvahiDnsPacket *p, const struct sock              return;          } -        handle_response_packet(s, p, i, &a); +        handle_response_packet(s, p, i, &a, from_local_iface);  /*         avahi_log_debug("Handled response"); */      }  } diff --git a/avahi-daemon/Server.introspect b/avahi-daemon/Server.introspect index da1b6fb..9ce3259 100644 --- a/avahi-daemon/Server.introspect +++ b/avahi-daemon/Server.introspect @@ -127,7 +127,6 @@        <arg name="path" type="o" direction="out"/>      </method> -      <method name="ServiceResolverNew">        <arg name="interface" type="i" direction="in"/>        <arg name="protocol" type="i" direction="in"/> diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c index 36ad690..8a0bd55 100644 --- a/avahi-daemon/dbus-protocol.c +++ b/avahi-daemon/dbus-protocol.c @@ -198,7 +198,7 @@ static void entry_group_free(EntryGroupInfo *i) {      assert(i->client->n_objects >= 0);      avahi_free(i); - } +}  static void sync_host_name_resolver_free(SyncHostNameResolverInfo *i) {      assert(i); @@ -838,7 +838,7 @@ fail:      return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;  } -static void host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) { +static void sync_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) {      SyncHostNameResolverInfo *i = userdata;      assert(r); @@ -878,7 +878,7 @@ static void host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex      sync_host_name_resolver_free(i);  } -static void address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) { +static void sync_address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) {      SyncAddressResolverInfo *i = userdata;      assert(r); @@ -1127,7 +1127,28 @@ static void service_browser_callback(AvahiSServiceBrowser *b, AvahiIfIndex inter      dbus_message_unref(m);  } -static void service_resolver_callback( +static void append_string_list(DBusMessage *reply, AvahiStringList *txt) { +    AvahiStringList *p; +    DBusMessageIter iter, sub; +     +    assert(reply); + +    dbus_message_iter_init_append(reply, &iter); +    dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub); +     +    for (p = txt; p; p = p->next) { +        DBusMessageIter sub2; +        const uint8_t *data = p->text; +         +        dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2); +        dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size);  +        dbus_message_iter_close_container(&sub, &sub2); +         +    } +    dbus_message_iter_close_container(&iter, &sub); +} + +static void sync_service_resolver_callback(      AvahiSServiceResolver *r,      AvahiIfIndex interface,      AvahiProtocol protocol, @@ -1149,11 +1170,8 @@ static void service_resolver_callback(      if (event == AVAHI_RESOLVER_FOUND) {          char t[256], *pt = t;          int32_t i_interface, i_protocol, i_aprotocol; -        unsigned n, j; -        AvahiStringList *p;          DBusMessage *reply; -        DBusMessageIter iter, sub; - +              assert(host_name);          assert(a); @@ -1177,19 +1195,7 @@ static void service_resolver_callback(              DBUS_TYPE_UINT16, &port,              DBUS_TYPE_INVALID); -        dbus_message_iter_init_append(reply, &iter); -        dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub); - -        for (p = txt, j = n-1; p; p = p->next, j--) { -            DBusMessageIter sub2; -            const uint8_t *data = p->text; -             -            dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2); -            dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size);  -            dbus_message_iter_close_container(&sub, &sub2); - -        } -        dbus_message_iter_close_container(&iter, &sub); +        append_string_list(reply, txt);          dbus_connection_send(server->bus, reply, NULL);          dbus_message_unref(reply); @@ -1202,6 +1208,273 @@ static void service_resolver_callback(      sync_service_resolver_free(i);  } +static void async_address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) { +    AsyncAddressResolverInfo *i = userdata; +    DBusMessage *reply; +     +    assert(r); +    assert(address); +    assert(i); + +    if (event == AVAHI_RESOLVER_FOUND) { +        char t[256], *pt = t; +        int32_t i_interface, i_protocol, i_aprotocol; + +        assert(host_name); +        avahi_address_snprint(t, sizeof(t), address); + +        i_interface = (int32_t) interface; +        i_protocol = (int32_t) protocol; +        i_aprotocol = (int32_t) address->family; +         +        reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Found"); +        dbus_message_append_args( +            reply, +            DBUS_TYPE_INT32, &i_interface, +            DBUS_TYPE_INT32, &i_protocol, +            DBUS_TYPE_INT32, &i_aprotocol, +            DBUS_TYPE_STRING, &pt, +            DBUS_TYPE_STRING, &host_name, +            DBUS_TYPE_INVALID); + +    } else { +        assert(event == AVAHI_RESOLVER_TIMEOUT); + +        reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Timeout"); +    } + +    dbus_connection_send(server->bus, reply, NULL); +    dbus_message_unref(reply); +} + +static DBusHandlerResult msg_async_address_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) { +    DBusError error; +    AsyncAddressResolverInfo *i = userdata; + +    assert(c); +    assert(m); +    assert(i); +     +    dbus_error_init(&error); + +    avahi_log_debug("dbus: interface=%s, path=%s, member=%s", +                    dbus_message_get_interface(m), +                    dbus_message_get_path(m), +                    dbus_message_get_member(m)); + +    /* Introspection */ +    if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) +        return handle_introspect(c, m, "AddressResolver.Introspect"); +     +    /* Access control */ +    if (strcmp(dbus_message_get_sender(m), i->client->name))  +        return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); +     +    if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Free")) { + +        if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { +            avahi_log_warn("Error parsing AddressResolver::Free message"); +            goto fail; +        } + +        async_address_resolver_free(i); +        return respond_ok(c, m); +         +    } +     +    avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); + +fail: +    if (dbus_error_is_set(&error)) +        dbus_error_free(&error); +     +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void async_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) { +    AsyncHostNameResolverInfo *i = userdata; +    DBusMessage *reply; +     +    assert(r); +    assert(host_name); +    assert(i); + +    if (event == AVAHI_RESOLVER_FOUND) { +        char t[256], *pt = t; +        int32_t i_interface, i_protocol, i_aprotocol; + +        assert(a); +        avahi_address_snprint(t, sizeof(t), a); + +        i_interface = (int32_t) interface; +        i_protocol = (int32_t) protocol; +        i_aprotocol = (int32_t) a->family; +         +        reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Found"); +        dbus_message_append_args( +            reply, +            DBUS_TYPE_INT32, &i_interface, +            DBUS_TYPE_INT32, &i_protocol, +            DBUS_TYPE_STRING, &host_name, +            DBUS_TYPE_INT32, &i_aprotocol, +            DBUS_TYPE_STRING, &pt, +            DBUS_TYPE_INVALID); +    } else { +        assert(event == AVAHI_RESOLVER_TIMEOUT); + +        reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Timeout"); +    } + +    dbus_connection_send(server->bus, reply, NULL); +    dbus_message_unref(reply); +} + +static DBusHandlerResult msg_async_host_name_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) { +    DBusError error; +    AsyncHostNameResolverInfo *i = userdata; + +    assert(c); +    assert(m); +    assert(i); +     +    dbus_error_init(&error); + +    avahi_log_debug("dbus: interface=%s, path=%s, member=%s", +                    dbus_message_get_interface(m), +                    dbus_message_get_path(m), +                    dbus_message_get_member(m)); + +    /* Introspection */ +    if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) +        return handle_introspect(c, m, "HostNameResolver.Introspect"); +     +    /* Access control */ +    if (strcmp(dbus_message_get_sender(m), i->client->name))  +        return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); +     +    if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Free")) { + +        if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { +            avahi_log_warn("Error parsing HostNameResolver::Free message"); +            goto fail; +        } + +        async_host_name_resolver_free(i); +        return respond_ok(c, m); +    } +     +    avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); + +fail: +    if (dbus_error_is_set(&error)) +        dbus_error_free(&error); +     +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +static void async_service_resolver_callback( +    AvahiSServiceResolver *r, +    AvahiIfIndex interface, +    AvahiProtocol protocol, +    AvahiResolverEvent event, +    const char *name, +    const char *type, +    const char *domain, +    const char *host_name, +    const AvahiAddress *a, +    uint16_t port, +    AvahiStringList *txt, +    void* userdata) { + +    AsyncServiceResolverInfo *i = userdata; +    DBusMessage *reply; +     +    assert(r); +    assert(host_name); +    assert(i); + +    if (event == AVAHI_RESOLVER_FOUND) { +        char t[256], *pt = t; +        int32_t i_interface, i_protocol, i_aprotocol; +     +        assert(host_name); +         +        assert(a); +        avahi_address_snprint(t, sizeof(t), a); + +        i_interface = (int32_t) interface; +        i_protocol = (int32_t) protocol; +        i_aprotocol = (int32_t) a->family; + +        reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Found"); +        dbus_message_append_args( +            reply, +            DBUS_TYPE_INT32, &i_interface, +            DBUS_TYPE_INT32, &i_protocol, +            DBUS_TYPE_STRING, &name, +            DBUS_TYPE_STRING, &type, +            DBUS_TYPE_STRING, &domain, +            DBUS_TYPE_STRING, &host_name, +            DBUS_TYPE_INT32, &i_aprotocol, +            DBUS_TYPE_STRING, &pt, +            DBUS_TYPE_UINT16, &port, +            DBUS_TYPE_INVALID); + +        append_string_list(reply, txt); +         +    } else { +        assert(event == AVAHI_RESOLVER_TIMEOUT); + +        reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Timeout"); +    } + +    dbus_connection_send(server->bus, reply, NULL); +    dbus_message_unref(reply); +} + +static DBusHandlerResult msg_async_service_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) { +    DBusError error; +    AsyncServiceResolverInfo *i = userdata; + +    assert(c); +    assert(m); +    assert(i); +     +    dbus_error_init(&error); + +    avahi_log_debug("dbus: interface=%s, path=%s, member=%s", +                    dbus_message_get_interface(m), +                    dbus_message_get_path(m), +                    dbus_message_get_member(m)); + +    /* Introspection */ +    if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) +        return handle_introspect(c, m, "ServiceResolver.Introspect"); +     +    /* Access control */ +    if (strcmp(dbus_message_get_sender(m), i->client->name))  +        return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL); +     +    if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free")) { + +        if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) { +            avahi_log_warn("Error parsing ServiceResolver::Free message"); +            goto fail; +        } + +        async_service_resolver_free(i); +        return respond_ok(c, m); +    } +     +    avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); + +fail: +    if (dbus_error_is_set(&error)) +        dbus_error_free(&error); +     +    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} +  static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) {      DBusError error; @@ -1435,7 +1708,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          AVAHI_LLIST_PREPEND(SyncHostNameResolverInfo, sync_host_name_resolvers, client->sync_host_name_resolvers, i);          client->n_objects++; -        if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, host_name_resolver_callback, i))) { +        if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, sync_host_name_resolver_callback, i))) {              sync_host_name_resolver_free(i);              return respond_error(c, m, avahi_server_errno(avahi_server), NULL);          } @@ -1478,7 +1751,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          AVAHI_LLIST_PREPEND(SyncAddressResolverInfo, sync_address_resolvers, client->sync_address_resolvers, i);          client->n_objects++; -        if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, address_resolver_callback, i))) { +        if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, sync_address_resolver_callback, i))) {              sync_address_resolver_free(i);              return respond_error(c, m, avahi_server_errno(avahi_server), NULL);          } @@ -1499,7 +1772,6 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          int32_t interface, protocol, type;          char *domain; -          if (!dbus_message_get_args(                  m, &error,                  DBUS_TYPE_INT32, &interface, @@ -1592,7 +1864,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          dbus_connection_register_object_path(c, i->path, &vtable, i);          return respond_path(c, m, i->path); -     } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew")) { +    } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew")) {          Client *client;          ServiceBrowserInfo *i;          static const DBusObjectPathVTable vtable = { @@ -1684,13 +1956,168 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          AVAHI_LLIST_PREPEND(SyncServiceResolverInfo, sync_service_resolvers, client->sync_service_resolvers, i);          client->n_objects++; -        if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) { +        if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, sync_service_resolver_callback, i))) {              sync_service_resolver_free(i);              return respond_error(c, m, avahi_server_errno(avahi_server), NULL);          }          return DBUS_HANDLER_RESULT_HANDLED; -     } +         +    } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceResolverNew")) { +        Client *client; +        int32_t interface, protocol, aprotocol; +        char *name, *type, *domain; +        AsyncServiceResolverInfo *i; +        static const DBusObjectPathVTable vtable = { +            NULL, +            msg_async_service_resolver_impl, +            NULL, +            NULL, +            NULL, +            NULL +        }; + +        if (!dbus_message_get_args( +                m, &error, +                DBUS_TYPE_INT32, &interface, +                DBUS_TYPE_INT32, &protocol, +                DBUS_TYPE_STRING, &name, +                DBUS_TYPE_STRING, &type, +                DBUS_TYPE_STRING, &domain, +                DBUS_TYPE_INT32, &aprotocol, +                DBUS_TYPE_INVALID) || !name || !type) { +            avahi_log_warn("Error parsing Server::ServiceResolverNew message"); +            goto fail; +        } +             +        if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { +            avahi_log_warn(__FILE__": Too many clients, client request failed."); +            return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); +        } + +        if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { +            avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name); +            return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); +        } + +        i = avahi_new(AsyncServiceResolverInfo, 1); +        i->id = ++client->current_id; +        i->client = client; +        i->path = avahi_strdup_printf("/Client%u/ServiceResolver%u", client->id, i->id); +        AVAHI_LLIST_PREPEND(AsyncServiceResolverInfo, async_service_resolvers, client->async_service_resolvers, i); +        client->n_objects++; + +        if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, async_service_resolver_callback, i))) { +            async_service_resolver_free(i); +            return respond_error(c, m, avahi_server_errno(avahi_server), NULL); +        } +         +        dbus_connection_register_object_path(c, i->path, &vtable, i); +        return respond_path(c, m, i->path); + +    } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew")) { +        Client *client; +        int32_t interface, protocol, aprotocol; +        char *name; +        AsyncHostNameResolverInfo *i; +        static const DBusObjectPathVTable vtable = { +            NULL, +            msg_async_host_name_resolver_impl, +            NULL, +            NULL, +            NULL, +            NULL +        }; +             +        if (!dbus_message_get_args( +                m, &error, +                DBUS_TYPE_INT32, &interface, +                DBUS_TYPE_INT32, &protocol, +                DBUS_TYPE_STRING, &name, +                DBUS_TYPE_INT32, &aprotocol, +                DBUS_TYPE_INVALID) || !name) { +            avahi_log_warn("Error parsing Server::HostNameResolverNew message"); +            goto fail; +        } +             +        if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { +            avahi_log_warn(__FILE__": Too many clients, client request failed."); +            return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); +        } + +        if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { +            avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name); +            return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); +        } + +        i = avahi_new(AsyncHostNameResolverInfo, 1); +        i->id = ++client->current_id; +        i->client = client; +        i->path = avahi_strdup_printf("/Client%u/HostNameResolver%u", client->id, i->id); +        AVAHI_LLIST_PREPEND(AsyncHostNameResolverInfo, async_host_name_resolvers, client->async_host_name_resolvers, i); +        client->n_objects++; + +        if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, aprotocol, async_host_name_resolver_callback, i))) { +            async_host_name_resolver_free(i); +            return respond_error(c, m, avahi_server_errno(avahi_server), NULL); +        } +         +        dbus_connection_register_object_path(c, i->path, &vtable, i); +        return respond_path(c, m, i->path); + +    } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "AddressResolverNew")) { +        Client *client; +        int32_t interface, protocol; +        char *address; +        AsyncAddressResolverInfo *i; +        AvahiAddress a; +        static const DBusObjectPathVTable vtable = { +            NULL, +            msg_async_address_resolver_impl, +            NULL, +            NULL, +            NULL, +            NULL +        }; +             +        if (!dbus_message_get_args( +                m, &error, +                DBUS_TYPE_INT32, &interface, +                DBUS_TYPE_INT32, &protocol, +                DBUS_TYPE_STRING, &address, +                DBUS_TYPE_INVALID) || !address) { +            avahi_log_warn("Error parsing Server::AddressResolverNew message"); +            goto fail; +        } + +        if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a)) +            return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL); + +        if (!(client = client_get(dbus_message_get_sender(m), TRUE))) { +            avahi_log_warn(__FILE__": Too many clients, client request failed."); +            return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL); +        } + +        if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) { +            avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name); +            return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL); +        } + +        i = avahi_new(AsyncAddressResolverInfo, 1); +        i->id = ++client->current_id; +        i->client = client; +        i->path = avahi_strdup_printf("/Client%u/AddressResolver%u", client->id, i->id); +        AVAHI_LLIST_PREPEND(AsyncAddressResolverInfo, async_address_resolvers, client->async_address_resolvers, i); +        client->n_objects++; + +        if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, async_address_resolver_callback, i))) { +            async_address_resolver_free(i); +            return respond_error(c, m, avahi_server_errno(avahi_server), NULL); +        } +         +        dbus_connection_register_object_path(c, i->path, &vtable, i); +        return respond_path(c, m, i->path); +    }      avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m)); diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c index 4c3a069..9f7b847 100644 --- a/avahi-daemon/main.c +++ b/avahi-daemon/main.c @@ -383,7 +383,6 @@ static int load_config_file(DaemonConfig *c) {                      c->server_config.check_response_ttl = is_yes(p->value);                  else if (strcasecmp(p->key, "use-iff-running") == 0)                      c->server_config.use_iff_running = is_yes(p->value); -#ifdef HAVE_DBUS                                  else if (strcasecmp(p->key, "enable-dbus") == 0) {                      if (*(p->value) == 'w' || *(p->value) == 'W') { @@ -392,11 +391,10 @@ static int load_config_file(DaemonConfig *c) {                      } else if (*(p->value) == 'y' || *(p->value) == 'Y') {                          c->fail_on_missing_dbus = 1;                          c->enable_dbus = 1; -                    } else +                    } else {                          c->enable_dbus = 0; -                     +                    }                  } -#endif                  else if (strcasecmp(p->key, "drop-root") == 0)                      c->drop_root = is_yes(p->value);                  else { @@ -599,9 +597,8 @@ static int run_server(DaemonConfig *c) {      if (simple_protocol_setup(poll_api) < 0)          goto finish; -     +    if (c->enable_dbus) {  #ifdef HAVE_DBUS -    if (c->enable_dbus)          if (dbus_protocol_setup(poll_api) < 0) {              if (c->fail_on_missing_dbus) @@ -610,7 +607,10 @@ static int run_server(DaemonConfig *c) {              avahi_log_warn("WARNING: Failed to contact D-BUS daemon, disabling D-BUS support.");              c->enable_dbus = 0;          } +#else +        avahi_log_warn("WARNING: We are configured to enable D-BUS but it was not compiled in");  #endif +    }      load_resolv_conf(c);      static_service_load(); diff --git a/configure.ac b/configure.ac index 2300100..be62e38 100644 --- a/configure.ac +++ b/configure.ac @@ -47,7 +47,7 @@ AC_PROG_GCC_TRADITIONAL  AC_PROG_LIBTOOL  # -# Detecting the linux distro for specific things like initscripts. +# Detecting the linux distribution for specific things like init scripts.  #  AC_ARG_WITH(distro, AS_HELP_STRING([--with-distro=DISTRO],[Specify the Linux distribution to target: One of debian, gentoo, archlinux or none]))  if test "z$with_distro" = "z"; then @@ -59,14 +59,14 @@ fi  with_distro=`echo ${with_distro} | tr '[[:upper:]]' '[[:lower:]]' `  if test "z$with_distro" = "z"; then -   echo "Linux distribution autodetection failed, you must specify the distribution to target using --with-distro=DISTRO" +   AC_MSG_ERROR([Linux distribution autodetection failed, you must specify the distribution to target using --with-distro=DISTRO])     exit 1  else  case $with_distro in     debian|gentoo|archlinux)       ;;     *) -     echo "Your distribution (${with_distro}) is not yet supported, init scripts and dbus configuration will not be installed! (patches welcome)" +     AC_MSG_ERROR([Your distribution (${with_distro}) is not yet supported, init scripts and dbus configuration will not be installed! (patches welcome)])       ;;  esac  fi @@ -76,7 +76,6 @@ AM_CONDITIONAL(TARGET_GENTOO, test x"$with_distro" = xgentoo)  AM_CONDITIONAL(TARGET_DEBIAN, test x"$with_distro" = xdebian)  AM_CONDITIONAL(TARGET_ARCHLINUX, test x"$with_distro" = xarchlinux) -  test_gcc_flag() {     AC_LANG_CONFTEST([int main() {}])     $CC -c conftest.c $CFLAGS $@ > /dev/null 2> /dev/null @@ -93,7 +92,7 @@ if test "x$GCC" = "xyes" ; then      # Test whether rtnetlink.h can be included when compiled with -std=c99      # some distributions (e.g. archlinux) have broken headers that dont      # define __u64 with -std=c99 -    echo -n "checking whether rtnetlink.h can be included with -std=c99... " +    AC_MSG_CHECKING([checking whether rtnetlink.h can be included with -std=c99])      OLDCFLAGS="$CFLAGS"      CFLAGS="-std=c99"      AC_TRY_COMPILE([#include <linux/rtnetlink.h>], [], @@ -101,9 +100,9 @@ if test "x$GCC" = "xyes" ; then      if test x"$use_stdc99" = xyes; then          DESIRED_FLAGS="-std=c99 $DESIRED_FLAGS" -        echo "yes" +        AC_MSG_RESULT([yes])      else -        echo "no" +        AC_MSG_RESULT([no])      fi      CFLAGS="$OLDCFLAGS" | 
