From a29887070855153ac64a3503e2f0004c2056f8e8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 20 May 2005 23:03:57 +0000 Subject: [PATCH] * rename AvahiSubscription to AvahiRecordResolver * implement AvahiHostNameResolver git-svn-id: file:///home/lennart/svn/public/avahi/trunk@80 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-core/Makefile.am | 3 +- avahi-core/avahi-test.c | 31 +++++++--- avahi-core/cache.c | 4 +- avahi-core/core.h | 29 +++++---- avahi-core/iface.c | 5 +- avahi-core/resolve-host-name.c | 104 +++++++++++++++++++++++++++++++++ avahi-core/server.c | 14 +++-- avahi-core/server.h | 5 +- avahi-core/subscribe.c | 56 +++++++++--------- avahi-core/subscribe.h | 10 ++-- 10 files changed, 195 insertions(+), 66 deletions(-) create mode 100644 avahi-core/resolve-host-name.c diff --git a/avahi-core/Makefile.am b/avahi-core/Makefile.am index de82b0a..e72d54f 100644 --- a/avahi-core/Makefile.am +++ b/avahi-core/Makefile.am @@ -57,7 +57,8 @@ libavahi_core_la_SOURCES = \ subscribe.c subscribe.h \ strlst.c strlst.h \ rrlist.c rrlist.h \ - alternative.c alternative.h + alternative.c alternative.h \ + resolve-host-name.c prioq_test_SOURCES = \ prioq-test.c \ diff --git a/avahi-core/avahi-test.c b/avahi-core/avahi-test.c index fc1426f..89dc8f8 100644 --- a/avahi-core/avahi-test.c +++ b/avahi-core/avahi-test.c @@ -46,16 +46,16 @@ static gboolean dump_timeout(gpointer data) { return TRUE; } -static void subscription(AvahiSubscription *s, AvahiRecord *r, gint interface, guchar protocol, AvahiSubscriptionEvent event, gpointer userdata) { +static void record_resolver_callback(AvahiRecordResolver *r, gint interface, guchar protocol, AvahiBrowserEvent event, AvahiRecord *record, gpointer userdata) { gchar *t; - g_assert(s); g_assert(r); + g_assert(record); g_assert(interface > 0); g_assert(protocol != AF_UNSPEC); - g_message("SUBSCRIPTION: record [%s] on %i.%i is %s", t = avahi_record_to_string(r), interface, protocol, - event == AVAHI_SUBSCRIPTION_NEW ? "new" : "removed"); + g_message("SUBSCRIPTION: record [%s] on %i.%i is %s", t = avahi_record_to_string(record), interface, protocol, + event == AVAHI_BROWSER_NEW ? "new" : "removed"); g_free(t); } @@ -122,30 +122,43 @@ static void create_entries(gboolean new_name) { avahi_entry_group_commit(group); } + +static void hnr_callback(AvahiHostNameResolver *r, gint iface, guchar protocol, AvahiBrowserEvent event, const gchar *hostname, const AvahiAddress *a, 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"); +} + int main(int argc, char *argv[]) { GMainLoop *loop = NULL; - AvahiSubscription *s; + AvahiRecordResolver *r; + AvahiHostNameResolver *hnr; AvahiKey *k; AvahiServerConfig config; avahi_server_config_init(&config); - config.host_name = g_strdup("test"); +/* config.host_name = g_strdup("test"); */ server = avahi_server_new(NULL, &config, server_callback, NULL); avahi_server_config_free(&config); k = avahi_key_new("_http._tcp.local", AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_PTR); - s = avahi_subscription_new(server, k, 0, AF_UNSPEC, subscription, NULL); + r = avahi_record_resolver_new(server, 0, AF_UNSPEC, k, record_resolver_callback, NULL); avahi_key_unref(k); + hnr = avahi_host_name_resolver_new(server, 0, AF_UNSPEC, "ecstasy.local", hnr_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_subscription_free(s); + avahi_record_resolver_free(r); + avahi_host_name_resolver_free(hnr); if (group) avahi_entry_group_free(group); diff --git a/avahi-core/cache.c b/avahi-core/cache.c index 12ee0e6..ec4ee60 100644 --- a/avahi-core/cache.c +++ b/avahi-core/cache.c @@ -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_subscription_notify(c->server, c->interface, e->record, AVAHI_SUBSCRIPTION_REMOVE); + avahi_resolver_notify(c->server, c->interface, e->record, AVAHI_BROWSER_REMOVE); avahi_record_unref(e->record); @@ -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_subscription_notify(c->server, c->interface, e->record, AVAHI_SUBSCRIPTION_NEW); + avahi_resolver_notify(c->server, c->interface, e->record, AVAHI_BROWSER_NEW); } e->origin = *a; diff --git a/avahi-core/core.h b/avahi-core/core.h index e113f86..e1927b6 100644 --- a/avahi-core/core.h +++ b/avahi-core/core.h @@ -207,15 +207,24 @@ void avahi_server_add_service_strlst( AvahiStringList *strlst); typedef enum { - AVAHI_SUBSCRIPTION_NEW, - AVAHI_SUBSCRIPTION_REMOVE, -} AvahiSubscriptionEvent; - -typedef struct AvahiSubscription AvahiSubscription; - -typedef void (*AvahiSubscriptionCallback)(AvahiSubscription *s, AvahiRecord *record, gint interface, guchar protocol, AvahiSubscriptionEvent event, gpointer userdata); - -AvahiSubscription *avahi_subscription_new(AvahiServer *s, AvahiKey *key, gint interface, guchar protocol, AvahiSubscriptionCallback callback, gpointer userdata); -void avahi_subscription_free(AvahiSubscription *s); + AVAHI_BROWSER_NEW, + AVAHI_BROWSER_REMOVE, +} AvahiBrowserEvent; + +typedef struct AvahiRecordResolver AvahiRecordResolver; +typedef struct AvahiHostNameResolver AvahiHostNameResolver; +typedef struct AvahiReverseHostNameResolver AvahiReverseHostNameResolver; +typedef struct AvahiDomainBrowser AvahiDomainBrowser; +typedef struct AvahiServiceTypeBrowser AvahiServiceTypeBrowser; +typedef struct AvahiServiceBrowser AvahiServiceBrowser; +typedef struct AvahiServiceResolver AvahiServiceResolver; + +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 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); +void avahi_host_name_resolver_free(AvahiHostNameResolver *r); #endif diff --git a/avahi-core/iface.c b/avahi-core/iface.c index efd960a..ff7106b 100644 --- a/avahi-core/iface.c +++ b/avahi-core/iface.c @@ -49,7 +49,7 @@ static void update_address_rr(AvahiInterfaceMonitor *m, AvahiInterfaceAddress *a if (!a->entry_group) { a->entry_group = avahi_entry_group_new(m->server, avahi_host_rr_entry_group_callback, NULL); - avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, AF_UNSPEC, 0, NULL, &a->address); + avahi_server_add_address(m->server, a->entry_group, a->interface->hardware->index, a->interface->protocol, 0, NULL, &a->address); avahi_entry_group_commit(a->entry_group); } } else { @@ -102,11 +102,8 @@ static void free_interface(AvahiInterfaceMonitor *m, AvahiInterface *i, gboolean g_assert(m); g_assert(i); - g_message("removing interface %s.%i", i->hardware->name, i->protocol); avahi_goodbye_interface(m->server, i, send_goodbye); - g_message("forcing responses..."); avahi_response_scheduler_force(i->response_scheduler); - g_message("done"); g_assert(!i->announcements); diff --git a/avahi-core/resolve-host-name.c b/avahi-core/resolve-host-name.c new file mode 100644 index 0000000..1eea1c2 --- /dev/null +++ b/avahi-core/resolve-host-name.c @@ -0,0 +1,104 @@ +/* $Id$ */ + +/*** + This file is part of avahi. + + avahi is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of the + License, or (at your option) any later version. + + avahi is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General + Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with avahi; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include "subscribe.h" +#include "util.h" + +struct AvahiHostNameResolver { + AvahiServer *server; + gchar *host_name; + + AvahiRecordResolver *record_resolver_a; + AvahiRecordResolver *record_resolver_aaaa; + + AvahiHostNameResolverCallback callback; + gpointer userdata; + + 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; + AvahiAddress a; + + 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; + + default: + g_assert(FALSE); + } + + r->callback(r, interface, protocol, event, record->key->name, &a, r->userdata); +} + +AvahiHostNameResolver *avahi_host_name_resolver_new(AvahiServer *s, gint interface, guchar protocol, const gchar *host_name, AvahiHostNameResolverCallback callback, gpointer userdata) { + AvahiHostNameResolver *r; + AvahiKey *k; + + g_assert(s); + g_assert(host_name); + g_assert(callback); + + r = g_new(AvahiHostNameResolver, 1); + r->server = s; + 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); + + return r; +} + +void avahi_host_name_resolver_free(AvahiHostNameResolver *r) { + g_assert(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); + g_free(r->host_name); + g_free(r); +} diff --git a/avahi-core/server.c b/avahi-core/server.c index 4085276..1511ac4 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -950,8 +950,9 @@ 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(AvahiSubscription, s->subscriptions); - s->subscription_hashtable = g_hash_table_new((GHashFunc) avahi_key_hash, (GEqualFunc) avahi_key_equal); + 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(AvahiHostNameResolver, s->host_name_resolvers); /* Get host name */ s->host_name = s->config.host_name ? avahi_normalize_name(s->config.host_name) : avahi_get_host_name(); @@ -990,9 +991,12 @@ void avahi_server_free(AvahiServer* s) { while (s->groups) free_group(s, s->groups); - while (s->subscriptions) - avahi_subscription_free(s->subscriptions); - g_hash_table_destroy(s->subscription_hashtable); + while (s->host_name_resolvers) + avahi_host_name_resolver_free(s->host_name_resolvers); + + while (s->record_resolvers) + avahi_record_resolver_free(s->record_resolvers); + g_hash_table_destroy(s->record_resolver_hashtable); g_hash_table_destroy(s->entries_by_key); diff --git a/avahi-core/server.h b/avahi-core/server.h index 7ba4ad9..809ced1 100644 --- a/avahi-core/server.h +++ b/avahi-core/server.h @@ -75,8 +75,9 @@ struct AvahiServer { AVAHI_LLIST_HEAD(AvahiEntryGroup, groups); - AVAHI_LLIST_HEAD(AvahiSubscription, subscriptions); - GHashTable *subscription_hashtable; + AVAHI_LLIST_HEAD(AvahiRecordResolver, record_resolvers); + GHashTable *record_resolver_hashtable; + AVAHI_LLIST_HEAD(AvahiHostNameResolver, host_name_resolvers); gboolean need_entry_cleanup, need_group_cleanup; diff --git a/avahi-core/subscribe.c b/avahi-core/subscribe.c index 975fa1c..db5ed88 100644 --- a/avahi-core/subscribe.c +++ b/avahi-core/subscribe.c @@ -27,7 +27,7 @@ #include "util.h" static void elapse(AvahiTimeEvent *e, void *userdata) { - AvahiSubscription *s = userdata; + AvahiRecordResolver *s = userdata; GTimeVal tv; /* gchar *t; */ @@ -46,7 +46,7 @@ static void elapse(AvahiTimeEvent *e, void *userdata) { } struct cbdata { - AvahiSubscription *subscription; + AvahiRecordResolver *record_resolver; AvahiInterface *interface; }; @@ -58,19 +58,19 @@ static gpointer scan_cache_callback(AvahiCache *c, AvahiKey *pattern, AvahiCache g_assert(e); g_assert(cbdata); - cbdata->subscription->callback( - cbdata->subscription, - e->record, + cbdata->record_resolver->callback( + cbdata->record_resolver, cbdata->interface->hardware->index, cbdata->interface->protocol, - AVAHI_SUBSCRIPTION_NEW, - cbdata->subscription->userdata); + AVAHI_BROWSER_NEW, + e->record, + cbdata->record_resolver->userdata); return NULL; } static void scan_interface_callback(AvahiInterfaceMonitor *m, AvahiInterface *i, gpointer userdata) { - AvahiSubscription *s = userdata; + AvahiRecordResolver *s = userdata; struct cbdata cbdata = { s, i }; g_assert(m); @@ -80,8 +80,8 @@ static void scan_interface_callback(AvahiInterfaceMonitor *m, AvahiInterface *i, avahi_cache_walk(i->cache, s->key, scan_cache_callback, &cbdata); } -AvahiSubscription *avahi_subscription_new(AvahiServer *server, AvahiKey *key, gint interface, guchar protocol, AvahiSubscriptionCallback callback, gpointer userdata) { - AvahiSubscription *s, *t; +AvahiRecordResolver *avahi_record_resolver_new(AvahiServer *server, gint interface, guchar protocol, AvahiKey *key, AvahiRecordResolverCallback callback, gpointer userdata) { + AvahiRecordResolver *s, *t; GTimeVal tv; g_assert(server); @@ -90,7 +90,7 @@ AvahiSubscription *avahi_subscription_new(AvahiServer *server, AvahiKey *key, gi g_assert(!avahi_key_is_pattern(key)); - s = g_new(AvahiSubscription, 1); + s = g_new(AvahiRecordResolver, 1); s->server = server; s->key = avahi_key_ref(key); s->interface = interface; @@ -105,12 +105,12 @@ AvahiSubscription *avahi_subscription_new(AvahiServer *server, AvahiKey *key, gi 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_LLIST_PREPEND(AvahiSubscription, subscriptions, server->subscriptions, s); + AVAHI_LLIST_PREPEND(AvahiRecordResolver, resolver, server->record_resolvers, s); - /* Add the new entry to the subscription hash table */ - t = g_hash_table_lookup(server->subscription_hashtable, key); - AVAHI_LLIST_PREPEND(AvahiSubscription, by_key, t, s); - g_hash_table_replace(server->subscription_hashtable, key, t); + /* 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); /* Scan the caches */ avahi_interface_monitor_walk(s->server->monitor, s->interface, s->protocol, scan_interface_callback, s); @@ -118,19 +118,19 @@ AvahiSubscription *avahi_subscription_new(AvahiServer *server, AvahiKey *key, gi return s; } -void avahi_subscription_free(AvahiSubscription *s) { - AvahiSubscription *t; +void avahi_record_resolver_free(AvahiRecordResolver *s) { + AvahiRecordResolver *t; g_assert(s); - AVAHI_LLIST_REMOVE(AvahiSubscription, subscriptions, s->server->subscriptions, s); + AVAHI_LLIST_REMOVE(AvahiRecordResolver, resolver, s->server->record_resolvers, s); - t = g_hash_table_lookup(s->server->subscription_hashtable, s->key); - AVAHI_LLIST_REMOVE(AvahiSubscription, by_key, t, s); + t = g_hash_table_lookup(s->server->record_resolver_hashtable, s->key); + AVAHI_LLIST_REMOVE(AvahiRecordResolver, by_key, t, s); if (t) - g_hash_table_replace(s->server->subscription_hashtable, t->key, t); + g_hash_table_replace(s->server->record_resolver_hashtable, t->key, t); else - g_hash_table_remove(s->server->subscription_hashtable, s->key); + g_hash_table_remove(s->server->record_resolver_hashtable, s->key); avahi_time_event_queue_remove(s->server->time_event_queue, s->time_event); avahi_key_unref(s->key); @@ -139,20 +139,20 @@ void avahi_subscription_free(AvahiSubscription *s) { g_free(s); } -void avahi_subscription_notify(AvahiServer *server, AvahiInterface *i, AvahiRecord *record, AvahiSubscriptionEvent event) { - AvahiSubscription *s; +void avahi_resolver_notify(AvahiServer *server, AvahiInterface *i, AvahiRecord *record, AvahiBrowserEvent event) { + AvahiRecordResolver *s; g_assert(server); g_assert(record); - for (s = g_hash_table_lookup(server->subscription_hashtable, record->key); s; s = s->by_key_next) + 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, record, i->hardware->index, i->protocol, event, s->userdata); + s->callback(s, i->hardware->index, i->protocol, event, record, s->userdata); } gboolean avahi_is_subscribed(AvahiServer *server, AvahiKey *k) { g_assert(server); g_assert(k); - return !!g_hash_table_lookup(server->subscription_hashtable, k); + return !!g_hash_table_lookup(server->record_resolver_hashtable, k); } diff --git a/avahi-core/subscribe.h b/avahi-core/subscribe.h index 0290085..23b12e5 100644 --- a/avahi-core/subscribe.h +++ b/avahi-core/subscribe.h @@ -28,7 +28,7 @@ #include "timeeventq.h" #include "server.h" -struct AvahiSubscription { +struct AvahiRecordResolver { AvahiServer *server; AvahiKey *key; gint interface; @@ -38,14 +38,14 @@ struct AvahiSubscription { AvahiTimeEvent *time_event; - AvahiSubscriptionCallback callback; + AvahiRecordResolverCallback callback; gpointer userdata; - AVAHI_LLIST_FIELDS(AvahiSubscription, subscriptions); - AVAHI_LLIST_FIELDS(AvahiSubscription, by_key); + AVAHI_LLIST_FIELDS(AvahiRecordResolver, resolver); + AVAHI_LLIST_FIELDS(AvahiRecordResolver, by_key); }; -void avahi_subscription_notify(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, AvahiSubscriptionEvent event); +void avahi_resolver_notify(AvahiServer *s, AvahiInterface *i, AvahiRecord *record, AvahiBrowserEvent event); gboolean avahi_is_subscribed(AvahiServer *s, AvahiKey *k); -- 2.39.5