+ assert(l);
+
+ b = l->record_browser;
+
+ if (b->dead)
+ return;
+
+ lookup_ref(l);
+
+ switch (event) {
+ case AVAHI_BROWSER_NEW:
+ assert(r);
+
+ if (r->key->clazz == AVAHI_DNS_CLASS_IN &&
+ r->key->type == AVAHI_DNS_TYPE_CNAME)
+ /* It's a CNAME record, so let's follow it. We allow browsing on both multicast and wide area. */
+ lookup_handle_cname(l, interface, protocol, b->flags, r);
+ else {
+ /* It's a normal record, so let's call the user callback */
+ assert(avahi_key_equal(b->key, l->key));
+
+ b->callback(b, interface, protocol, event, r, flags, b->userdata);
+ }
+ break;
+
+ case AVAHI_BROWSER_REMOVE:
+ assert(r);
+
+ if (r->key->clazz == AVAHI_DNS_CLASS_IN &&
+ r->key->type == AVAHI_DNS_TYPE_CNAME)
+ /* It's a CNAME record, so let's drop that query! */
+ lookup_drop_cname(l, interface, protocol, 0, r);
+ else {
+ /* It's a normal record, so let's call the user callback */
+ assert(avahi_key_equal(b->key, l->key));
+
+ b->callback(b, interface, protocol, event, r, flags, b->userdata);
+ }
+ break;
+
+ case AVAHI_BROWSER_ALL_FOR_NOW:
+
+ b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, flags, b->userdata);
+ break;
+
+ case AVAHI_BROWSER_CACHE_EXHAUSTED:
+ case AVAHI_BROWSER_FAILURE:
+ /* Not defined for multicast DNS */
+ abort();
+
+ }
+
+ lookup_unref(l);
+}
+
+static int lookup_start(AvahiSRBLookup *l) {
+ assert(l);
+
+ assert(!(l->flags & AVAHI_LOOKUP_USE_WIDE_AREA) != !(l->flags & AVAHI_LOOKUP_USE_MULTICAST));
+ assert(!l->wide_area && !l->multicast);
+
+ if (l->flags & AVAHI_LOOKUP_USE_WIDE_AREA) {
+
+ if (!(l->wide_area = avahi_wide_area_lookup_new(l->record_browser->server->wide_area_lookup_engine, l->key, lookup_wide_area_callback, l)))
+ return -1;
+
+ } else {
+ assert(l->flags & AVAHI_LOOKUP_USE_MULTICAST);
+
+ if (!(l->multicast = avahi_multicast_lookup_new(l->record_browser->server->multicast_lookup_engine, l->interface, l->protocol, l->key, lookup_multicast_callback, l)))
+ return -1;
+ }
+
+ return 0;
+}
+
+static int lookup_scan_cache(AvahiSRBLookup *l) {
+ int n = 0;
+
+ assert(l);
+
+ assert(!(l->flags & AVAHI_LOOKUP_USE_WIDE_AREA) != !(l->flags & AVAHI_LOOKUP_USE_MULTICAST));
+
+
+ if (l->flags & AVAHI_LOOKUP_USE_WIDE_AREA) {
+ n = (int) avahi_wide_area_scan_cache(l->record_browser->server->wide_area_lookup_engine, l->key, lookup_wide_area_callback, l);
+
+ } else {
+ assert(l->flags & AVAHI_LOOKUP_USE_MULTICAST);
+ n = (int) avahi_multicast_lookup_engine_scan_cache(l->record_browser->server->multicast_lookup_engine, l->interface, l->protocol, l->key, lookup_multicast_callback, l);
+ }
+
+ return n;
+}
+
+static AvahiSRBLookup* lookup_add(AvahiSRecordBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiLookupFlags flags, AvahiKey *key) {
+ AvahiSRBLookup *l;
+
+ assert(b);
+ assert(!b->dead);