#include "browse.h"
#include "log.h"
#include "querier.h"
+#include "domain-util.h"
+#include "rr-util.h"
-#define AVAHI_MAX_LOOKUPS_PER_BROWSER 15
+#define AVAHI_LOOKUPS_PER_BROWSER_MAX 15
struct AvahiSRBLookup {
AvahiSRecordBrowser *record_browser;
*flags |= AVAHI_LOOKUP_USE_WIDE_AREA;
}
-
static AvahiSRBLookup* lookup_new(
AvahiSRecordBrowser *b,
AvahiIfIndex interface,
assert(AVAHI_IF_VALID(interface));
assert(AVAHI_PROTO_VALID(protocol));
- if (b->n_lookups >= AVAHI_MAX_LOOKUPS_PER_BROWSER)
+ if (b->n_lookups >= AVAHI_LOOKUPS_PER_BROWSER_MAX)
/* We don't like cyclic CNAMEs */
return NULL;
return NULL;
}
+static void browser_cancel(AvahiSRecordBrowser *b) {
+ assert(b);
+
+ if (b->root_lookup) {
+ lookup_unref(b->root_lookup);
+ b->root_lookup = NULL;
+ }
+
+ if (b->defer_time_event) {
+ avahi_time_event_free(b->defer_time_event);
+ b->defer_time_event = NULL;
+ }
+}
+
static void lookup_wide_area_callback(
AvahiWideAreaLookupEngine *e,
AvahiBrowserEvent event,
assert(e);
assert(l);
+ assert(l->ref >= 1);
b = l->record_browser;
abort();
case AVAHI_BROWSER_ALL_FOR_NOW:
- case AVAHI_BROWSER_NOT_FOUND:
case AVAHI_BROWSER_FAILURE:
b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, flags, b->userdata);
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));
+ if (avahi_server_is_record_local(b->server, interface, protocol, r))
+ flags |= AVAHI_LOOKUP_RESULT_LOCAL;
+
b->callback(b, interface, protocol, event, r, flags, b->userdata);
}
break;
break;
case AVAHI_BROWSER_CACHE_EXHAUSTED:
- case AVAHI_BROWSER_NOT_FOUND:
case AVAHI_BROWSER_FAILURE:
/* Not defined for multicast DNS */
abort();
l->cname_lookups = avahi_rlist_prepend(l->cname_lookups, lookup_ref(n));
lookup_go(n);
+ lookup_unref(n);
}
static void lookup_drop_cname(AvahiSRBLookup *l, AvahiIfIndex interface, AvahiProtocol protocol, AvahiLookupFlags flags, AvahiRecord *r) {
AvahiKey *k;
- AvahiSRBLookup *n;
+ AvahiSRBLookup *n = NULL;
AvahiRList *rl;
assert(r->key->clazz == AVAHI_DNS_CLASS_IN);
}
}
-static void defer_callback(AvahiTimeEvent *e, void *userdata) {
+static void defer_callback(AVAHI_GCC_UNUSED AvahiTimeEvent *e, void *userdata) {
AvahiSRecordBrowser *b = userdata;
int n;
if (n < 0) {
/* sending of the initial query failed */
+ avahi_server_set_errno(b->server, AVAHI_ERR_FAILURE);
+
b->callback(
b, b->interface, b->protocol, AVAHI_BROWSER_FAILURE, NULL,
b->flags & AVAHI_LOOKUP_USE_WIDE_AREA ? AVAHI_LOOKUP_RESULT_WIDE_AREA : AVAHI_LOOKUP_RESULT_MULTICAST,
b->userdata);
- avahi_s_record_browser_cancel(b);
+ browser_cancel(b);
return;
}
assert(b);
assert(!b->dead);
- avahi_s_record_browser_cancel(b);
+ browser_cancel(b);
/* Request a new iteration of the cache scanning */
if (!b->defer_time_event) {
}
}
-#define CHECK_VALIDITY_RETURN_NULL(server, expression, error) { \
- if (!(expression)) { \
- avahi_server_set_errno((server), (error)); \
- return NULL; \
- } \
-}
-
AvahiSRecordBrowser *avahi_s_record_browser_new(
AvahiServer *server,
AvahiIfIndex interface,
assert(key);
assert(callback);
- CHECK_VALIDITY_RETURN_NULL(server, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
- CHECK_VALIDITY_RETURN_NULL(server, !avahi_key_is_pattern(key), AVAHI_ERR_IS_PATTERN);
- CHECK_VALIDITY_RETURN_NULL(server, avahi_key_is_valid(key), AVAHI_ERR_INVALID_KEY);
- CHECK_VALIDITY_RETURN_NULL(server, AVAHI_VALID_FLAGS(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
- CHECK_VALIDITY_RETURN_NULL(server, !(flags & AVAHI_LOOKUP_USE_WIDE_AREA) || !(flags & AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+ 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, !avahi_key_is_pattern(key), AVAHI_ERR_IS_PATTERN);
+ AVAHI_CHECK_VALIDITY_RETURN_NULL(server, avahi_key_is_valid(key), AVAHI_ERR_INVALID_KEY);
+ AVAHI_CHECK_VALIDITY_RETURN_NULL(server, AVAHI_FLAGS_VALID(flags, AVAHI_LOOKUP_USE_WIDE_AREA|AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
+ AVAHI_CHECK_VALIDITY_RETURN_NULL(server, !(flags & AVAHI_LOOKUP_USE_WIDE_AREA) || !(flags & AVAHI_LOOKUP_USE_MULTICAST), AVAHI_ERR_INVALID_FLAGS);
if (!(b = avahi_new(AvahiSRecordBrowser, 1))) {
avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY);
b->flags = flags;
b->callback = callback;
b->userdata = userdata;
-
b->n_lookups = 0;
AVAHI_LLIST_HEAD_INIT(AvahiSRBLookup, b->lookups);
b->root_lookup = NULL;
return b;
}
-void avahi_s_record_browser_cancel(AvahiSRecordBrowser *b) {
- assert(b);
-
- if (b->root_lookup) {
- lookup_unref(b->root_lookup);
- b->root_lookup = NULL;
- }
-
- if (b->defer_time_event) {
- avahi_time_event_free(b->defer_time_event);
- b->defer_time_event = NULL;
- }
-
-
-
-}
-
void avahi_s_record_browser_free(AvahiSRecordBrowser *b) {
assert(b);
assert(!b->dead);
b->dead = 1;
b->server->need_browser_cleanup = 1;
- avahi_s_record_browser_cancel(b);
+ browser_cancel(b);
}
void avahi_s_record_browser_destroy(AvahiSRecordBrowser *b) {
assert(b);
- avahi_s_record_browser_cancel(b);
+ browser_cancel(b);
AVAHI_LLIST_REMOVE(AvahiSRecordBrowser, browser, b->server->record_browsers, b);