From a417c80df67fd640a6f66fc4ef08c7f7ddc4bccd Mon Sep 17 00:00:00 2001 From: Trent Lloyd Date: Tue, 23 Aug 2005 19:31:53 +0000 Subject: * 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 --- avahi-client/Makefile.am | 2 +- avahi-client/browser.c | 3 + avahi-common/Makefile.am | 2 +- avahi-common/dbus.h | 3 + avahi-core/iface.c | 18 ++ avahi-core/iface.h | 2 + avahi-core/server.c | 94 +++++--- avahi-daemon/Server.introspect | 1 - avahi-daemon/dbus-protocol.c | 481 ++++++++++++++++++++++++++++++++++++++--- avahi-daemon/main.c | 12 +- 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 @@ - 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 ], [], @@ -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" -- cgit