]> git.meshlink.io Git - catta/commitdiff
* Rework some Browsing/Resolving stuff
authorLennart Poettering <lennart@poettering.net>
Sun, 22 May 2005 02:00:31 +0000 (02:00 +0000)
committerLennart Poettering <lennart@poettering.net>
Sun, 22 May 2005 02:00:31 +0000 (02:00 +0000)
* Add AvahiDomainBrowser
* fix avahi_strlist_to_string() with empty lists

git-svn-id: file:///home/lennart/svn/public/avahi/trunk@83 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe

14 files changed:
avahi-core/Makefile.am
avahi-core/avahi-test.c
avahi-core/cache.c
avahi-core/core.h
avahi-core/resolve-address.c
avahi-core/resolve-host-name.c
avahi-core/resolve.c
avahi-core/resolve.h
avahi-core/rr.c
avahi-core/server.c
avahi-core/server.h
avahi-core/strlst.c
avahi-core/timeeventq.h
avahi-core/util.c

index 42ad9c47db44f99e42a8225a550813f68dd4f2f6..24b81b081a3a5ca239b04ac28dbe88f53cb278f8 100644 (file)
@@ -59,7 +59,8 @@ libavahi_core_la_SOURCES = \
        rrlist.c rrlist.h \
        alternative.c alternative.h \
        resolve-host-name.c \
-       resolve-address.c
+       resolve-address.c \
+       browse-domain.c
 
 prioq_test_SOURCES = \
        prioq-test.c  \
index 89dc8f85fcfa8956e8ac083b2fa72891fa5b3eaa..45a37f2840fd3a6a617e3ebeb519bb3b78eb091f 100644 (file)
@@ -46,7 +46,7 @@ static gboolean dump_timeout(gpointer data) {
     return TRUE;
 }
 
