db->callback = callback;
db->userdata = userdata;
db->path = NULL;
+ db->interface = interface;
+ db->protocol = protocol;
AVAHI_LLIST_PREPEND(AvahiDomainBrowser, domain_browsers, client->domain_browsers, db);
return NULL;
}
-AvahiClient* avahi_domain_browser_get_client (AvahiDomainBrowser *b)
-{
+AvahiClient* avahi_domain_browser_get_client (AvahiDomainBrowser *b) {
assert(b);
return b->client;
}
DBusError error;
const char *path;
char *domain = NULL;
- int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
+ int32_t interface, protocol;
uint32_t flags = 0;
assert(client);
if (!db)
goto fail;
+ interface = db->interface;
+ protocol = db->protocol;
+
switch (event) {
case AVAHI_BROWSER_NEW:
case AVAHI_BROWSER_REMOVE:
b->callback = callback;
b->userdata = userdata;
b->path = NULL;
+ b->domain = NULL;
+ b->interface = interface;
+ b->protocol = protocol;
AVAHI_LLIST_PREPEND(AvahiServiceTypeBrowser, service_type_browsers, client->service_type_browsers, b);
+ if (domain[0])
+ if (!(b->domain = avahi_strdup(domain))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceTypeBrowserNew"))) {
avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
goto fail;
return NULL;
}
-AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *b)
-{
+AvahiClient* avahi_service_type_browser_get_client (AvahiServiceTypeBrowser *b) {
assert(b);
return b->client;
}
AVAHI_LLIST_REMOVE(AvahiServiceTypeBrowser, service_type_browsers, b->client->service_type_browsers, b);
avahi_free(b->path);
+ avahi_free(b->domain);
avahi_free(b);
return r;
}
AvahiServiceTypeBrowser *b = NULL;
DBusError error;
const char *path;
- char *domain = NULL, *type = NULL;
- int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
+ char *domain, *type = NULL;
+ int32_t interface, protocol;
uint32_t flags = 0;
assert(client);
if (!b)
goto fail;
+
+ domain = b->domain;
+ interface = b->interface;
+ protocol = b->protocol;
+
switch (event) {
case AVAHI_BROWSER_NEW:
case AVAHI_BROWSER_REMOVE:
b->callback = callback;
b->userdata = userdata;
b->path = NULL;
+ b->type = b->domain = NULL;
+ b->interface = interface;
+ b->protocol = protocol;
AVAHI_LLIST_PREPEND(AvahiServiceBrowser, service_browsers, client->service_browsers, b);
+ if (!(b->type = avahi_strdup(type))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
+ if (domain && domain[0])
+ if (!(b->domain = avahi_strdup(domain))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
if (!(message = dbus_message_new_method_call (AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew"))) {
avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
goto fail;
return NULL;
}
-AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *b)
-{
+AvahiClient* avahi_service_browser_get_client (AvahiServiceBrowser *b) {
assert(b);
return b->client;
}
AVAHI_LLIST_REMOVE(AvahiServiceBrowser, service_browsers, b->client->service_browsers, b);
avahi_free(b->path);
+ avahi_free(b->type);
+ avahi_free(b->domain);
avahi_free(b);
return r;
}
-
DBusHandlerResult avahi_service_browser_event(AvahiClient *client, AvahiBrowserEvent event, DBusMessage *message) {
AvahiServiceBrowser *b = NULL;
DBusError error;
const char *path;
- char *name = NULL, *type = NULL, *domain = NULL;
- int32_t interface = AVAHI_IF_UNSPEC, protocol = AVAHI_PROTO_UNSPEC;
+ char *name = NULL, *type, *domain;
+ int32_t interface, protocol;
uint32_t flags = 0;
dbus_error_init (&error);
if (!b)
goto fail;
+ type = b->type;
+ domain = b->domain;
+ interface = b->interface;
+ protocol = b->protocol;
+
switch (event) {
case AVAHI_BROWSER_NEW:
case AVAHI_BROWSER_REMOVE:
#include <avahi-common/error.h>
#include <avahi-common/simple-watch.h>
#include <avahi-common/malloc.h>
+#include <avahi-common/timeval.h>
static const AvahiPoll *poll_api = NULL;
static AvahiSimplePoll *simple_poll = NULL;
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiResolverEvent event,
- AvahiProtocol aprotocol,
const AvahiAddress *address,
const char *name,
AvahiLookupResultFlags flags,
return;
}
avahi_address_snprint (addr, sizeof (addr), address);
- printf ("ADDRESS-RESOLVER: Callback on AddressResolver, interface (%d), protocol (%d), even (%d), aprotocol (%d), address (%s), name (%s), data(%s)\n", interface, protocol, event, aprotocol, addr, name, (char*) userdata);
+ printf ("ADDRESS-RESOLVER: Callback on AddressResolver, interface (%d), protocol (%d), even (%d), address (%s), name (%s), data(%s)\n", interface, protocol, event, addr, name, (char*) userdata);
}
static void avahi_host_name_resolver_callback (
return;
}
client = avahi_host_name_resolver_get_client (r);
- ar = avahi_address_resolver_new_a (client, interface, protocol, a, 0, avahi_address_resolver_callback, "omghai6u");
+ ar = avahi_address_resolver_new(client, interface, protocol, a, 0, avahi_address_resolver_callback, "omghai6u");
if (ar)
{
printf ("Succesfully created address resolver object\n");
group2 = avahi_entry_group_new (avahi, avahi_entry_group2_callback, "omghai222");
if ((error = avahi_entry_group_add_address (group2, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, 0, "test-mdns.local.", aar)) < 0)
{
- printf ("*** failed to add address to entry group: %s\n", avahi_strerror (ret));
+ printf ("*** failed to add address to entry group: %s\n", avahi_strerror (error));
avahi_entry_group_free (group2);
} else {
printf ("*** success, added address\n");
return AVAHI_SERVICE_COOKIE_INVALID;
}
-
-int avahi_client_is_service_local(AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain) {
- DBusMessage *message = NULL, *reply = NULL;
- DBusError error;
- int32_t i_interface, i_protocol;
- int b;
-
- assert(client);
- assert(name);
- assert(type);
- assert(domain);
-
- if (client->state == AVAHI_CLIENT_DISCONNECTED) {
- avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
- return AVAHI_SERVICE_COOKIE_INVALID;
- }
-
- dbus_error_init (&error);
-
- if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "IsServiceLocal"))) {
- avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
- goto fail;
- }
-
- i_interface = (int32_t) interface;
- i_protocol = (int32_t) protocol;
-
- if (!dbus_message_append_args(
- message,
- DBUS_TYPE_INT32, &i_interface,
- DBUS_TYPE_INT32, &i_protocol,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &type,
- DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_INVALID)) {
- 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_BOOLEAN, &b, DBUS_TYPE_INVALID) ||
- dbus_error_is_set (&error))
- goto fail;
-
- dbus_message_unref(message);
- dbus_message_unref(reply);
-
- return b;
-
-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;
-}
/** Return the local service cookie. returns AVAHI_SERVICE_COOKIE_INVALID on failure. */
uint32_t avahi_client_get_local_service_cookie(AvahiClient *client);
-/** Return 1 if the specified service is a registered locally, negative on failure, 0 otherwise. */
-int avahi_client_is_service_local(AvahiClient *client, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain);
-
#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
#endif
AvahiStringList *p;
assert(message);
- assert(txt);
dbus_message_iter_init_append(message, &iter);
AvahiDomainBrowserCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiDomainBrowser, domain_browsers);
+
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
};
struct AvahiServiceBrowser {
AvahiServiceBrowserCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiServiceBrowser, service_browsers);
+
+ char *type, *domain;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
};
struct AvahiServiceTypeBrowser {
AvahiServiceTypeBrowserCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiServiceTypeBrowser, service_type_browsers);
+
+ char *domain;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
};
struct AvahiServiceResolver {
AvahiServiceResolverCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiServiceResolver, service_resolvers);
+
+ char *name, *type, *domain;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
};
struct AvahiHostNameResolver {
AvahiHostNameResolverCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiHostNameResolver, host_name_resolvers);
+
+ char *host_name;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
};
struct AvahiAddressResolver {
AvahiAddressResolverCallback callback;
void *userdata;
AVAHI_LLIST_FIELDS(AvahiAddressResolver, address_resolvers);
+
+ AvahiAddress address;
+ AvahiIfIndex interface;
+ AvahiProtocol protocol;
};
int avahi_client_set_errno (AvahiClient *client, int error);
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiResolverEvent event,
- AvahiProtocol aprotocol,
const AvahiAddress *a,
const char *name,
AvahiLookupResultFlags flags,
void *userdata);
-
/** Browse for domains on the local network */
AvahiDomainBrowser* avahi_domain_browser_new (
AvahiClient *client,
/** Free a hostname resolver object */
int avahi_host_name_resolver_free(AvahiHostNameResolver *r);
-/** Create a new address resolver object from an address string. Set aprotocol to AF_UNSPEC for protocol detection. */
-AvahiAddressResolver * avahi_address_resolver_new(
- AvahiClient *client,
- AvahiIfIndex interface,
- AvahiProtocol protocol,
- const char *address,
- AvahiLookupFlags flags,
- AvahiAddressResolverCallback callback,
- void *userdata);
-
/** Create a new address resolver object from an AvahiAddress object */
-AvahiAddressResolver* avahi_address_resolver_new_a(
+AvahiAddressResolver* avahi_address_resolver_new(
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
}
avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
- r->callback(r, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, NULL, NULL, NULL, NULL, 0, NULL, 0, r->userdata);
+ r->callback(r, r->interface, r->protocol, event, r->name, r->type, r->domain, NULL, NULL, 0, NULL, 0, r->userdata);
break;
}
}
r->callback = callback;
r->userdata = userdata;
r->path = NULL;
+ r->name = r->type = r->domain = NULL;
+ r->interface = interface;
+ r->protocol = protocol;
AVAHI_LLIST_PREPEND(AvahiServiceResolver, service_resolvers, client->service_resolvers, r);
+ if (name && name[0])
+ if (!(r->name = avahi_strdup(name))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
+ if (!(r->type = avahi_strdup(type))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
+ if (domain && domain[0])
+ if (!(r->domain = avahi_strdup(domain))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
+
if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "ServiceResolverNew"))) {
avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
goto fail;
AVAHI_LLIST_REMOVE(AvahiServiceResolver, service_resolvers, client->service_resolvers, r);
avahi_free(r->path);
+ avahi_free(r->name);
+ avahi_free(r->type);
+ avahi_free(r->domain);
avahi_free(r);
return ret;
}
avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
- r->callback(r, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, NULL, NULL, 0, r->userdata);
+ r->callback(r, r->interface, r->protocol, event, r->host_name, NULL, 0, r->userdata);
break;
}
}
r->callback = callback;
r->userdata = userdata;
r->path = NULL;
+ r->interface = interface;
+ r->protocol = protocol;
+ r->host_name = NULL;
AVAHI_LLIST_PREPEND(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r);
+ if (!(r->host_name = avahi_strdup(name))) {
+ avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
+ goto fail;
+ }
+
if (!(message = dbus_message_new_method_call(AVAHI_DBUS_NAME, AVAHI_DBUS_PATH_SERVER, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew"))) {
avahi_client_set_errno(client, AVAHI_ERR_NO_MEMORY);
goto fail;
AVAHI_LLIST_REMOVE(AvahiHostNameResolver, host_name_resolvers, client->host_name_resolvers, r);
avahi_free(r->path);
+ avahi_free(r->host_name);
avahi_free(r);
return ret;
goto fail;
}
- r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, (AvahiProtocol) aprotocol, &a, name, (AvahiLookupResultFlags) flags, r->userdata);
+ r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, &a, name, (AvahiLookupResultFlags) flags, r->userdata);
break;
}
}
avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
- r->callback(r, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, event, AVAHI_PROTO_UNSPEC, NULL, NULL, 0, r->userdata);
+ r->callback(r, r->interface, r->protocol, event, &r->address, NULL, 0, r->userdata);
break;
}
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-AvahiAddressResolver * avahi_address_resolver_new_a(
- AvahiClient *client,
- AvahiIfIndex interface,
- AvahiProtocol protocol,
- const AvahiAddress *a,
- AvahiLookupFlags flags,
- AvahiAddressResolverCallback callback,
- void *userdata) {
-
- char addr[AVAHI_ADDRESS_STR_MAX];
-
- assert (a);
-
- if (!avahi_address_snprint (addr, sizeof (addr), a)) {
- avahi_client_set_errno(client, AVAHI_ERR_INVALID_ADDRESS);
- return NULL;
- }
-
- return avahi_address_resolver_new(
- client, interface, protocol,
- addr, flags,
- callback, userdata);
-}
-
AvahiAddressResolver * avahi_address_resolver_new(
AvahiClient *client,
AvahiIfIndex interface,
AvahiProtocol protocol,
- const char *address,
+ const AvahiAddress *a,
AvahiLookupFlags flags,
AvahiAddressResolverCallback callback,
void *userdata) {
int32_t i_interface, i_protocol;
uint32_t u_flags;
char *path;
-
+ char addr[AVAHI_ADDRESS_STR_MAX], *address = addr;
+
assert(client);
+ assert(a);
dbus_error_init (&error);
+ if (!avahi_address_snprint (addr, sizeof(addr), a)) {
+ avahi_client_set_errno(client, AVAHI_ERR_INVALID_ADDRESS);
+ return NULL;
+ }
+
if (client->state == AVAHI_CLIENT_DISCONNECTED) {
avahi_client_set_errno(client, AVAHI_ERR_BAD_STATE);
goto fail;
r->callback = callback;
r->userdata = userdata;
r->path = NULL;
+ r->interface = interface;
+ r->protocol = protocol;
+ r->address = *a;
AVAHI_LLIST_PREPEND(AvahiAddressResolver, address_resolvers, client->address_resolvers, r);
AVAHI_PUBLISH_ALLOW_MULTIPLE = 8, /**< For raw records: Allow multiple local records of this type, even if they are intended to be unique */
AVAHI_PUBLISH_NO_REVERSE = 16, /**< For address records: don't create a reverse (PTR) entry */
AVAHI_PUBLISH_NO_COOKIE = 32, /**< For service records: do not implicitly add the local service cookie to TXT data */
- AVAHI_PUBLISH_IS_PROXY = 64, /**< For service records: this is a proxy for another host. This modifies behaviour of avahi_server_is_service_local() */
- AVAHI_PUBLISH_UPDATE = 128 /**< Update existing records instead of adding new ones */
+ AVAHI_PUBLISH_UPDATE = 64 /**< Update existing records instead of adding new ones */
} AvahiPublishFlags;
/** Some flags for lookup functions */
/** Some flags for lookup callback functions */
typedef enum {
AVAHI_LOOKUP_RESULT_NULL = 0,
- AVAHI_LOOKUP_RESULT_CACHED = 1, /**< This response originates from the cache */
- 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_CACHED = 1, /**< This response originates from the cache */
+ 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. */
} AvahiLookupResultFlags;
/** Type of callback event when browsing */
assert(rr);
assert(b);
+ /* Filter flags */
+ flags &= AVAHI_LOOKUP_RESULT_CACHED | AVAHI_LOOKUP_RESULT_MULTICAST | AVAHI_LOOKUP_RESULT_WIDE_AREA;
switch (event) {
case AVAHI_BROWSER_NEW: {
assert(rr);
assert(b);
+
+ /* 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);
b->callback(b, interface, protocol, event, n, flags, b->userdata);
}
-
AvahiSDomainBrowser *avahi_s_domain_browser_new(
AvahiServer *server,
AvahiIfIndex interface,
assert(rr);
assert(b);
+ /* Filter flags */
+ flags &= AVAHI_LOOKUP_RESULT_CACHED | AVAHI_LOOKUP_RESULT_MULTICAST | AVAHI_LOOKUP_RESULT_WIDE_AREA;
+
if (record) {
char type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX];
assert(rr);
assert(b);
+ /* Filter flags */
+ flags &= AVAHI_LOOKUP_RESULT_CACHED | AVAHI_LOOKUP_RESULT_MULTICAST | AVAHI_LOOKUP_RESULT_WIDE_AREA;
+
if (record) {
char service[AVAHI_LABEL_MAX], type[AVAHI_DOMAIN_NAME_MAX], domain[AVAHI_DOMAIN_NAME_MAX];
assert(record->key->type == AVAHI_DNS_TYPE_PTR);
+ if (event == AVAHI_BROWSER_NEW && avahi_server_is_service_local(b->server, interface, protocol, record->data.ptr.name))
+ flags |= AVAHI_LOOKUP_RESULT_LOCAL;
+
if (avahi_service_name_split(record->data.ptr.name, service, sizeof(service), type, sizeof(type), domain, sizeof(domain)) < 0) {
avahi_log_warn("Failed to split '%s'", record->key->name);
return;
/* It's a normal record, so let's call the user callback */
assert(avahi_key_equal(b->key, l->key));
+ if (avahi_server_is_record_local(b->server, interface, protocol, r))
+ flags |= AVAHI_LOOKUP_RESULT_LOCAL;
+
b->callback(b, interface, protocol, event, r, flags, b->userdata);
}
break;
/** Return the local service cookie */
uint32_t avahi_server_get_local_service_cookie(AvahiServer *s);
-/** Return 1 if there is a local service with the specified credentials registeresd. Return 0 if not, negative on failure */
-int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex, AvahiProtocol protocol, const char *name, const char *type, const char*domain);
-
/** Set the wide area DNS servers */
int avahi_server_set_wide_area_servers(AvahiServer *s, const AvahiAddress *a, unsigned n);
AVAHI_PUBLISH_NO_PROBE|
AVAHI_PUBLISH_UNIQUE|
AVAHI_PUBLISH_ALLOW_MULTIPLE|
- AVAHI_PUBLISH_IS_PROXY|
AVAHI_PUBLISH_UPDATE))
return avahi_server_set_errno(s, AVAHI_ERR_INVALID_FLAGS);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
- AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_IS_PROXY|AVAHI_PUBLISH_UPDATE), AVAHI_ERR_INVALID_FLAGS);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE|AVAHI_PUBLISH_UPDATE), AVAHI_ERR_INVALID_FLAGS);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
/* Add service enumeration PTR record */
- if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
+ if ((ret = avahi_server_add_ptr(s, g, interface, protocol, 0, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
goto fail;
/* Add SRV record */
r->data.srv.port = port;
r->data.srv.name = h;
h = NULL;
- ret = avahi_server_add(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY) | AVAHI_PUBLISH_UNIQUE, r);
+ ret = avahi_server_add(s, g, interface, protocol, AVAHI_PUBLISH_UNIQUE, r);
avahi_record_unref(r);
if (ret < 0)
if (!(flags & AVAHI_PUBLISH_NO_COOKIE))
strlst = add_magic_cookie(s, strlst);
- ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY) | AVAHI_PUBLISH_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
+ ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_PUBLISH_UNIQUE, AVAHI_DEFAULT_TTL, svc_name, strlst);
strlst = NULL;
if (ret < 0)
/* Add service type enumeration record */
- ret = avahi_server_add_ptr(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY), AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
+ ret = avahi_server_add_ptr(s, g, interface, protocol, 0, AVAHI_DEFAULT_TTL, enum_ptr, ptr_name);
fail:
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_IF_VALID(interface), AVAHI_ERR_INVALID_INTERFACE);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_PROTO_VALID(protocol), AVAHI_ERR_INVALID_PROTOCOL);
- AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_IS_PROXY|AVAHI_PUBLISH_NO_COOKIE), AVAHI_ERR_INVALID_FLAGS);
+ AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, AVAHI_FLAGS_VALID(flags, AVAHI_PUBLISH_NO_COOKIE), AVAHI_ERR_INVALID_FLAGS);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_name(name), AVAHI_ERR_INVALID_SERVICE_NAME);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, avahi_is_valid_service_type_strict(type), AVAHI_ERR_INVALID_SERVICE_TYPE);
AVAHI_CHECK_VALIDITY_SET_RET_GOTO_FAIL(s, !domain || avahi_is_valid_domain_name(domain), AVAHI_ERR_INVALID_DOMAIN_NAME);
if (!(flags & AVAHI_PUBLISH_NO_COOKIE))
strlst = add_magic_cookie(s, strlst);
- ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, (flags & AVAHI_PUBLISH_IS_PROXY) | AVAHI_PUBLISH_UNIQUE | AVAHI_PUBLISH_UPDATE, AVAHI_DEFAULT_TTL, svc_name, strlst);
+ ret = server_add_txt_strlst_nocopy(s, g, interface, protocol, AVAHI_PUBLISH_UNIQUE | AVAHI_PUBLISH_UPDATE, AVAHI_DEFAULT_TTL, svc_name, strlst);
strlst = NULL;
fail:
goto fail;
}
- if ((ret = avahi_server_add_ptr(s, g, interface, protocol, flags & AVAHI_PUBLISH_IS_PROXY, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
+ if ((ret = avahi_server_add_ptr(s, g, interface, protocol, 0, AVAHI_DEFAULT_TTL, ptr_name, svc_name)) < 0)
goto fail;
fail:
int avahi_server_set_errno(AvahiServer *s, int error);
+int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name);
+int avahi_server_is_record_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiRecord *record);
+
int avahi_server_add_ptr(
AvahiServer *s,
AvahiSEntryGroup *g,
const char *dest);
+
+
#define AVAHI_CHECK_VALIDITY_RETURN_NULL(server, expression, error) { \
if (!(expression)) { \
avahi_server_set_errno((server), (error)); \
const char *domain,
...) AVAHI_GCC_SENTINEL;
+/** Check if there is a service locally defined and return the entry group it is attached to. Returns NULL if the service isn't local*/
+int avahi_server_get_group_of_service(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain, AvahiSEntryGroup** ret_group);
+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
AVAHI_C_DECL_END
#endif
assert(rr);
assert(r);
-
switch (event) {
case AVAHI_BROWSER_NEW:
assert(record);
return s->local_service_cookie;
}
-int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char*domain) {
+static AvahiEntry *find_entry(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiKey *key) {
+ AvahiEntry *e;
+
+ assert(s);
+ assert(key);
+
+ for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next)
+
+ if ((e->interface == interface || e->interface <= 0 || interface <= 0) &&
+ (e->protocol == protocol || e->protocol == AVAHI_PROTO_UNSPEC || protocol == AVAHI_PROTO_UNSPEC) &&
+ (!e->group || e->group->state == AVAHI_ENTRY_GROUP_ESTABLISHED || e->group->state == AVAHI_ENTRY_GROUP_REGISTERING))
+
+ return e;
+
+ return NULL;
+}
+
+int avahi_server_get_group_of_service(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain, AvahiSEntryGroup** ret_group) {
AvahiKey *key = NULL;
- char n[256];
- int ret;
AvahiEntry *e;
+ int ret;
+ char n[AVAHI_DOMAIN_NAME_MAX];
assert(s);
assert(name);
assert(type);
- assert(domain);
+ assert(ret_group);
+
+ if (!AVAHI_IF_VALID(interface))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_INTERFACE);
+ if (!AVAHI_IF_VALID(protocol))
+ return avahi_server_set_errno(s, AVAHI_ERR_INVALID_PROTOCOL);
+
if (!avahi_is_valid_service_name(name))
return avahi_server_set_errno(s, AVAHI_ERR_INVALID_SERVICE_NAME);
if (!(key = avahi_key_new(n, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV)))
return avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
- ret = 0;
-
- for (e = avahi_hashmap_lookup(s->entries_by_key, key); e; e = e->by_key_next) {
+ e = find_entry(s, interface, protocol, key);
+ avahi_key_unref(key);
- if ((e->interface == interface || e->interface <= 0 || interface <= 0) &&
- (e->protocol == protocol || e->protocol == AVAHI_PROTO_UNSPEC || protocol == AVAHI_PROTO_UNSPEC) &&
- !(e->flags & AVAHI_PUBLISH_IS_PROXY)) {
- ret = 1;
- break;
- }
+ if (e) {
+ *ret_group = e->group;
+ return AVAHI_OK;
}
+
+ return avahi_server_set_errno(s, AVAHI_ERR_NOT_FOUND);
+}
+
+int avahi_server_is_service_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, const char *name) {
+ AvahiKey *key = NULL;
+ AvahiEntry *e;
+
+ assert(s);
+ assert(name);
+
+ if (!s->host_name_fqdn)
+ return 0;
+ if (!(key = avahi_key_new(name, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_SRV)))
+ return 0;
+
+ e = find_entry(s, interface, protocol, key);
avahi_key_unref(key);
+
+ if (!e)
+ return 0;
- return ret;
+ return avahi_domain_equal(s->host_name_fqdn, e->record->data.srv.name);
+}
+
+int avahi_server_is_record_local(AvahiServer *s, AvahiIfIndex interface, AvahiProtocol protocol, AvahiRecord *record) {
+ AvahiEntry *e;
+
+ assert(s);
+ assert(record);
+
+ for (e = avahi_hashmap_lookup(s->entries_by_key, record->key); e; e = e->by_key_next)
+
+ if ((e->interface == interface || e->interface <= 0 || interface <= 0) &&
+ (e->protocol == protocol || e->protocol == AVAHI_PROTO_UNSPEC || protocol == AVAHI_PROTO_UNSPEC) &&
+ (!e->group || e->group->state == AVAHI_ENTRY_GROUP_ESTABLISHED || e->group->state == AVAHI_ENTRY_GROUP_REGISTERING) &&
+ avahi_record_equal_no_ttl(record, e->record))
+ return 1;
+
+ return 0;
}
/** Set the wide area DNS servers */
<arg name="flags" type="u" direction="out"/>
</method>
- <method name="IsServiceLocal">
- <arg name="interface" type="i" direction="in"/>
- <arg name="protocol" type="i" direction="in"/>
- <arg name="name" type="s" direction="in"/>
- <arg name="type" type="s" direction="in"/>
- <arg name="domain" type="s" direction="in"/>
-
- <arg name="is_local" type="b" direction="out"/>
- </method>
-
<method name="EntryGroupNew">
<arg name="path" type="o" direction="out"/>
</method>
return respond_ok(c, m);
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "IsEmpty")) {
- DBusMessage *reply;
- int b;
-
+
if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
avahi_log_warn("Error parsing EntryGroup::IsEmpty message");
goto fail;
}
- b = !!avahi_s_entry_group_is_empty(i->entry_group);
-
- reply = dbus_message_new_method_return(m);
- dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &b, DBUS_TYPE_INVALID);
- dbus_connection_send(c, reply, NULL);
- dbus_message_unref(reply);
-
- return DBUS_HANDLER_RESULT_HANDLED;
+ return respond_boolean(c, m, !!avahi_s_entry_group_is_empty(i->entry_group));
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ENTRY_GROUP, "GetState")) {
AvahiEntryGroupState state;
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+static int is_our_own_service(Client *c, AvahiIfIndex interface, AvahiProtocol protocol, const char *name, const char *type, const char *domain) {
+ AvahiSEntryGroup *g;
+
+
+ if (avahi_server_get_group_of_service(avahi_server, interface, protocol, name, type, domain, &g) == AVAHI_OK) {
+ EntryGroupInfo *egi;
+
+ for (egi = c->entry_groups; egi; egi = egi->entry_groups_next)
+ if (egi->entry_group == g)
+ return 1;
+ }
+
+ return 0;
+}
+
static void service_browser_callback(AvahiSServiceBrowser *b, AvahiIfIndex interface, AvahiProtocol protocol, AvahiBrowserEvent event, const char *name, const char *type, const char *domain, AvahiLookupResultFlags flags, void* userdata) {
ServiceBrowserInfo *i = userdata;
DBusMessage *m;
m = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_BROWSER, map_browse_signal_name(event));
+ if (event == AVAHI_BROWSER_NEW) {
+ /* Patch in AVAHI_LOOKUP_RESULT_OUR_OWN */
+
+ if (is_our_own_service(i->client, interface, protocol, name, type, domain) > 0)
+ flags |= AVAHI_LOOKUP_RESULT_OUR_OWN;
+ }
+
if (event == AVAHI_BROWSER_NEW || event == AVAHI_BROWSER_REMOVE) {
assert(name);
assert(type);
if (!name)
name = "";
-
- assert(a);
- avahi_address_snprint(t, sizeof(t), a);
+ if (a)
+ avahi_address_snprint(t, sizeof(t), a);
+ else
+ t[0] = 0;
+
+ /* Patch in AVAHI_LOOKUP_RESULT_OUR_OWN */
+
+ if (is_our_own_service(i->client, interface, protocol, name, type, domain) > 0)
+ flags |= AVAHI_LOOKUP_RESULT_OUR_OWN;
+
i_interface = (int32_t) interface;
i_protocol = (int32_t) protocol;
- i_aprotocol = (int32_t) a->proto;
+ if (a)
+ i_aprotocol = (int32_t) a->proto;
+ else
+ i_aprotocol = AVAHI_PROTO_UNSPEC;
u_flags = (uint32_t) flags;
reply = dbus_message_new_method_return(i->message);
dbus_connection_send(server->bus, reply, NULL);
dbus_message_unref(reply);
-
} else {
assert(event == AVAHI_RESOLVER_FAILURE);
if (!name)
name = "";
+ if (is_our_own_service(i->client, interface, protocol, name, type, domain) > 0)
+ flags |= AVAHI_LOOKUP_RESULT_OUR_OWN;
+
i_interface = (int32_t) interface;
i_protocol = (int32_t) protocol;
if (a)
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, "IsServiceLocal")) {
- int32_t interface, protocol;
- char *name, *type, *domain;
- int b;
-
- if (!dbus_message_get_args(
- m, &error,
- DBUS_TYPE_INT32, &interface,
- DBUS_TYPE_INT32, &protocol,
- DBUS_TYPE_STRING, &name,
- DBUS_TYPE_STRING, &type,
- DBUS_TYPE_STRING, &domain,
- DBUS_TYPE_INVALID) || !name || !type || !domain) {
- avahi_log_warn("Error parsing Server::IsServiceLocal message");
- goto fail;
- }
-
- if ((b = avahi_server_is_service_local(avahi_server, interface, protocol, name, type, domain)) < 0)
- return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
-
- return respond_boolean(c, m, b);
-
} else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "GetNetworkInterfaceNameByIndex")) {
int32_t idx;
int fd;
avahi_server,
g->entry_group,
AVAHI_IF_UNSPEC, s->protocol,
- s->host_name ? AVAHI_PUBLISH_IS_PROXY : 0,
+ 0,
g->chosen_name, s->type,
s->domain_name, s->host_name, s->port,
s->txt_records) < 0) {
"\tTXT=%s\n"
"\tcookie is %u\n"
"\tis_local: %i\n"
+ "\tour_own: %i\n"
"\twide_area: %i\n"
"\tmulticast: %i\n"
"\tcached: %i\n",
host_name, port, a,
t,
avahi_string_list_get_service_cookie(txt),
- avahi_client_is_service_local(avahi_service_resolver_get_client(r), interface, protocol, name, type, domain),
+ !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
+ !!(flags & AVAHI_LOOKUP_RESULT_OUR_OWN),
!!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
!!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
!!(flags & AVAHI_LOOKUP_RESULT_CACHED));
fprintf(stderr, "Failed to create service browser: %s\n", avahi_strerror(avahi_client_errno(client)));
goto fail;
}
-
+
/* Run the main loop */
- for (;;)
- if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
- break;
+ avahi_simple_poll_loop(simple_poll);
ret = 0;
assert(c);
/* If this is the first time we're called, let's create a new entry group */
- if (!group) {
+ if (!group)
if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) {
fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_client_errno(c)));
goto fail;
}
- }
fprintf(stderr, "Adding service '%s'\n", name);
-
+
/* Create some random TXT data */
snprintf(r, sizeof(r), "random=%i", rand());
/* Called whenever the client or server state changes */
- if (state == AVAHI_CLIENT_S_RUNNING)
- /* The serve has startup successfully and registered its host
+ if (state == AVAHI_CLIENT_S_RUNNING) {
+
+ /* The server has startup successfully and registered its host
* name on the network, so it's time to create our services */
- create_services(c);
+ if (group)
+ create_services(c);
- else if (state == AVAHI_CLIENT_S_COLLISION) {
+ } else if (state == AVAHI_CLIENT_S_COLLISION) {
+
/* Let's drop our registered services. When the server is back
* in AVAHI_SERVER_RUNNING state we will register them
* again with the new host name. */
fprintf(stderr, "Failed to create client: %s\n", avahi_strerror(error));
goto fail;
}
-
+
/* Run the main loop */
- for (;;)
- if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
- break;
+ avahi_simple_poll_loop(simple_poll);
ret = 0;
fail:
/* Cleanup things */
- if (group)
- avahi_entry_group_free(group);
if (client)
avahi_client_free(client);
host_name, port, a,
t,
avahi_string_list_get_service_cookie(txt),
- avahi_server_is_service_local(server, interface, protocol, name, type, domain),
+ !!(flags & AVAHI_LOOKUP_RESULT_LOCAL),
!!(flags & AVAHI_LOOKUP_RESULT_WIDE_AREA),
!!(flags & AVAHI_LOOKUP_RESULT_MULTICAST),
!!(flags & AVAHI_LOOKUP_RESULT_CACHED));
}
/* Run the main loop */
- for (;;)
- if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
- break;
+ avahi_simple_poll_loop(simple_poll);
ret = 0;
assert(s);
/* If this is the first time we're called, let's create a new entry group */
- if (!group) {
+ if (!group)
if (!(group = avahi_s_entry_group_new(s, entry_group_callback, NULL))) {
fprintf(stderr, "avahi_entry_group_new() failed: %s\n", avahi_strerror(avahi_server_errno(s)));
goto fail;
}
- }
fprintf(stderr, "Adding service '%s'\n", name);
/* Called whenever the server state changes */
- if (state == AVAHI_SERVER_RUNNING)
+ if (state == AVAHI_SERVER_RUNNING) {
/* The serve has startup successfully and registered its host
* name on the network, so it's time to create our services */
- create_services(s);
+
+ if (group)
+ create_services(s);
- else if (state == AVAHI_SERVER_COLLISION) {
+ } else if (state == AVAHI_SERVER_COLLISION) {
char *n;
int r;
fprintf(stderr, "Failed to create server: %s\n", avahi_strerror(error));
goto fail;
}
-
+
/* Run the main loop */
- for (;;)
- if (avahi_simple_poll_iterate(simple_poll, -1) != 0)
- break;
+ avahi_simple_poll_loop(simple_poll);
ret = 0;
fail:
/* Cleanup things */
- if (group)
- avahi_s_entry_group_free(group);
if (server)
avahi_server_free(server);