AvahiHostNameResolver *hnr;
const char *ret;
int error;
+ uint32_t cookie;
struct timeval tv;
simple_poll = avahi_simple_poll_new();
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)));
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);
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;
+}
/** 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
/* 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;
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
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. */
/** 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
#include <errno.h>
#include <stdio.h>
#include <assert.h>
+#include <stdlib.h>
#include <avahi-common/domain.h>
#include <avahi-common/timeval.h>
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();
*(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,
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;
c->use_iff_running = 0;
c->enable_reflector = 0;
c->reflect_ipv = 0;
+ c->add_service_cookie = 1;
return c;
}
return s->error = error;
}
+uint32_t avahi_server_get_local_service_cookie(AvahiServer *s) {
+ assert(s);
+
+ return s->local_service_cookie;
+}
uint16_t legacy_unicast_reflect_id;
int error;
+
+ uint32_t local_service_cookie;
};
int avahi_server_entry_match_interface(AvahiEntry *e, AvahiInterface *i);
<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"/>
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;
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;
#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();
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])
* 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)
* examples
* publish IP addresses with scope "link" only, unless ther are the only one the interface
* release 0.2!
+* add identical service detection cookie