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 \
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);
}
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);
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);
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;
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
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 {
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);
--- /dev/null
+/* $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 <config.h>
+#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);
+}
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();
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);
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;
#include "util.h"
static void elapse(AvahiTimeEvent *e, void *userdata) {
- AvahiSubscription *s = userdata;
+ AvahiRecordResolver *s = userdata;
GTimeVal tv;
/* gchar *t; */
}
struct cbdata {
- AvahiSubscription *subscription;
+ AvahiRecordResolver *record_resolver;
AvahiInterface *interface;
};
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);
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);
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;
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);
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);
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);
}
#include "timeeventq.h"
#include "server.h"
-struct AvahiSubscription {
+struct AvahiRecordResolver {
AvahiServer *server;
AvahiKey *key;
gint interface;
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);