diff options
| author | Lennart Poettering <lennart@poettering.net> | 2005-09-10 00:22:30 +0000 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2005-09-10 00:22:30 +0000 | 
| commit | e8edcf439d2ce1593af11c357893681b6b3c0bb4 (patch) | |
| tree | d630ac06209abd27e352cef664394bc0cb9b904e | |
| parent | a9566d5dcac080d7fa91546823277c57a5d09a5f (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.c | 4 | ||||
| -rw-r--r-- | avahi-client/client.c | 52 | ||||
| -rw-r--r-- | avahi-client/client.h | 3 | ||||
| -rw-r--r-- | avahi-client/internal.h | 2 | ||||
| -rw-r--r-- | avahi-common/defs.h | 9 | ||||
| -rw-r--r-- | avahi-core/core.h | 4 | ||||
| -rw-r--r-- | avahi-core/server.c | 29 | ||||
| -rw-r--r-- | avahi-core/server.h | 2 | ||||
| -rw-r--r-- | avahi-daemon/Server.introspect | 4 | ||||
| -rw-r--r-- | avahi-daemon/dbus-protocol.c | 20 | ||||
| -rw-r--r-- | avahi-daemon/main.c | 2 | ||||
| -rw-r--r-- | configure.ac | 6 | ||||
| -rw-r--r-- | docs/TODO | 2 | 
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]) @@ -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 | 
