From e2f7e83d25a5f0966938163c18b1fd8c399393b1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 3 Nov 2005 23:36:25 +0000 Subject: [PATCH] * allow the user to specify a static browse domain list in the configuration file * remove "drop-root" configuration variable * move the configuration variable "add-service-cookie" from [server] to [publish] * reorder AVAHI_DOMAIN_BROWSER_xx defs git-svn-id: file:///home/lennart/svn/public/avahi/trunk@926 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe --- avahi-common/defs.h | 7 +-- avahi-common/strlst.c | 5 +- avahi-core/browse-domain.c | 90 ++++++++++++++++++++++++++++++++-- avahi-core/core.h | 1 + avahi-core/internal.h | 2 + avahi-core/server.c | 10 ++++ avahi-daemon/avahi-daemon.conf | 3 +- avahi-daemon/ini-file-parser.c | 12 ++++- avahi-daemon/main.c | 27 ++++++++-- avahi-sharp/DomainBrowser.cs | 4 +- docs/TODO | 1 + 11 files changed, 143 insertions(+), 19 deletions(-) diff --git a/avahi-common/defs.h b/avahi-common/defs.h index 4393e98..8167f34 100644 --- a/avahi-common/defs.h +++ b/avahi-common/defs.h @@ -156,10 +156,10 @@ typedef enum { /** The type of domain to browse for */ typedef enum { - AVAHI_DOMAIN_BROWSER_REGISTER, /**< Browse for a list of available registering domains */ - AVAHI_DOMAIN_BROWSER_REGISTER_DEFAULT, /**< Browse for the default registering domain */ AVAHI_DOMAIN_BROWSER_BROWSE, /**< Browse for a list of available browsing domains */ AVAHI_DOMAIN_BROWSER_BROWSE_DEFAULT, /**< Browse for the default browsing domain */ + AVAHI_DOMAIN_BROWSER_REGISTER, /**< Browse for a list of available registering domains */ + AVAHI_DOMAIN_BROWSER_REGISTER_DEFAULT, /**< Browse for the default registering domain */ AVAHI_DOMAIN_BROWSER_BROWSE_LEGACY, /**< Legacy browse domain - see DNS-SD spec for more information */ AVAHI_DOMAIN_BROWSER_MAX } AvahiDomainBrowserType; @@ -189,7 +189,8 @@ typedef enum { AVAHI_LOOKUP_RESULT_WIDE_AREA = 2, /**< This response originates from wide area DNS */ AVAHI_LOOKUP_RESULT_MULTICAST = 4, /**< This response originates from multicast DNS */ AVAHI_LOOKUP_RESULT_LOCAL = 8, /**< This record/service resides on and was announced by the local host. Only available in service and record browsers and only on AVAHI_BROWSER_NEW. */ - AVAHI_LOOKUP_RESULT_OUR_OWN = 16 /**< This service belongs to the same local client as the browser object. Only available in avahi-client, and only for service browsers and only on AVAHI_BROWSER_NEW. */ + AVAHI_LOOKUP_RESULT_OUR_OWN = 16, /**< This service belongs to the same local client as the browser object. Only available in avahi-client, and only for service browsers and only on AVAHI_BROWSER_NEW. */ + AVAHI_LOOKUP_RESULT_STATIC = 32 /**< The returned data has been defined statically by some configuration option */ } AvahiLookupResultFlags; /** Type of callback event when browsing */ diff --git a/avahi-common/strlst.c b/avahi-common/strlst.c index 4b96112..0111870 100644 --- a/avahi-common/strlst.c +++ b/avahi-common/strlst.c @@ -299,7 +299,10 @@ AvahiStringList *avahi_string_list_copy(const AvahiStringList *l) { AvahiStringList *r = NULL; for (; l; l = l->next) - r = avahi_string_list_add_arbitrary(r, l->text, l->size); + if (!(r = avahi_string_list_add_arbitrary(r, l->text, l->size))) { + avahi_string_list_free(r); + return NULL; + } return avahi_string_list_reverse(r); } diff --git a/avahi-core/browse-domain.c b/avahi-core/browse-domain.c index 5074469..4c78832 100644 --- a/avahi-core/browse-domain.c +++ b/avahi-core/browse-domain.c @@ -28,18 +28,33 @@ #include #include "browse.h" +#include "log.h" struct AvahiSDomainBrowser { + int ref; + AvahiServer *server; AvahiSRecordBrowser *record_browser; - + + AvahiDomainBrowserType type; AvahiSDomainBrowserCallback callback; void* userdata; + AvahiTimeEvent *defer_event; + + int all_for_now_scheduled; + AVAHI_LLIST_FIELDS(AvahiSDomainBrowser, browser); }; +static void inc_ref(AvahiSDomainBrowser *b) { + assert(b); + assert(b->ref >= 1); + + b->ref++; +} + static void record_browser_callback( AvahiSRecordBrowser*rr, AvahiIfIndex interface, @@ -55,17 +70,69 @@ static void record_browser_callback( assert(rr); assert(b); + if (event == AVAHI_BROWSER_ALL_FOR_NOW && + b->defer_event) { + + b->all_for_now_scheduled = 1; + return; + } + /* Filter flags */ flags &= AVAHI_LOOKUP_RESULT_CACHED | AVAHI_LOOKUP_RESULT_MULTICAST | AVAHI_LOOKUP_RESULT_WIDE_AREA; - + if (record) { assert(record->key->type == AVAHI_DNS_TYPE_PTR); n = record->data.ptr.name; + + if (b->type == AVAHI_DOMAIN_BROWSER_BROWSE) { + AvahiStringList *l; + + /* Filter out entries defined statically */ + + for (l = b->server->config.browse_domains; l; l = l->next) + if (avahi_domain_equal((char*) l->text, n)) + return; + } + } b->callback(b, interface, protocol, event, n, flags, b->userdata); } +static void defer_callback(AvahiTimeEvent *e, void *userdata) { + AvahiSDomainBrowser *b = userdata; + AvahiStringList *l; + + assert(e); + assert(b); + + avahi_time_event_free(b->defer_event); + b->defer_event = NULL; + + /* Increase ref counter */ + inc_ref(b); + + for (l = b->server->config.browse_domains; l; l = l->next) { + + /* Check whether this object still exists outside our own + * stack frame */ + if (b->ref <= 1) + break; + + b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_BROWSER_NEW, (char*) l->text, AVAHI_LOOKUP_RESULT_STATIC, b->userdata); + } + + if (b->ref > 1) { + /* If the ALL_FOR_NOW event has already been scheduled, execute it now */ + + if (b->all_for_now_scheduled) + b->callback(b, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, AVAHI_BROWSER_ALL_FOR_NOW, NULL, 0, b->userdata); + } + + /* Decrease ref counter */ + avahi_s_domain_browser_free(b); +} + AvahiSDomainBrowser *avahi_s_domain_browser_new( AvahiServer *server, AvahiIfIndex interface, @@ -77,10 +144,10 @@ AvahiSDomainBrowser *avahi_s_domain_browser_new( void* userdata) { static const char * const type_table[AVAHI_DOMAIN_BROWSER_MAX] = { - "r", - "dr", "b", "db", + "r", + "dr", "lb" }; @@ -110,11 +177,14 @@ AvahiSDomainBrowser *avahi_s_domain_browser_new( avahi_server_set_errno(server, AVAHI_ERR_NO_MEMORY); return NULL; } - + + b->ref = 1; b->server = server; b->callback = callback; b->userdata = userdata; b->record_browser = NULL; + b->type = type; + b->all_for_now_scheduled = 0; AVAHI_LLIST_PREPEND(AvahiSDomainBrowser, browser, server->domain_browsers, b); @@ -127,6 +197,9 @@ AvahiSDomainBrowser *avahi_s_domain_browser_new( goto fail; avahi_key_unref(k); + + b->defer_event = avahi_time_event_new(server->time_event_queue, NULL, defer_callback, b); + return b; fail: @@ -142,10 +215,17 @@ fail: void avahi_s_domain_browser_free(AvahiSDomainBrowser *b) { assert(b); + assert(b->ref >= 1); + if (--b->ref > 0) + return; + AVAHI_LLIST_REMOVE(AvahiSDomainBrowser, browser, b->server->domain_browsers, b); if (b->record_browser) avahi_s_record_browser_free(b->record_browser); + + if (b->defer_event) + avahi_time_event_free(b->defer_event); avahi_free(b); } diff --git a/avahi-core/core.h b/avahi-core/core.h index 78020ee..64db69c 100644 --- a/avahi-core/core.h +++ b/avahi-core/core.h @@ -60,6 +60,7 @@ typedef struct AvahiServerConfig { AvahiAddress wide_area_servers[AVAHI_WIDE_AREA_SERVERS_MAX]; /** Unicast DNS server to use for wide area lookup */ unsigned n_wide_area_servers; /**< Number of servers in wide_area_servers[] */ int disallow_other_stacks; /**< Make sure that only one mDNS responder is run at the same time on the local machine. If this is enable Avahi will not set SO_REUSADDR on its sockets, effectively preventing other stacks from running on the local machine */ + AvahiStringList *browse_domains; /**< Additional browsing domains */ } AvahiServerConfig; /** Allocate a new mDNS responder object. */ diff --git a/avahi-core/internal.h b/avahi-core/internal.h index 813eacd..e360889 100644 --- a/avahi-core/internal.h +++ b/avahi-core/internal.h @@ -157,6 +157,8 @@ struct AvahiServer { AvahiMulticastLookupEngine *multicast_lookup_engine; AvahiWideAreaLookupEngine *wide_area_lookup_engine; + + AvahiStringList *static_browse_domains; }; void avahi_entry_free(AvahiServer*s, AvahiEntry *e); diff --git a/avahi-core/server.c b/avahi-core/server.c index 3d53154..d92afac 100644 --- a/avahi-core/server.c +++ b/avahi-core/server.c @@ -1528,6 +1528,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) { c->enable_wide_area = 0; c->n_wide_area_servers = 0; c->disallow_other_stacks = 0; + c->browse_domains = NULL; return c; } @@ -1537,10 +1538,12 @@ void avahi_server_config_free(AvahiServerConfig *c) { avahi_free(c->host_name); avahi_free(c->domain_name); + avahi_string_list_free(c->browse_domains); } AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiServerConfig *c) { char *d = NULL, *h = NULL; + AvahiStringList *l = NULL; assert(ret); assert(c); @@ -1553,10 +1556,17 @@ AvahiServerConfig* avahi_server_config_copy(AvahiServerConfig *ret, const AvahiS avahi_free(h); return NULL; } + + if (!(l = avahi_string_list_copy(c->browse_domains)) && c->browse_domains) { + avahi_free(h); + avahi_free(d); + return NULL; + } *ret = *c; ret->host_name = h; ret->domain_name = d; + ret->browse_domains = l; return ret; } diff --git a/avahi-daemon/avahi-daemon.conf b/avahi-daemon/avahi-daemon.conf index b812d37..ce6b0a2 100644 --- a/avahi-daemon/avahi-daemon.conf +++ b/avahi-daemon/avahi-daemon.conf @@ -1,18 +1,19 @@ [server] #host-name=foo #domain-name=local +browse-domains=0pointer.de, zeroconf.org, dns-sd.org use-ipv4=yes use-ipv6=no check-response-ttl=no use-iff-running=no enable-dbus=yes -add-service-cookie=yes disallow-other-stacks=no [wide-area] enable-wide-area=yes [publish] +add-service-cookie=yes publish-addresses=yes publish-hinfo=yes publish-workstation=yes diff --git a/avahi-daemon/ini-file-parser.c b/avahi-daemon/ini-file-parser.c index 03a3f8b..135876e 100644 --- a/avahi-daemon/ini-file-parser.c +++ b/avahi-daemon/ini-file-parser.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -155,9 +156,16 @@ char** avahi_split_csv(const char *t) { i = r = avahi_new(char*, n_comma+2); for (;;) { - size_t l = strcspn(t, ","); + size_t n, l = strcspn(t, ","); + const char *c; - *(i++) = avahi_strndup(t, l); + /* Ignore leading blanks */ + for (c = t, n = l; isblank(*c); c++, n--); + + /* Ignore trailing blanks */ + for (; n > 0 && isblank(c[n-1]); n--); + + *(i++) = avahi_strndup(c, n); t += l; diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c index 45c4f59..a903e63 100644 --- a/avahi-daemon/main.c +++ b/avahi-daemon/main.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -457,6 +458,24 @@ static int load_config_file(DaemonConfig *c) { } else if (strcasecmp(p->key, "domain-name") == 0) { avahi_free(c->server_config.domain_name); c->server_config.domain_name = avahi_strdup(p->value); + } else if (strcasecmp(p->key, "browse-domains") == 0) { + char **e, **t; + + e = avahi_split_csv(p->value); + + for (t = e; *t; t++) { + char cleaned[AVAHI_DOMAIN_NAME_MAX]; + + if (!avahi_normalize_name(*t, cleaned, sizeof(cleaned))) { + avahi_log_error("Invalid domain name \"%s\" for key \"%s\" in group \"%s\"\n", *t, p->key, g->name); + avahi_strfreev(e); + goto finish; + } + + c->server_config.browse_domains = avahi_string_list_add(c->server_config.browse_domains, cleaned); + } + + avahi_strfreev(e); } else if (strcasecmp(p->key, "use-ipv4") == 0) c->server_config.use_ipv4 = is_yes(p->value); else if (strcasecmp(p->key, "use-ipv6") == 0) @@ -481,10 +500,6 @@ static int load_config_file(DaemonConfig *c) { } } #endif - else if (strcasecmp(p->key, "drop-root") == 0) - c->drop_root = is_yes(p->value); - else if (strcasecmp(p->key, "add-service-cookie") == 0) - c->server_config.add_service_cookie = is_yes(p->value); else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; @@ -506,9 +521,11 @@ static int load_config_file(DaemonConfig *c) { c->server_config.publish_domain = is_yes(p->value); else if (strcasecmp(p->key, "publish-resolv-conf-dns-servers") == 0) c->publish_resolv_conf = is_yes(p->value); + else if (strcasecmp(p->key, "add-service-cookie") == 0) + c->server_config.add_service_cookie = is_yes(p->value); else if (strcasecmp(p->key, "publish-dns-servers") == 0) { avahi_strfreev(c->publish_dns_servers); - c->publish_dns_servers = avahi_split_csv(p->value); + c->publish_dns_servers = avahi_split_csv(p->value); } else { avahi_log_error("Invalid configuration key \"%s\" in group \"%s\"\n", p->key, g->name); goto finish; diff --git a/avahi-sharp/DomainBrowser.cs b/avahi-sharp/DomainBrowser.cs index 3ce9e4d..08f2b35 100644 --- a/avahi-sharp/DomainBrowser.cs +++ b/avahi-sharp/DomainBrowser.cs @@ -29,10 +29,10 @@ namespace Avahi IntPtr domain, LookupResultFlags flags, IntPtr userdata); public enum DomainBrowserType { - Register, - RegisterDefault, Browse, BrowseDefault, + Register, + RegisterDefault, BrowseLegacy } diff --git a/docs/TODO b/docs/TODO index 56a4a78..bf3753f 100644 --- a/docs/TODO +++ b/docs/TODO @@ -7,6 +7,7 @@ for 0.6: * add support for defining browsing domains with an option in avahi-daemon.onf * fix python scripts * update man pages +* return an error when the user tries to register a service in a domain != .local, for now later: * avahi-client: do something about letting the client know if the daemon comes back from a DISCONNECTED state -- 2.39.5