]> git.meshlink.io Git - catta/commitdiff
* add magic identification cookies to service TXT records automatically
authorLennart Poettering <lennart@poettering.net>
Sat, 10 Sep 2005 00:22:30 +0000 (00:22 +0000)
committerLennart Poettering <lennart@poettering.net>
Sat, 10 Sep 2005 00:22:30 +0000 (00:22 +0000)
* 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

13 files changed:
avahi-client/client-test.c
avahi-client/client.c
avahi-client/client.h
avahi-client/internal.h
avahi-common/defs.h
avahi-core/core.h
avahi-core/server.c
avahi-core/server.h
avahi-daemon/Server.introspect
avahi-daemon/dbus-protocol.c
avahi-daemon/main.c
configure.ac
docs/TODO

index a65a92554618e91d3c0b5f20bf155dd2e0b4a133..96c9f1e0d891c00466318bbd274f3b47b5aa5818 100644 (file)
@@ -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)));
 
index b536beb5ee9a8d37bed4c8d9526a12f67c1962cb..31bfcdcf57b41d1f4f6000ee4c49eeddc13b5835 100644 (file)
@@ -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;
+}
index 2d8f41b6058935730ccb111585acfaf820e04e8b..f92f4bff53df5afdf2f81f97362377da184a0e90 100644 (file)
@@ -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
index b826175e04125d0361862019a56a74322e0a1d8d..b05835f722d845c4969dc1e85355d65f33c7723d 100644 (file)
@@ -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;
index 1475a43946b858fc9499829fbe4d40288eaa30e1..b973b0cbf12a63e7293deca85895b9d9e24c9c35 100644 (file)
@@ -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
index 1cf35fc2f2cacea5955143c622eee0e40607d39d..427a09a36298005b47d05cf2186e9ad9b55c4a8b 100644 (file)
@@ -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
index 66cc70592699286d40120494f45b44263729989e..625af50f349cbe911ef9043721e6eb7ea5695f6f 100644 (file)
@@ -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;
+}
index 6ceab429c771db674a60ca016d2af1667f5e8397..7384e9879f18b05b0368715e4473096a7bf8de3f 100644 (file)
@@ -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);
index 1229733ff89f55f3d11f6b6d62be2519ccf77c1f..3cd85f8913fb4f6231adf40693f7f07770d78ce2 100644 (file)
       <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"/>
index 9cc4434b4718acd67756ac086f0fba207667feb3..61d26d0a0ad6f8566c30388067b4dfff20353fc3 100644 (file)
@@ -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;
index 566a276d599355d4b23324b142fc6e01ac1c0ce4..dab65f7722ab13233e423e948e5740817663d2f6 100644 (file)
@@ -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();
index 1bd727aa322dd2c190c051e05bc498232431a0f6..38a7332e37fb1feb90efb97463bb9e47b6da0cf3 100644 (file)
@@ -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])
index a5e32cf323d99be6ca8165800ed475604597c2ef..97b8aacfd4478c8cb5aeb8bf672e76e9639d05db 100644 (file)
--- 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