10139N/A--- avahi-0.6.28/avahi-core/browse-service.c.orig 2010-08-26 01:51:38.983153000 +0100
10139N/A+++ avahi-0.6.28/avahi-core/browse-service.c 2011-01-20 09:22:41.808471289 +0000
10139N/A@@ -21,10 +21,14 @@
10139N/A #include <config.h>
10139N/A #endif
10139N/A
10139N/A+#include <stdio.h>
10139N/A #include <string.h>
10139N/A
10139N/A #include <avahi-common/domain.h>
10139N/A #include <avahi-common/malloc.h>
10139N/A+#ifdef HAVE_BONJOUR
13352N/A+#include <avahi-common/timeval.h>
10139N/A+#endif
10139N/A #include <avahi-common/error.h>
10139N/A
10139N/A #include "browse.h"
10139N/A@@ -40,9 +44,131 @@
10139N/A AvahiSServiceBrowserCallback callback;
10139N/A void* userdata;
10139N/A
10139N/A+#ifdef HAVE_BONJOUR
10139N/A+ AvahiProtocol protocol;
10139N/A+ AvahiIfIndex interface;
10139N/A+ AvahiTimeEvent *browse_error_event;
10139N/A+ AvahiTimeEvent *all_for_now_event;
10139N/A+ AvahiLookupFlags flags;
10139N/A+ AvahiWatch *watch;
10139N/A+ DNSServiceRef client;
10139N/A+#endif
10139N/A+
10139N/A AVAHI_LLIST_FIELDS(AvahiSServiceBrowser, browser);
10139N/A };
10139N/A
10139N/A+#ifdef HAVE_BONJOUR
10392N/A+static void browse_reply(DNSServiceRef client, const DNSServiceFlags flags, uint32_t IfIndex, DNSServiceErrorType errorCode,
10139N/A+ const char *name, const char *type, const char *domain, void *context) {
10139N/A+ AvahiSServiceBrowser *b = context;
10139N/A+ char *op = (flags &kDNSServiceFlagsAdd) ? "Add" : "Rmv";
10139N/A+ AvahiBrowserEvent event;
10139N/A+ AvahiIfIndex interface;
10139N/A+
10139N/A+ interface = (IfIndex == kDNSServiceInterfaceIndexAny) ? AVAHI_IF_UNSPEC : IfIndex;
10139N/A+
10139N/A+ event = (flags &kDNSServiceFlagsAdd) ? AVAHI_BROWSER_NEW : AVAHI_BROWSER_REMOVE;
10139N/A+
10139N/A+ b->callback(b, interface, AVAHI_PROTO_UNSPEC, event, name, type, domain, 0, b->userdata);
10139N/A+
10139N/A+}
10139N/A+
10139N/A+static void browse_socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events, void *userdata) {
10139N/A+ AvahiSServiceBrowser *b = userdata;
13352N/A+ DNSServiceErrorType ret;
13352N/A+
12046N/A+ assert(w);
12046N/A+ assert(fd >= 0);
10392N/A+ assert(events & AVAHI_WATCH_IN);
10392N/A+
10139N/A+ assert (fd == DNSServiceRefSockFD(b->client));
10139N/A+ ret = DNSServiceProcessResult(b->client);
10139N/A+ if (ret != kDNSServiceErr_NoError) {
10139N/A+ if (b->watch) {
10139N/A+ b->server->poll_api->watch_free(b->watch);
10139N/A+ b->watch = NULL;
10139N/A+ }
10139N/A+ DNSServiceRefDeallocate(b->client);
+ b->client = NULL;
+ avahi_server_set_errno(b->server, AVAHI_ERR_DISCONNECTED);
+ b->callback(b,
+ b->interface,
+ b->protocol,
+ AVAHI_BROWSER_FAILURE,
+ NULL,
+ b->service_type,
+ b->domain_name,
+ 0,
+ b->userdata);
+ }
+}
+
+static void all_for_now_callback(AvahiTimeEvent *e, void* userdata) {
+ AvahiSServiceBrowser *b = userdata;
+
+ assert(e);
+ assert(b);
+
+ avahi_time_event_free(b->all_for_now_event);
+ b->all_for_now_event = NULL;
+
+ b->callback(b,
+ b->interface,
+ b->protocol,
+ AVAHI_BROWSER_ALL_FOR_NOW,
+ NULL,
+ b->service_type,
+ NULL,
+ 0,
+ b->userdata);
+}
+
+static void browse_error_callback(AvahiTimeEvent *e, void *userdata) {
+ AvahiSServiceBrowser *b = userdata;
+
+ if (b->browse_error_event) {
+ avahi_time_event_free(b->browse_error_event);
+ b->browse_error_event = NULL;
+ }
+ avahi_server_set_errno(b->server, AVAHI_ERR_FAILURE);
+ b->callback(b,
+ b->interface,
+ b->protocol,
+ AVAHI_BROWSER_FAILURE,
+ NULL,
+ b->service_type,
+ b->domain_name,
+ 0,
+ b->userdata);
+}
+
+static void avahi_browse_service_start(AvahiSServiceBrowser *b) {
+ DNSServiceErrorType ret;
+ struct timeval tv;
+
+ ret = DNSServiceBrowse(&b->client,
+ 0,
+ b->interface == AVAHI_IF_UNSPEC ?
+ kDNSServiceInterfaceIndexAny :
+ b->interface,
+ b->service_type,
+ b->domain_name,
+ browse_reply,
+ b);
+ if (ret != kDNSServiceErr_NoError || !b->client) {
+ b->browse_error_event = avahi_time_event_new(b->server->time_event_queue,
+NULL, browse_error_callback, b);
+ } else {
+ b->watch = b->server->poll_api->watch_new(b->server->poll_api, DNSServiceRefSockFD(b->client), AVAHI_WATCH_IN, browse_socket_event, b);
+
+ /* Add a second */
+ gettimeofday(&tv, NULL);
+ avahi_timeval_add(&tv, 1000000);
+ b->all_for_now_event = avahi_time_event_new(b->server->time_event_queue, &tv, all_for_now_callback, b);
+ }
+}
+#endif
+
static void record_browser_callback(
AvahiSRecordBrowser*rr,
AvahiIfIndex interface,
@@ -102,7 +228,11 @@
AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
+#ifdef HAVE_BONJOUR
+ AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+#else
AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+#endif
AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_is_valid_service_type_generic(service_type), AVAHI_ERR_INVALID_SERVICE_TYPE);
if (!domain)
@@ -132,6 +262,16 @@
goto fail;
}
+#ifdef HAVE_BONJOUR
+ b->protocol = protocol;
+ b->interface = interface;
+ b->flags = flags;
+ b->browse_error_event = NULL;
+ b->all_for_now_event = NULL;
+ b->client = NULL;
+ b->watch = NULL;
+ avahi_browse_service_start(b);
+#else
if (!(k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR))) {
avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
goto fail;
@@ -141,6 +281,7 @@
goto fail;
avahi_key_unref(k);
+#endif
return b;
@@ -163,5 +304,21 @@
avahi_free(b->domain_name);
avahi_free(b->service_type);
+#ifdef HAVE_BONJOUR
+ if (b->browse_error_event) {
+ avahi_time_event_free(b->browse_error_event);
+ b->browse_error_event = NULL;
+ }
+ if (b->all_for_now_event) {
+ avahi_time_event_free(b->all_for_now_event);
+ b->all_for_now_event = NULL;
+ }
+
+ if (b->watch)
+ b->server->poll_api->watch_free(b->watch);
+
+ if (b->client)
+ DNSServiceRefDeallocate (b->client);
+#endif
avahi_free(b);
}