summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2005-09-10 00:22:30 +0000
committerLennart Poettering <lennart@poettering.net>2005-09-10 00:22:30 +0000
commite8edcf439d2ce1593af11c357893681b6b3c0bb4 (patch)
treed630ac06209abd27e352cef664394bc0cb9b904e
parenta9566d5dcac080d7fa91546823277c57a5d09a5f (diff)
* add magic identification cookies to service TXT records automatically
* add an API to query the local service cookie * add a DBUS interface to query the local service cookie * wrap that in avahi-client git-svn-id: file:///home/lennart/svn/public/avahi/trunk@555 941a03a8-eaeb-0310-b9a0-b1bbd8fe43fe
-rw-r--r--avahi-client/client-test.c4
-rw-r--r--avahi-client/client.c52
-rw-r--r--avahi-client/client.h3
-rw-r--r--avahi-client/internal.h2
-rw-r--r--avahi-common/defs.h9
-rw-r--r--avahi-core/core.h4
-rw-r--r--avahi-core/server.c29
-rw-r--r--avahi-core/server.h2
-rw-r--r--avahi-daemon/Server.introspect4
-rw-r--r--avahi-daemon/dbus-protocol.c20
-rw-r--r--avahi-daemon/main.c2
-rw-r--r--configure.ac6
-rw-r--r--docs/TODO2
13 files changed, 133 insertions, 6 deletions
diff --git a/avahi-client/client-test.c b/avahi-client/client-test.c
index a65a925..96c9f1e 100644
--- a/avahi-client/client-test.c
+++ b/avahi-client/client-test.c
@@ -164,6 +164,7 @@ int main (int argc, char *argv[]) {
AvahiHostNameResolver *hnr;
const char *ret;
int error;
+ uint32_t cookie;
struct timeval tv;
simple_poll = avahi_simple_poll_new();
@@ -188,6 +189,9 @@ int main (int argc, char *argv[]) {
ret = avahi_client_get_host_name_fqdn (avahi);
printf("FQDN: %s (Error Return: %s)\n", ret, ret ? "OK" : avahi_strerror(avahi_client_errno(avahi)));
+ cookie = avahi_client_get_local_service_cookie(avahi);
+ printf("Local service cookie: %u (Error Return: %s)\n", cookie, cookie != AVAHI_SERVICE_COOKIE_INVALID ? "OK" : avahi_strerror(avahi_client_errno(avahi)));
+
group = avahi_entry_group_new (avahi, avahi_entry_group_callback, "omghai");
printf("Creating entry group: %s\n", group ? "OK" : avahi_strerror(avahi_client_errno (avahi)));
diff --git a/avahi-client/client.c b/avahi-client/client.c
index b536beb..31bfcdc 100644
--- a/avahi-client/client.c
+++ b/avahi-client/client.c
@@ -303,7 +303,8 @@ AvahiClient *avahi_client_new(const AvahiPoll *poll_api, AvahiClientCallback cal
client->host_name_fqdn = NULL;
client->domain_name = NULL;
client->version_string = NULL;
-
+ client->local_service_cookie_valid = 0;
+
AVAHI_LLIST_HEAD_INIT(AvahiEntryGroup, client->groups);
AVAHI_LLIST_HEAD_INIT(AvahiDomainBrowser, client->domain_browsers);
AVAHI_LLIST_HEAD_INIT(AvahiServiceBrowser, client->service_browsers);
@@ -594,3 +595,52 @@ fail:
return r;
}
+uint32_t avahi_client_get_local_service_cookie(AvahiClient *client) {
+ DBusMessage *message = NULL, *reply = NULL;
+ DBusError error;
+ assert(client);
+
+ if (client->state == AVAHI_CLIENT_DISCONNECTED) {
+ avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
+ return AVAHI_SERVICE_COOKIE_INVALID;
+ }
+
+ if (client->local_service_cookie_valid)
+ return client->local_service_cookie;
+
+ dbus_error_init (&error);
+
+ if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "GetLocalServiceCookie"))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
+ reply = dbus_connection_send_with_reply_and_block (client->bus, message, -1, &error);
+
+ if (!reply || dbus_error_is_set (&error))
+ goto fail;
+
+ if (!dbus_message_get_args (reply, &error, DBUS_TYPE_UINT32, &client->local_service_cookie, DBUS_TYPE_INVALID) ||
+ dbus_error_is_set (&error))
+ goto fail;
+
+ dbus_message_unref(message);
+ dbus_message_unref(reply);
+
+ client->local_service_cookie_valid = 1;
+ return client->local_service_cookie;
+
+fail:
+
+ if (message)
+ dbus_message_unref(message);
+ if (reply)
+ dbus_message_unref(reply);
+
+ if (dbus_error_is_set(&error)) {
+ avahi_client_set_dbus_error(client, &error);
+ dbus_error_free(&error);
+ }
+
+ return AVAHI_SERVICE_COOKIE_INVALID;
+}
diff --git a/avahi-client/client.h b/avahi-client/client.h
index 2d8f41b..f92f4bf 100644
--- a/avahi-client/client.h
+++ b/avahi-client/client.h
@@ -317,6 +317,9 @@ AvahiClient* avahi_address_resolver_get_client (AvahiAddressResolver *);
/** Free a AvahiAddressResolver resolver object */
int avahi_address_resolver_free(AvahiAddressResolver *r);
+/** Return the local service cookie. returns AVAHI_SERVICE_COOKIE_INVALID on failure. */
+uint32_t avahi_client_get_local_service_cookie(AvahiClient *client);
+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
#endif
diff --git a/avahi-client/internal.h b/avahi-client/internal.h
index b826175..b05835f 100644
--- a/avahi-client/internal.h
+++ b/avahi-client/internal.h
@@ -33,6 +33,8 @@ struct AvahiClient {
/* Cache for some seldom changing server data */
char *version_string, *host_name, *host_name_fqdn, *domain_name;
+ uint32_t local_service_cookie;
+ int local_service_cookie_valid;
AvahiClientCallback callback;
void *userdata;
diff --git a/avahi-common/defs.h b/avahi-common/defs.h
index 1475a43..b973b0c 100644
--- a/avahi-common/defs.h
+++ b/avahi-common/defs.h
@@ -172,6 +172,15 @@ typedef enum {
AVAHI_SERVER_COLLISION /**< There is a collision with a host RR. All host RRs have been withdrawn, the user should set a new host name via avahi_server_set_host_name() */
} AvahiServerState;
+/** For every service a special TXT item is implicitly added, which
+ * contains a random cookie which is private to the local daemon. This
+ * can be used by clients to determine if two services on two
+ * different subnets are effectively the same. */
+#define AVAHI_SERVICE_COOKIE "org.freedesktop.Avahi.cookie"
+
+/** In invalid cookie as special value */
+#define AVAHI_SERVICE_COOKIE_INVALID (0)
+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
#endif
diff --git a/avahi-core/core.h b/avahi-core/core.h
index 1cf35fc..427a09a 100644
--- a/avahi-core/core.h
+++ b/avahi-core/core.h
@@ -85,6 +85,7 @@ typedef struct AvahiServerConfig {
int use_iff_running; /**< Require IFF_RUNNING on local network interfaces. This is the official way to check for link beat. Unfortunately this doesn't work with all drivers. So bettere leave this off. */
int enable_reflector; /**< Reflect incoming mDNS traffic to all local networks. This allows mDNS based network browsing beyond ethernet borders */
int reflect_ipv; /**< if enable_reflector is 1, enable/disable reflecting between IPv4 and IPv6 */
+ int add_service_cookie; /**< Add magic service cookie to all locally generated records implicitly */
} AvahiServerConfig;
/** Allocate a new mDNS responder object. */
@@ -564,6 +565,9 @@ void avahi_s_dns_server_browser_free(AvahiSDNSServerBrowser *b);
/** Return the last error code */
int avahi_server_errno(AvahiServer *s);
+/** Return the local service cookie */
+uint32_t avahi_server_get_local_service_cookie(AvahiServer *s);
+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
#endif
diff --git a/avahi-core/server.c b/avahi-core/server.c
index 66cc705..625af50 100644
--- a/avahi-core/server.c
+++ b/avahi-core/server.c
@@ -31,6 +31,7 @@
#include <errno.h>
#include <stdio.h>
#include <assert.h>
+#include <stdlib.h>
#include <avahi-common/domain.h>
#include <avahi-common/timeval.h>
@@ -1411,6 +1412,10 @@ AvahiServer *avahi_server_new(const AvahiPoll *poll_api, const AvahiServerConfig
s->legacy_unicast_reflect_slots = NULL;
s->legacy_unicast_reflect_id = 0;
+
+ do {
+ s->local_service_cookie = (uint32_t) rand() * (uint32_t) rand();
+ } while (s->local_service_cookie == AVAHI_SERVICE_COOKIE_INVALID);
/* Get host name */
s->host_name = s->config.host_name ? avahi_normalize_name(s->config.host_name) : avahi_get_host_name();
@@ -1849,6 +1854,22 @@ static void escape_service_name(char *d, size_t size, const char *s) {
*(d++) = 0;
}
+static AvahiStringList *add_magic_cookie(
+ AvahiServer *s,
+ AvahiStringList *strlst) {
+
+ assert(s);
+
+ if (!s->config.add_service_cookie)
+ return strlst;
+
+ if (avahi_string_list_find(strlst, AVAHI_SERVICE_COOKIE))
+ /* This string list already contains a magic cookie */
+ return strlst;
+
+ return avahi_string_list_add_printf(strlst, AVAHI_SERVICE_COOKIE"=%u", s->local_service_cookie);
+}
+
static int server_add_service_strlst_nocopy(
AvahiServer *s,
AvahiSEntryGroup *g,
@@ -1919,6 +1940,8 @@ static int server_add_service_strlst_nocopy(
if (ret < 0)
goto fail;
+ strlst = add_magic_cookie(s, strlst);
+
ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_ENTRY_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
strlst = NULL;
@@ -2389,6 +2412,7 @@ AvahiServerConfig* avahi_server_config_init(AvahiServerConfig *c) {
c->use_iff_running = 0;
c->enable_reflector = 0;
c->reflect_ipv = 0;
+ c->add_service_cookie = 1;
return c;
}
@@ -2435,3 +2459,8 @@ int avahi_server_set_errno(AvahiServer *s, int error) {
return s->error = error;
}
+uint32_t avahi_server_get_local_service_cookie(AvahiServer *s) {
+ assert(s);
+
+ return s->local_service_cookie;
+}
diff --git a/avahi-core/server.h b/avahi-core/server.h
index 6ceab42..7384e98 100644
--- a/avahi-core/server.h
+++ b/avahi-core/server.h
@@ -139,6 +139,8 @@ struct AvahiServer {
uint16_t legacy_unicast_reflect_id;
int error;
+
+ uint32_t local_service_cookie;
};
int avahi_server_entry_match_interface(AvahiEntry *e, AvahiInterface *i);
diff --git a/avahi-daemon/Server.introspect b/avahi-daemon/Server.introspect
index 1229733..3cd85f8 100644
--- a/avahi-daemon/Server.introspect
+++ b/avahi-daemon/Server.introspect
@@ -33,6 +33,10 @@
<arg name="state" type="i"/>
</signal>
+ <method name="GetLocalServiceCookie">
+ <arg name="cookie" type="u" direction="out"/>
+ </method>
+
<method name="GetAlternativeHostName">
<arg name="name" type="s" direction="in"/>
<arg name="name" type="s" direction="out"/>
diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c
index 9cc4434..61d26d0 100644
--- a/avahi-daemon/dbus-protocol.c
+++ b/avahi-daemon/dbus-protocol.c
@@ -452,6 +452,17 @@ static DBusHandlerResult respond_int32(DBusConnection *c, DBusMessage *m, int32_
return DBUS_HANDLER_RESULT_HANDLED;
}
+static DBusHandlerResult respond_uint32(DBusConnection *c, DBusMessage *m, uint32_t u) {
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(m);
+ dbus_message_append_args(reply, DBUS_TYPE_UINT32, &u, DBUS_TYPE_INVALID);
+ dbus_connection_send(c, reply, NULL);
+ dbus_message_unref(reply);
+
+ return DBUS_HANDLER_RESULT_HANDLED;
+}
+
static DBusHandlerResult respond_ok(DBusConnection *c, DBusMessage *m) {
DBusMessage *reply;
@@ -1541,6 +1552,15 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void
state = avahi_server_get_state(avahi_server);
return respond_int32(c, m, (int32_t) state);
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetLocalServiceCookie")) {
+
+ if (!(dbus_message_get_args(m, &error, DBUS_TYPE_INVALID))) {
+ avahi_log_warn("Error parsing Server::GetLocalServiceCookie message");
+ goto fail;
+ }
+
+ return respond_uint32(c, m, avahi_server_get_local_service_cookie(avahi_server));
+
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetNetworkInterfaceNameByIndex")) {
int32_t idx;
int fd;
diff --git a/avahi-daemon/main.c b/avahi-daemon/main.c
index 566a276..dab65f7 100644
--- a/avahi-daemon/main.c
+++ b/avahi-daemon/main.c
@@ -220,7 +220,7 @@ static void server_callback(AvahiServer *s, AvahiServerState state, void *userda
#endif
if (state == AVAHI_SERVER_RUNNING) {
- avahi_log_info("Server startup complete. Host name is %s.", avahi_server_get_host_name_fqdn(s));
+ avahi_log_info("Server startup complete. Host name is %s. Local service cookie is %u.", avahi_server_get_host_name_fqdn(s), avahi_server_get_local_service_cookie(s));
static_service_add_to_server();
remove_dns_server_entry_groups();
diff --git a/configure.ac b/configure.ac
index 1bd727a..38a7332 100644
--- a/configure.ac
+++ b/configure.ac
@@ -28,9 +28,9 @@ AM_INIT_AUTOMAKE([foreign 1.9 -Wall])
AC_SUBST(PACKAGE_URL, [http://www.freedesktop.org/Software/Avahi])
-AC_SUBST(LIBAVAHI_COMMON_VERSION_INFO, [1:0:1])
-AC_SUBST(LIBAVAHI_CORE_VERSION_INFO, [0:2:0])
-AC_SUBST(LIBAVAHI_CLIENT_VERSION_INFO, [1:0:0])
+AC_SUBST(LIBAVAHI_COMMON_VERSION_INFO, [1:1:1])
+AC_SUBST(LIBAVAHI_CORE_VERSION_INFO, [1:0:0])
+AC_SUBST(LIBAVAHI_CLIENT_VERSION_INFO, [1:1:0])
AC_SUBST(LIBAVAHI_GLIB_VERSION_INFO, [0:1:0])
AC_SUBST(LIBAVAHI_QT3_VERSION_INFO, [0:0:0])
AC_SUBST(LIBAVAHI_QT4_VERSION_INFO, [0:0:0])
diff --git a/docs/TODO b/docs/TODO
index a5e32cf..97b8aac 100644
--- a/docs/TODO
+++ b/docs/TODO
@@ -2,7 +2,6 @@ todo:
* Add sensible record updating API
* Passive observation of failures
* support for special domain PTR records based on local IP subnet address
-* add identical service detection cookie
* add API to detect if a service is local
* add subtype browsing
* add wide area support (i.e. DNS-SD over unicast DNS)
@@ -61,3 +60,4 @@ done:
* examples
* publish IP addresses with scope "link" only, unless ther are the only one the interface
* release 0.2!
+* add identical service detection cookie