-static void record_resolver_callback(AvahiRecordResolver *r, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void record_browser_callback(AvahiRecordBrowser *r, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
     gchar *t;
     
     g_assert(r);
@@ -55,12 +55,11 @@ static void record_resolver_callback(AvahiRecordResolver *r, gint interface, guc
     g_assert(protocol != AF_UNSPEC);
 
     g_message("SUBSCRIPTION: record [%s] on %i.%i is %s", t = avahi_record_to_string(record), interface, protocol,
-              event == AVAHI_BROWSER_NEW ? "new" : "removed");
+              event == AVAHI_BROWSER_NEW ? "new" : "remove");
 
     g_free(t);
 }
 
-
 static void remove_entries(void);
 static void create_entries(gboolean new_name);
 
@@ -126,17 +125,34 @@ static void create_entries(gboolean new_name) {
 static void hnr_callback(AvahiHostNameResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, gpointer userdata) {
     gchar t[64];
 
+    if (a)
+        avahi_address_snprint(t, sizeof(t), a);
+
+    g_message("HNR: (%i.%i) %s -> %s [%s]", iface, protocol, hostname, a ? t : "n/a", event == AVAHI_BROWSER_NEW ? "found" : "timeout");
+}
+
+static void ar_callback(AvahiAddressResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *hostname, gpointer userdata) {
+    gchar t[64];
+
     avahi_address_snprint(t, sizeof(t), a);
 
-    g_message("HNR: (%i.%i) %s -> %s [%s]", iface, protocol, hostname, t, event == AVAHI_BROWSER_NEW ? "new" : "remove");
+    g_message("AR: (%i.%i) %s -> %s [%s]", iface, protocol, t, hostname ? hostname : "n/a", event == AVAHI_BROWSER_NEW ? "found" : "timeout");
+}
+
+static void db_callback(AvahiDomainBrowser *b, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata) {
+
+    g_message("DB: (%i.%i) %s [%s]", iface, protocol, domain, event == AVAHI_BROWSER_NEW ? "new" : "remove");
 }
 
 int main(int argc, char *argv[]) {
     GMainLoop *loop = NULL;
-    AvahiRecordResolver *r;
+    AvahiRecordBrowser *r;
     AvahiHostNameResolver *hnr;
+    AvahiAddressResolver *ar;
     AvahiKey *k;
     AvahiServerConfig config;
+    AvahiAddress a;
+    AvahiDomainBrowser *db;
 
     avahi_server_config_init(&config);
 /*     config.host_name = g_strdup("test"); */
@@ -144,21 +160,26 @@ int main(int argc, char *argv[]) {
     avahi_server_config_free(&config);
 
     k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
-    r = avahi_record_resolver_new(server, 0, AF_UNSPEC, k, record_resolver_callback, NULL);
+    r = avahi_record_browser_new(server, 0, AF_UNSPEC, k, record_browser_callback, NULL);
     avahi_key_unref(k);
 
-    hnr = avahi_host_name_resolver_new(server, 0, AF_UNSPEC, "ecstasy.local", hnr_callback, NULL);
+    hnr = avahi_host_name_resolver_new(server, 0, AF_UNSPEC, "codes-CompUTER.local", AF_UNSPEC, hnr_callback, NULL);
 
+    ar = avahi_address_resolver_new(server, 0, AF_UNSPEC, avahi_address_parse("192.168.50.15", AF_INET, &a), ar_callback, NULL);
+
+    db = avahi_domain_browser_new(server, 0, AF_UNSPEC, NULL, AVAHI_DOMAIN_BROWSER_BROWSE, db_callback, NULL);
+    
     loop = g_main_loop_new(NULL, FALSE);
     
 /*      g_timeout_add(1000*5, dump_timeout, server);   */
-    g_timeout_add(1000*30, quit_timeout, loop);    
+/*     g_timeout_add(1000*30, quit_timeout, loop);     */
     
     g_main_loop_run(loop);
     g_main_loop_unref(loop);
 
-    avahi_record_resolver_free(r);
+    avahi_record_browser_free(r);
     avahi_host_name_resolver_free(hnr);
+    avahi_address_resolver_free(ar);
 
     if (group)
         avahi_entry_group_free(group);   
index ec4ee6088e55e1a57a410c3b7f24eaf8f9eab74f..c5e7e319e9bcc6ece613238bf0fc646db57b2bf8 100644 (file)
@@ -50,7 +50,7 @@ static void remove_entry(AvahiCache *c, AvahiCacheEntry *e) {
     if (e->time_event)
         avahi_time_event_queue_remove(c->server->time_event_queue, e->time_event);
 
-    avahi_resolver_notify(c->server, c->interface, e->record, AVAHI_BROWSER_REMOVE);
+    avahi_browser_notify(c->server, c->interface, e->record, AVAHI_BROWSER_REMOVE);
 
     avahi_record_unref(e->record);
     
@@ -182,7 +182,7 @@ static void elapse_func(AvahiTimeEvent *t, void *userdata) {
         g_assert(percent > 0);
 
         /* Request a cache update, if we are subscribed to this entry */
-        if (avahi_is_subscribed(e->cache->server, e->record->key)) {
+        if (avahi_is_subscribed(e->cache->server, e->cache->interface, e->record->key)) {
 /*             g_message("Requesting cache entry update at %i%%.", percent); */
             avahi_interface_post_query(e->cache->interface, e->record->key, TRUE);
         }
@@ -307,7 +307,7 @@ void avahi_cache_update(AvahiCache *c, AvahiRecord *r, gboolean unique, const Av
             AVAHI_LLIST_PREPEND(AvahiCacheEntry, entry, c->entries, e);
 
             /* Notify subscribers */
-            avahi_resolver_notify(c->server, c->interface, e->record, AVAHI_BROWSER_NEW);
+            avahi_browser_notify(c->server, c->interface, e->record, AVAHI_BROWSER_NEW);
         } 
         
         e->origin = *a;
index e800a389baf83a3936628e44af55be55a1b7d09b..4f981e034b24e5eceac4fb48a54391b6a76a74b9 100644 (file)
@@ -105,7 +105,7 @@ void avahi_server_set_domain_name(AvahiServer *s, const gchar *domain_name);
 gpointer avahi_server_get_data(AvahiServer *s);
 void avahi_server_set_data(AvahiServer *s, gpointer userdata);
 
-AvahiServerState avhai_server_get_state(AvahiServer *s);
+AvahiServerState avahi_server_get_state(AvahiServer *s);
 
 const AvahiRecord *avahi_server_iterate(AvahiServer *s, AvahiEntryGroup *g, void **state);
 void avahi_server_dump(AvahiServer *s, FILE *f);
@@ -207,28 +207,44 @@ void avahi_server_add_service_strlst(
     AvahiStringList *strlst);
 
 typedef enum {
-    AVAHI_BROWSER_NEW,
-    AVAHI_BROWSER_REMOVE,
+    AVAHI_BROWSER_NEW = 0,
+    AVAHI_BROWSER_REMOVE = -1
 } AvahiBrowserEvent;
 
-typedef struct AvahiRecordResolver AvahiRecordResolver;
-typedef void (*AvahiRecordResolverCallback)(AvahiRecordResolver *r, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata);
-AvahiRecordResolver *avahi_record_resolver_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordResolverCallback callback, gpointer userdata);
-void avahi_record_resolver_free(AvahiRecordResolver *r);
+typedef enum {
+    AVAHI_RESOLVER_FOUND = 0,
+    AVAHI_RESOLVER_TIMEOUT = -1
+} AvahiResolverEvent;
+
+
+typedef struct AvahiRecordBrowser AvahiRecordBrowser;
+typedef void (*AvahiRecordBrowserCallback)(AvahiRecordBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata);
+AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata);
+void avahi_record_browser_free(AvahiRecordBrowser *b);
 
 typedef struct AvahiHostNameResolver AvahiHostNameResolver;
-typedef void (*AvahiHostNameResolverCallback)(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata);
-AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, AvahiHostNameResolverCallback calback, gpointer userdata);
+typedef void (*AvahiHostNameResolverCallback)(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const gchar *host_name, const AvahiAddress *a, gpointer userdata);
+AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback calback, gpointer userdata);
 void avahi_host_name_resolver_free(AvahiHostNameResolver *r);
 
 typedef struct AvahiAddressResolver AvahiAddressResolver;
-typedef void (*AvahiAddressResolverCallback)(AvahiAddressResolver *r, gint interface, guchar protocol, AvahiBrowserEvent event, const AvahiAddress *a, const gchar *host_name, gpointer userdata);
+typedef void (*AvahiAddressResolverCallback)(AvahiAddressResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, const AvahiAddress *a, const gchar *host_name, gpointer userdata);
 AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback calback, gpointer userdata);
 void avahi_address_resolver_free(AvahiAddressResolver *r);
 
-/* not yet implemented */
+typedef enum {
+    AVAHI_DOMAIN_BROWSER_REGISTER,
+    AVAHI_DOMAIN_BROWSER_REGISTER_DEFAULT,
+    AVAHI_DOMAIN_BROWSER_BROWSE,
+    AVAHI_DOMAIN_BROWSER_BROWSE_DEFAULT
+} AvahiDomainBrowserType;
 
 typedef struct AvahiDomainBrowser AvahiDomainBrowser;
+typedef void (*AvahiDomainBrowserCallback)(AvahiDomainBrowser *b, gint interface, guchar protocol, AvahiBrowserEvent event, const gchar *domain, gpointer userdata);
+AvahiDomainBrowser *avahi_domain_browser_new(AvahiServer *server, gint interface, guchar protocol, const gchar *domain, AvahiDomainBrowserType type, AvahiDomainBrowserCallback callback, gpointer userdata);
+void avahi_domain_browser_free(AvahiDomainBrowser *b);
+
+/* not yet implemented */
 typedef struct AvahiServiceTypeBrowser AvahiServiceTypeBrowser;
 typedef struct AvahiServiceBrowser AvahiServiceBrowser;
 typedef struct AvahiServiceResolver AvahiServiceResolver;
index cba30ac17fc5426a9180187b4df66609c5718b4b..a4870aa0d3b8856400b1591c44e59373c553de7e 100644 (file)
@@ -30,28 +30,57 @@ struct AvahiAddressResolver {
     AvahiServer *server;
     AvahiAddress address;
     
-    AvahiRecordResolver *record_resolver;
+    AvahiRecordBrowser *record_browser;
 
     AvahiAddressResolverCallback callback;
     gpointer userdata;
 
+    AvahiTimeEvent *time_event;
+
     AVAHI_LLIST_FIELDS(AvahiAddressResolver, resolver);
 };
 
-static void record_resolver_callback(AvahiRecordResolver*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+static void finish(AvahiAddressResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, AvahiRecord *record) {
+    g_assert(r);
+    
+    avahi_record_browser_free(r->record_browser);
+    r->record_browser = NULL;
+
+    avahi_time_event_queue_remove(r->server->time_event_queue, r->time_event);
+    r->time_event = NULL;
+
+    r->callback(r, interface, protocol, event, &r->address, record ? record->data.ptr.name : NULL, r->userdata);
+}
+
+static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
     AvahiAddressResolver *r = userdata;
 
     g_assert(rr);
     g_assert(record);
     g_assert(r);
 
-    r->callback(r, interface, protocol, event, &r->address, record->data.ptr.name, r->userdata);
+    if (!(event == AVAHI_BROWSER_NEW))
+        return;
+
+    g_assert(record->key->type == AVAHI_DNS_TYPE_PTR);
+
+    finish(r, interface, protocol, AVAHI_RESOLVER_FOUND, record);
+}
+
+static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
+    AvahiAddressResolver *r = userdata;
+    
+    g_assert(e);
+    g_assert(r);
+
+    finish(r, -1, AF_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
 }
 
 AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint interface, guchar protocol, const AvahiAddress *address, AvahiAddressResolverCallback callback, gpointer userdata) {
     AvahiAddressResolver *r;
     AvahiKey *k;
     gchar *n;
+    GTimeVal tv;
 
     g_assert(server);
     g_assert(address);
@@ -73,9 +102,12 @@ AvahiAddressResolver *avahi_address_resolver_new(AvahiServer *server, gint inter
     k = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR);
     g_free(n);
     
-    r->record_resolver = avahi_record_resolver_new(server, interface, protocol, k, record_resolver_callback, r);
+    r->record_browser = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
     avahi_key_unref(k);
 
+    avahi_elapse_time(&tv, 1000, 0);
+    r->time_event = avahi_time_event_queue_add(server->time_event_queue, &tv, time_event_callback, r);
+
     AVAHI_LLIST_PREPEND(AvahiAddressResolver, resolver, server->address_resolvers, r);
     
     return r;
@@ -85,6 +117,12 @@ void avahi_address_resolver_free(AvahiAddressResolver *r) {
     g_assert(r);
 
     AVAHI_LLIST_REMOVE(AvahiAddressResolver, resolver, r->server->address_resolvers, r);
-    avahi_record_resolver_free(r->record_resolver);
+
+    if (r->record_browser)
+        avahi_record_browser_free(r->record_browser);
+
+    if (r->time_event)
+        avahi_time_event_queue_remove(r->server->time_event_queue, r->time_event);
+    
     g_free(r);
 }
index f031838a0e095bfdb480f282dc4d865de2a9890e..9fbf80345d37cbec3097f6fc3df48a13ef8d6ce9 100644 (file)
@@ -30,64 +30,113 @@ struct AvahiHostNameResolver {
     AvahiServer *server;
     gchar *host_name;
     
-    AvahiRecordResolver *record_resolver_a;
-    AvahiRecordResolver *record_resolver_aaaa;
+    AvahiRecordBrowser *record_browser_a;
+    AvahiRecordBrowser *record_browser_aaaa;
 
     AvahiHostNameResolverCallback callback;
     gpointer userdata;
 
+    AvahiTimeEvent *time_event;
+
     AVAHI_LLIST_FIELDS(AvahiHostNameResolver, resolver);
 };
 
-static void record_resolver_callback(AvahiRecordResolver*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
-    AvahiHostNameResolver *r = userdata;
+static void finish(AvahiHostNameResolver *r, gint interface, guchar protocol, AvahiResolverEvent event, AvahiRecord *record) {
     AvahiAddress a;
+    
+    g_assert(r);
+
+    if (r->record_browser_a) {
+        avahi_record_browser_free(r->record_browser_a);
+        r->record_browser_a = NULL;
+    }
+
+    if (r->record_browser_aaaa) {
+        avahi_record_browser_free(r->record_browser_aaaa);
+        r->record_browser_aaaa = NULL;
+    }
+    avahi_time_event_queue_remove(r->server->time_event_queue, r->time_event);
+    r->time_event = NULL;
+
+    if (record) {
+        switch (record->key->type) {
+            case AVAHI_DNS_TYPE_A:
+                a.family = AF_INET;
+                a.data.ipv4 = record->data.a.address;
+                break;
+                
+            case AVAHI_DNS_TYPE_AAAA:
+                a.family = AF_INET6;
+                a.data.ipv6 = record->data.aaaa.address;
+                break;
+                
+            default:
+                g_assert(FALSE);
+        }
+    }
+
+    r->callback(r, interface, protocol, event, record ? record->key->name : r->host_name, record ? &a : NULL, r->userdata);
+}
+
+static void record_browser_callback(AvahiRecordBrowser*rr, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) {
+    AvahiHostNameResolver *r = userdata;
 
     g_assert(rr);
     g_assert(record);
     g_assert(r);
 
-    switch (record->key->type) {
-        case AVAHI_DNS_TYPE_A:
-            a.family = AF_INET;
-            a.data.ipv4 = record->data.a.address;
-            break;
-
-        case AVAHI_DNS_TYPE_AAAA:
-            a.family = AF_INET6;
-            a.data.ipv6 = record->data.aaaa.address;
-            break;
+    if (!(event == AVAHI_BROWSER_NEW))
+        return;
+    
+    g_assert(record->key->type == AVAHI_DNS_TYPE_A || record->key->type == AVAHI_DNS_TYPE_AAAA);
+    finish(r, interface, protocol, AVAHI_RESOLVER_FOUND, record);
+}
 
-        default:
-            g_assert(FALSE);
-    }
+static void time_event_callback(AvahiTimeEvent *e, void *userdata) {
+    AvahiHostNameResolver *r = userdata;
+    
+    g_assert(e);
+    g_assert(r);
 
-    r->callback(r, interface, protocol, event, record->key->name, &a, r->userdata);
+    finish(r, -1, AF_UNSPEC, AVAHI_RESOLVER_TIMEOUT, NULL);
 }
 
-AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *s, gint interface, guchar protocol, const gchar *host_name, AvahiHostNameResolverCallback callback, gpointer userdata) {
+AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *server, gint interface, guchar protocol, const gchar *host_name, guchar aprotocol, AvahiHostNameResolverCallback callback, gpointer userdata) {
     AvahiHostNameResolver *r;
     AvahiKey *k;
-
-    g_assert(s);
+    GTimeVal tv;
+    
+    g_assert(server);
     g_assert(host_name);
     g_assert(callback);
 
+    g_assert(aprotocol == AF_UNSPEC || aprotocol == AF_INET || aprotocol == AF_INET6);
+
     r = g_new(AvahiHostNameResolver, 1);
-    r->server = s;
+    r->server = server;
     r->host_name = avahi_normalize_name(host_name);
     r->callback = callback;
     r->userdata = userdata;
 
-    k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
-    r->record_resolver_a = avahi_record_resolver_new(s, interface, protocol, k, record_resolver_callback, r);
-    avahi_key_unref(k);
-
-    k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
-    r->record_resolver_aaaa = avahi_record_resolver_new(s, interface, protocol, k, record_resolver_callback, r);
-    avahi_key_unref(k);
-
-    AVAHI_LLIST_PREPEND(AvahiHostNameResolver, resolver, s->host_name_resolvers, r);
+    if (aprotocol == AF_INET || aprotocol == AF_UNSPEC) {
+        k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_A);
+        r->record_browser_a = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
+        avahi_key_unref(k);
+    } else
+        r->record_browser_a = NULL;
+
+    if (aprotocol == AF_INET6 || aprotocol == AF_UNSPEC) {
+        k = avahi_key_new(host_name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_AAAA);
+        r->record_browser_aaaa = avahi_record_browser_new(server, interface, protocol, k, record_browser_callback, r);
+        avahi_key_unref(k);
+    } else
+        r->record_browser_aaaa = NULL;
+
+    avahi_elapse_time(&tv, 1000, 0);
+    r->time_event = avahi_time_event_queue_add(server->time_event_queue, &tv, time_event_callback, r);
+    
+    AVAHI_LLIST_PREPEND(AvahiHostNameResolver, resolver, server->host_name_resolvers, r);
     
     return r;
 }
@@ -97,8 +146,11 @@ void avahi_host_name_resolver_free(AvahiHostNameResolver *r) {
 
     AVAHI_LLIST_REMOVE(AvahiHostNameResolver, resolver, r->server->host_name_resolvers, r);
 
-    avahi_record_resolver_free(r->record_resolver_a);
-    avahi_record_resolver_free(r->record_resolver_aaaa);
+    if (r->record_browser_a)
+        avahi_record_browser_free(r->record_browser_a);
+    if (r->record_browser_aaaa)
+        avahi_record_browser_free(r->record_browser_aaaa);
+    
     g_free(r->host_name);
     g_free(r);
 }
index 7d0f068e58fdd480f225c3f45a5a6cacbfefa6d3..42eba35c7ab7a69801c1c1a8a428df5b68e56042 100644 (file)
 #include "resolve.h"
 #include "util.h"
 
+struct AvahiRecordBrowser {
+    gboolean dead;
+    
+    AvahiServer *server;
+    AvahiKey *key;
+    gint interface;
+    guchar protocol;
+    gint n_query;
+    guint sec_delay;
+
+    AvahiTimeEvent *time_event;
+
+    AvahiRecordBrowserCallback callback;
+    gpointer userdata;
+
+    AVAHI_LLIST_FIELDS(AvahiRecordBrowser, resolver);
+    AVAHI_LLIST_FIELDS(AvahiRecordBrowser, by_key);
+};
+
 static void elapse(AvahiTimeEvent *e, void *userdata) {
-    AvahiRecordResolver *s = userdata;
+    AvahiRecordBrowser *s = userdata;
     GTimeVal tv;
 /*     gchar *t; */
     
@@ -46,7 +65,7 @@ static void elapse(AvahiTimeEvent *e, void *userdata) {
 }
 
 struct cbdata {
-    AvahiRecordResolver *record_resolver;
+    AvahiRecordBrowser *record_browser;
     AvahiInterface *interface;
 };
 
@@ -58,19 +77,22 @@ static gpointer scan_cache_callback(AvahiCache *c, AvahiKey *pattern, AvahiCache
     g_assert(e);
     g_assert(cbdata);
 
-    cbdata->record_resolver->callback(
-        cbdata->record_resolver,
+    if (cbdata->record_browser->dead)
+        return NULL;
+
+    cbdata->record_browser->callback(
+        cbdata->record_browser,
         cbdata->interface->hardware->index,
         cbdata->interface->protocol,
         AVAHI_BROWSER_NEW,
         e->record,
-        cbdata->record_resolver->userdata);
+        cbdata->record_browser->userdata);
 
     return NULL;
 }
 
 static void scan_interface_callback(AvahiInterfaceMonitor *m, AvahiInterface *i, gpointer userdata) {
-    AvahiRecordResolver *s = userdata;
+    AvahiRecordBrowser *s = userdata;
     struct cbdata cbdata = { s, i };
 
     g_assert(m);
@@ -80,8 +102,8 @@ static void scan_interface_callback(AvahiInterfaceMonitor *m, AvahiInterface *i,
     avahi_cache_walk(i->cache, s->key, scan_cache_callback, &cbdata);
 }
 
-AvahiRecordResolver *avahi_record_resolver_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordResolverCallback callback, gpointer userdata) {
-    AvahiRecordResolver *s, *t;
+AvahiRecordBrowser *avahi_record_browser_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordBrowserCallback callback, gpointer userdata) {
+    AvahiRecordBrowser *b, *t;
     GTimeVal tv;
 
     g_assert(server);
@@ -90,69 +112,104 @@ AvahiRecordResolver *avahi_record_resolver_new(AvahiServer *server, gint interfa
 
     g_assert(!avahi_key_is_pattern(key));
     
-    s = g_new(AvahiRecordResolver, 1);
-    s->server = server;
-    s->key = avahi_key_ref(key);
-    s->interface = interface;
-    s->protocol = protocol;
-    s->callback = callback;
-    s->userdata = userdata;
-    s->n_query = 1;
-    s->sec_delay = 1;
-
-    avahi_server_post_query(s->server, s->interface, s->protocol, s->key);
+    b = g_new(AvahiRecordBrowser, 1);
+    b->dead = FALSE;
+    b->server = server;
+    b->key = avahi_key_ref(key);
+    b->interface = interface;
+    b->protocol = protocol;
+    b->callback = callback;
+    b->userdata = userdata;
+    b->n_query = 1;
+    b->sec_delay = 1;
+
+    avahi_server_post_query(b->server, b->interface, b->protocol, b->key);
     
-    avahi_elapse_time(&tv, s->sec_delay*1000, 0);
-    s->time_event = avahi_time_event_queue_add(server->time_event_queue, &tv, elapse, s);
+    avahi_elapse_time(&tv, b->sec_delay*1000, 0);
+    b->time_event = avahi_time_event_queue_add(server->time_event_queue, &tv, elapse, b);
 
-    AVAHI_LLIST_PREPEND(AvahiRecordResolver, resolver, server->record_resolvers, s);
+    AVAHI_LLIST_PREPEND(AvahiRecordBrowser, resolver, server->record_browsers, b);
 
-    /* Add the new entry to the record_resolver hash table */
-    t = g_hash_table_lookup(server->record_resolver_hashtable, key);
-    AVAHI_LLIST_PREPEND(AvahiRecordResolver, by_key, t, s);
-    g_hash_table_replace(server->record_resolver_hashtable, key, t);
+    /* Add the new entry to the record_browser hash table */
+    t = g_hash_table_lookup(server->record_browser_hashtable, key);
+    AVAHI_LLIST_PREPEND(AvahiRecordBrowser, by_key, t, b);
+    g_hash_table_replace(server->record_browser_hashtable, key, t);
 
     /* Scan the caches */
-    avahi_interface_monitor_walk(s->server->monitor, s->interface, s->protocol, scan_interface_callback, s);
+    avahi_interface_monitor_walk(b->server->monitor, b->interface, b->protocol, scan_interface_callback, b);
     
-    return s;
+    return b;
 }
 
-void avahi_record_resolver_free(AvahiRecordResolver *s) {
-    AvahiRecordResolver *t;
-    
-    g_assert(s);
+void avahi_record_browser_free(AvahiRecordBrowser *b) {
+    g_assert(b);
+    g_assert(!b->dead);
 
-    AVAHI_LLIST_REMOVE(AvahiRecordResolver, resolver, s->server->record_resolvers, s);
+    b->dead = TRUE;
+    b->server->need_browser_cleanup = TRUE;
 
-    t = g_hash_table_lookup(s->server->record_resolver_hashtable, s->key);
-    AVAHI_LLIST_REMOVE(AvahiRecordResolver, by_key, t, s);
+    if (b->time_event) {
+        avahi_time_event_queue_remove(b->server->time_event_queue, b->time_event);
+        b->time_event = NULL;
+    }
+}
+
+void avahi_record_browser_destroy(AvahiRecordBrowser *b) {
+    AvahiRecordBrowser *t;
+    
+    g_assert(b);
+    
+    AVAHI_LLIST_REMOVE(AvahiRecordBrowser, resolver, b->server->record_browsers, b);
+
+    t = g_hash_table_lookup(b->server->record_browser_hashtable, b->key);
+    AVAHI_LLIST_REMOVE(AvahiRecordBrowser, by_key, t, b);
     if (t)
-        g_hash_table_replace(s->server->record_resolver_hashtable, t->key, t);
+        g_hash_table_replace(b->server->record_browser_hashtable, t->key, t);
     else
-        g_hash_table_remove(s->server->record_resolver_hashtable, s->key);
+        g_hash_table_remove(b->server->record_browser_hashtable, b->key);
+
+    if (b->time_event)
+        avahi_time_event_queue_remove(b->server->time_event_queue, b->time_event);
+    avahi_key_unref(b->key);
     
-    avahi_time_event_queue_remove(s->server->time_event_queue, s->time_event);
-    avahi_key_unref(s->key);
+    g_free(b);
+}
 
+void avahi_browser_cleanup(AvahiServer *server) {
+    AvahiRecordBrowser *b;
+    AvahiRecordBrowser *n;
     
-    g_free(s);
+    g_assert(server);
+
+    for (b = server->record_browsers; b; b = n) {
+        n = b->resolver_next;
+        
+        if (b->dead)
+            avahi_record_browser_destroy(b);
+    }
+
+    server->need_browser_cleanup = FALSE;
 }
 
-void avahi_resolver_notify(AvahiServer *server, AvahiInterface *i, AvahiRecord *record, AvahiBrowserEvent event) {
-    AvahiRecordResolver *s;
+void avahi_browser_notify(AvahiServer *server, AvahiInterface *i, AvahiRecord *record, AvahiBrowserEvent event) {
+    AvahiRecordBrowser *b;
     
     g_assert(server);
     g_assert(record);
 
-    for (s = g_hash_table_lookup(server->record_resolver_hashtable, record->key); s; s = s->by_key_next)
-        if (avahi_interface_match(i, s->interface, s->protocol))
-            s->callback(s, i->hardware->index, i->protocol, event, record, s->userdata);
+    for (b = g_hash_table_lookup(server->record_browser_hashtable, record->key); b; b = b->by_key_next)
+        if (!b->dead && avahi_interface_match(i, b->interface, b->protocol))
+                b->callback(b, i->hardware->index, i->protocol, event, record, b->userdata);
 }
 
-gboolean avahi_is_subscribed(AvahiServer *server, AvahiKey *k) {
+gboolean avahi_is_subscribed(AvahiServer *server, AvahiInterface *i, AvahiKey *k) {
+    AvahiRecordBrowser *b;
     g_assert(server);
     g_assert(k);
 
-    return !!g_hash_table_lookup(server->record_resolver_hashtable, k);
+    for (b = g_hash_table_lookup(server->record_browser_hashtable, k); b; b = b->by_key_next)
+        if (!b->dead && avahi_interface_match(i, b->interface, b->protocol))
+            return TRUE;
+
+    return FALSE;
 }
index 7de75d483b6c99a5837650d5e1981e1299416de7..6659430eff7a99c8753449d3e34b96ef5e515e3d 100644 (file)
 #include "timeeventq.h"
 #include "server.h"
 
-struct AvahiRecordResolver {
-    AvahiServer *server;
-    AvahiKey *key;
-    gint interface;
-    guchar protocol;
-    gint n_query;
-    guint sec_delay;
+void avahi_browser_cleanup(AvahiServer *server);
+void avahi_browser_notify(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, AvahiBrowserEvent event);
 
-    AvahiTimeEvent *time_event;
+gboolean avahi_is_subscribed(AvahiServer *s, AvahiInterface *i, AvahiKey *k);
 
-    AvahiRecordResolverCallback callback;
-    gpointer userdata;
-
-    AVAHI_LLIST_FIELDS(AvahiRecordResolver, resolver);
-    AVAHI_LLIST_FIELDS(AvahiRecordResolver, by_key);
-};
-
-void avahi_resolver_notify(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, AvahiBrowserEvent event);
-
-gboolean avahi_is_subscribed(AvahiServer *s, AvahiKey *k);
+void avahi_record_browser_destroy(AvahiRecordBrowser *b);
 
 #endif
index f69d2e2a5feb9839d6facfb023524e598b4d4234..f3db5845d539e8fc6067e5c4e1036d02525b71d8 100644 (file)
@@ -181,6 +181,9 @@ const gchar *avahi_dns_type_to_string(guint16 type) {
 
 
 gchar *avahi_key_to_string(const AvahiKey *k) {
+    g_assert(k);
+    g_assert(k->ref >= 1);
+    
     return g_strdup_printf("%s\t%s\t%s",
                            k->name,
                            avahi_dns_class_to_string(k->class),
@@ -191,6 +194,9 @@ gchar *avahi_record_to_string(const AvahiRecord *r) {
     gchar *p, *s;
     char buf[257], *t = NULL, *d = NULL;
 
+    g_assert(r);
+    g_assert(r->ref >= 1);
+    
     switch (r->key->type) {
         case AVAHI_DNS_TYPE_A:
             inet_ntop(AF_INET, &r->data.a.address.address, t = buf, sizeof(buf));
index 644bb168c5002ecf19faa62f8812fdfce9c4f09d..dd0f707b6be3a957fc320cd4362358bf54d2a273 100644 (file)
@@ -102,6 +102,9 @@ static void cleanup_dead(AvahiServer *s) {
 
         s->need_entry_cleanup = FALSE;
     }
+
+    if (s->need_browser_cleanup)
+        avahi_browser_cleanup(s);
 }
 
 static void enum_aux_records(AvahiServer *s, AvahiInterface *i, const gchar *name, guint16 type, void (*callback)(AvahiServer *s, AvahiRecord *r, gboolean flush_cache, gpointer userdata), gpointer userdata) {
@@ -252,13 +255,11 @@ static void incoming_probe(AvahiServer *s, AvahiRecord *record, AvahiInterface *
 static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, gboolean unique, const AvahiAddress *a) {
     gboolean valid = TRUE, ours = FALSE, conflict = FALSE, withdraw_immediately = FALSE;
     AvahiEntry *e, *n, *conflicting_entry = NULL;
-    gchar *t;
     
     g_assert(s);
     g_assert(i);
     g_assert(record);
 
-    t = avahi_record_to_string(record);
 
 /*     g_message("CHECKING FOR CONFLICT: [%s]", t);   */
 
@@ -277,10 +278,15 @@ static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *
                 
                 /* Check wheter there is a TTL conflict */
                 if (record->ttl <= e->record->ttl/2) {
+                    gchar *t;
                     /* Refresh */
+                    t = avahi_record_to_string(record); 
+                           
                     g_message("Recieved record with bad TTL [%s]. Refreshing.", t);
-                    avahi_interface_post_response(i, e->record, FALSE, NULL, TRUE);
+                    avahi_server_prepare_matching_responses(s, i, e->record->key, FALSE);
                     valid = FALSE;
+
+                    g_free(t);
                 }
                 
                 /* There's no need to check the other entries of this RRset */
@@ -307,8 +313,12 @@ static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *
 /*     g_message("ours=%i conflict=%i", ours, conflict); */
 
     if (!ours && conflict) {
+        gchar *t;
         valid = FALSE;
 
+        t = avahi_record_to_string(record); 
         if (withdraw_immediately) {
             g_message("Recieved conflicting record [%s] with local record to be. Withdrawing.", t);
             withdraw_rrset(s, record->key);
@@ -320,9 +330,9 @@ static gboolean handle_conflict(AvahiServer *s, AvahiInterface *i, AvahiRecord *
             /* Local unique records are returned to probin
              * state. Local shared records are reannounced. */
         }
-    }
 
-    g_free(t);
+        g_free(t);
+    }
 
     return valid;
 }
@@ -900,7 +910,7 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
 
     s = g_new(AvahiServer, 1);
     s->n_host_rr_pending = 0;
-    s->need_entry_cleanup = s->need_group_cleanup = FALSE;
+    s->need_entry_cleanup = s->need_group_cleanup = s->need_browser_cleanup = FALSE;
 
     if (sc)
         avahi_server_config_copy(&s->config, sc);
@@ -950,10 +960,11 @@ AvahiServer *avahi_server_new(GMainContext *c, const AvahiServerConfig *sc, Avah
     s->entries_by_key = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal);
     AVAHI_LLIST_HEAD_INIT(AvahiGroup, s->groups);
 
-    AVAHI_LLIST_HEAD_INIT(AvahiRecordResolver, s->record_resolvers);
-    s->record_resolver_hashtable = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal);
+    AVAHI_LLIST_HEAD_INIT(AvahiRecordBrowser, s->record_browsers);
+    s->record_browser_hashtable = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal);
     AVAHI_LLIST_HEAD_INIT(AvahiHostNameResolver, s->host_name_resolvers);
     AVAHI_LLIST_HEAD_INIT(AvahiAddressResolver, s->address_resolvers);
+    AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, s->domain_browsers);
 
     /* Get host name */
     s->host_name = s->config.host_name ? avahi_normalize_name(s->config.host_name) : avahi_get_host_name();
@@ -996,9 +1007,11 @@ void avahi_server_free(AvahiServer* s) {
         avahi_host_name_resolver_free(s->host_name_resolvers);
     while (s->address_resolvers)
         avahi_address_resolver_free(s->address_resolvers);
-    while (s->record_resolvers)
-        avahi_record_resolver_free(s->record_resolvers);
-    g_hash_table_destroy(s->record_resolver_hashtable);
+    while (s->domain_browsers)
+        avahi_domain_browser_free(s->domain_browsers);
+    while (s->record_browsers)
+        avahi_record_browser_destroy(s->record_browsers);
+    g_hash_table_destroy(s->record_browser_hashtable);
 
     g_hash_table_destroy(s->entries_by_key);
 
@@ -1470,7 +1483,7 @@ void avahi_server_set_data(AvahiServer *s, gpointer userdata) {
     s->userdata = userdata;
 }
 
-AvahiServerState avhai_server_get_state(AvahiServer *s) {
+AvahiServerState avahi_server_get_state(AvahiServer *s) {
     g_assert(s);
 
     return s->state;
index 41a691e4c52040f6d604926f26eb0e51520beaaf..93ae1f07acf4e2f8a4d459ae39e7d002e1b24e17 100644 (file)
@@ -75,12 +75,13 @@ struct AvahiServer {
 
     AVAHI_LLIST_HEAD(AvahiEntryGroup, groups);
     
-    AVAHI_LLIST_HEAD(AvahiRecordResolver, record_resolvers);
-    GHashTable *record_resolver_hashtable;
+    AVAHI_LLIST_HEAD(AvahiRecordBrowser, record_browsers);
+    GHashTable *record_browser_hashtable;
     AVAHI_LLIST_HEAD(AvahiHostNameResolver, host_name_resolvers);
     AVAHI_LLIST_HEAD(AvahiAddressResolver, address_resolvers);
+    AVAHI_LLIST_HEAD(AvahiDomainBrowser, domain_browsers);
 
-    gboolean need_entry_cleanup, need_group_cleanup;
+    gboolean need_entry_cleanup, need_group_cleanup, need_browser_cleanup;
     
     AvahiTimeEventQueue *time_event_queue;
     
index ef9fa3ee603bc8fe7106e2acdb3b7e622e88c708..866618f3f1e36a2ec46c2104e1bd197b3f151532 100644 (file)
@@ -102,10 +102,10 @@ gchar* avahi_string_list_to_string(AvahiStringList *l) {
         if (n != l)
             s ++;
 
-        s += n->size+3;
+        s += n->size+2;
     }
 
-    t = e = g_new(gchar, s);
+    t = e = g_new(gchar, s+1);
 
     for (n = l; n; n = n->next) {
         if (n != l)
@@ -116,10 +116,12 @@ gchar* avahi_string_list_to_string(AvahiStringList *l) {
         e[n->size] = 0;
         e = strchr(e, 0);
         *(e++) = '"';
+
+        g_assert(e);
     }
 
     l = string_list_reverse(l);
-
+    
     *e = 0;
 
     return t;
index 4a668c0451414983d16515079226be8333c25ccf..a559d101029a4d643bc95b271c66480b4a6088dc 100644 (file)
@@ -51,7 +51,4 @@ void avahi_time_event_queue_update(AvahiTimeEventQueue *q, AvahiTimeEvent *e, co
 AvahiTimeEvent* avahi_time_event_queue_root(AvahiTimeEventQueue *q);
 AvahiTimeEvent* avahi_time_event_next(AvahiTimeEvent *e);
 
-
-
-
 #endif
index 91403e624f29fc928099b0a0f12fc21c83c47ef9..8dd9e645bc79a7d19aa1c62808ad7974714f6e8d 100644 (file)
@@ -62,7 +62,6 @@ static gchar *unescape_uneeded(const gchar *src, gchar *ret_dest, size_t size) {
             
             *(ret_dest++) = '\\';
             *(ret_dest++) = *src;
-
             escaped = FALSE;
         } else {
             if (--size <= 1) break;