#include <avahi-common/malloc.h>
#include <avahi-common/dbus.h>
#include <avahi-common/dbus-watch-glue.h>
+#include <avahi-common/alternative.h>
+#include <avahi-common/error.h>
#include <avahi-core/log.h>
#include <avahi-core/core.h>
typedef struct Server Server;
typedef struct Client Client;
typedef struct EntryGroupInfo EntryGroupInfo;
-typedef struct HostNameResolverInfo HostNameResolverInfo;
-typedef struct AddressResolverInfo AddressResolverInfo;
+typedef struct SyncHostNameResolverInfo SyncHostNameResolverInfo;
+typedef struct AsyncHostNameResolverInfo AsyncHostNameResolverInfo;
+typedef struct SyncAddressResolverInfo SyncAddressResolverInfo;
+typedef struct AsyncAddressResolverInfo AsyncAddressResolverInfo;
typedef struct DomainBrowserInfo DomainBrowserInfo;
typedef struct ServiceTypeBrowserInfo ServiceTypeBrowserInfo;
typedef struct ServiceBrowserInfo ServiceBrowserInfo;
-typedef struct ServiceResolverInfo ServiceResolverInfo;
+typedef struct SyncServiceResolverInfo SyncServiceResolverInfo;
+typedef struct AsyncServiceResolverInfo AsyncServiceResolverInfo;
#define MAX_CLIENTS 20
#define MAX_OBJECTS_PER_CLIENT 50
AVAHI_LLIST_FIELDS(EntryGroupInfo, entry_groups);
};
-struct HostNameResolverInfo {
+struct SyncHostNameResolverInfo {
Client *client;
AvahiSHostNameResolver *host_name_resolver;
DBusMessage *message;
- AVAHI_LLIST_FIELDS(HostNameResolverInfo, host_name_resolvers);
+ AVAHI_LLIST_FIELDS(SyncHostNameResolverInfo, sync_host_name_resolvers);
};
-struct AddressResolverInfo {
+struct AsyncHostNameResolverInfo {
+ unsigned id;
+ Client *client;
+ AvahiSHostNameResolver *host_name_resolver;
+ char *path;
+
+ AVAHI_LLIST_FIELDS(AsyncHostNameResolverInfo, async_host_name_resolvers);
+};
+
+struct SyncAddressResolverInfo {
Client *client;
AvahiSAddressResolver *address_resolver;
DBusMessage *message;
- AVAHI_LLIST_FIELDS(AddressResolverInfo, address_resolvers);
+ AVAHI_LLIST_FIELDS(SyncAddressResolverInfo, sync_address_resolvers);
+};
+
+struct AsyncAddressResolverInfo {
+ unsigned id;
+ Client *client;
+ AvahiSAddressResolver *address_resolver;
+ char *path;
+
+ AVAHI_LLIST_FIELDS(AsyncAddressResolverInfo, async_address_resolvers);
};
struct DomainBrowserInfo {
AVAHI_LLIST_FIELDS(ServiceBrowserInfo, service_browsers);
};
-struct ServiceResolverInfo {
+struct SyncServiceResolverInfo {
Client *client;
AvahiSServiceResolver *service_resolver;
DBusMessage *message;
- AVAHI_LLIST_FIELDS(ServiceResolverInfo, service_resolvers);
+ AVAHI_LLIST_FIELDS(SyncServiceResolverInfo, sync_service_resolvers);
+};
+
+struct AsyncServiceResolverInfo {
+ unsigned id;
+ Client *client;
+ AvahiSServiceResolver *service_resolver;
+ char *path;
+
+ AVAHI_LLIST_FIELDS(AsyncServiceResolverInfo, async_service_resolvers);
};
struct Client {
AVAHI_LLIST_FIELDS(Client, clients);
AVAHI_LLIST_HEAD(EntryGroupInfo, entry_groups);
- AVAHI_LLIST_HEAD(HostNameResolverInfo, host_name_resolvers);
- AVAHI_LLIST_HEAD(AddressResolverInfo, address_resolvers);
+ AVAHI_LLIST_HEAD(SyncHostNameResolverInfo, sync_host_name_resolvers);
+ AVAHI_LLIST_HEAD(AsyncHostNameResolverInfo, async_host_name_resolvers);
+ AVAHI_LLIST_HEAD(SyncAddressResolverInfo, sync_address_resolvers);
+ AVAHI_LLIST_HEAD(AsyncAddressResolverInfo, async_address_resolvers);
AVAHI_LLIST_HEAD(DomainBrowserInfo, domain_browsers);
AVAHI_LLIST_HEAD(ServiceTypeBrowserInfo, service_type_browsers);
AVAHI_LLIST_HEAD(ServiceBrowserInfo, service_browsers);
- AVAHI_LLIST_HEAD(ServiceResolverInfo, service_resolvers);
+ AVAHI_LLIST_HEAD(SyncServiceResolverInfo, sync_service_resolvers);
+ AVAHI_LLIST_HEAD(AsyncServiceResolverInfo, async_service_resolvers);
};
struct Server {
assert(i->client->n_objects >= 0);
avahi_free(i);
- }
+}
-static void host_name_resolver_free(HostNameResolverInfo *i) {
+static void sync_host_name_resolver_free(SyncHostNameResolverInfo *i) {
assert(i);
if (i->host_name_resolver)
avahi_s_host_name_resolver_free(i->host_name_resolver);
dbus_message_unref(i->message);
- AVAHI_LLIST_REMOVE(HostNameResolverInfo, host_name_resolvers, i->client->host_name_resolvers, i);
+ AVAHI_LLIST_REMOVE(SyncHostNameResolverInfo, sync_host_name_resolvers, i->client->sync_host_name_resolvers, i);
+
+ i->client->n_objects--;
+ assert(i->client->n_objects >= 0);
+
+ avahi_free(i);
+}
+
+static void async_host_name_resolver_free(AsyncHostNameResolverInfo *i) {
+ assert(i);
+
+ if (i->host_name_resolver)
+ avahi_s_host_name_resolver_free(i->host_name_resolver);
+ dbus_connection_unregister_object_path(server->bus, i->path);
+ AVAHI_LLIST_REMOVE(AsyncHostNameResolverInfo, async_host_name_resolvers, i->client->async_host_name_resolvers, i);
i->client->n_objects--;
assert(i->client->n_objects >= 0);
avahi_free(i);
}
-static void address_resolver_free(AddressResolverInfo *i) {
+static void sync_address_resolver_free(SyncAddressResolverInfo *i) {
assert(i);
if (i->address_resolver)
avahi_s_address_resolver_free(i->address_resolver);
dbus_message_unref(i->message);
- AVAHI_LLIST_REMOVE(AddressResolverInfo, address_resolvers, i->client->address_resolvers, i);
+ AVAHI_LLIST_REMOVE(SyncAddressResolverInfo, sync_address_resolvers, i->client->sync_address_resolvers, i);
+
+ i->client->n_objects--;
+ assert(i->client->n_objects >= 0);
+
+ avahi_free(i);
+}
+
+static void async_address_resolver_free(AsyncAddressResolverInfo *i) {
+ assert(i);
+
+ if (i->address_resolver)
+ avahi_s_address_resolver_free(i->address_resolver);
+ dbus_connection_unregister_object_path(server->bus, i->path);
+ AVAHI_LLIST_REMOVE(AsyncAddressResolverInfo, async_address_resolvers, i->client->async_address_resolvers, i);
i->client->n_objects--;
assert(i->client->n_objects >= 0);
avahi_free(i);
}
-static void service_resolver_free(ServiceResolverInfo *i) {
+static void sync_service_resolver_free(SyncServiceResolverInfo *i) {
assert(i);
if (i->service_resolver)
avahi_s_service_resolver_free(i->service_resolver);
dbus_message_unref(i->message);
- AVAHI_LLIST_REMOVE(ServiceResolverInfo, service_resolvers, i->client->service_resolvers, i);
+ AVAHI_LLIST_REMOVE(SyncServiceResolverInfo, sync_service_resolvers, i->client->sync_service_resolvers, i);
+
+ i->client->n_objects--;
+ assert(i->client->n_objects >= 0);
+
+ avahi_free(i);
+}
+
+static void async_service_resolver_free(AsyncServiceResolverInfo *i) {
+ assert(i);
+
+ if (i->service_resolver)
+ avahi_s_service_resolver_free(i->service_resolver);
+
+ dbus_connection_unregister_object_path(server->bus, i->path);
+ AVAHI_LLIST_REMOVE(AsyncServiceResolverInfo, async_service_resolvers, i->client->async_service_resolvers, i);
i->client->n_objects--;
assert(i->client->n_objects >= 0);
while (c->entry_groups)
entry_group_free(c->entry_groups);
- while (c->host_name_resolvers)
- host_name_resolver_free(c->host_name_resolvers);
+ while (c->sync_host_name_resolvers)
+ sync_host_name_resolver_free(c->sync_host_name_resolvers);
- while (c->address_resolvers)
- address_resolver_free(c->address_resolvers);
+ while (c->async_host_name_resolvers)
+ async_host_name_resolver_free(c->async_host_name_resolvers);
+
+ while (c->sync_address_resolvers)
+ sync_address_resolver_free(c->sync_address_resolvers);
+
+ while (c->async_address_resolvers)
+ async_address_resolver_free(c->async_address_resolvers);
while (c->domain_browsers)
domain_browser_free(c->domain_browsers);
while (c->service_browsers)
service_browser_free(c->service_browsers);
- while (c->service_resolvers)
- service_resolver_free(c->service_resolvers);
+ while (c->sync_service_resolvers)
+ sync_service_resolver_free(c->sync_service_resolvers);
+
+ while (c->async_service_resolvers)
+ async_service_resolver_free(c->async_service_resolvers);
assert(c->n_objects == 0);
client->name = avahi_strdup(name);
client->current_id = 0;
client->n_objects = 0;
+
AVAHI_LLIST_HEAD_INIT(EntryGroupInfo, client->entry_groups);
- AVAHI_LLIST_HEAD_INIT(HostNameResolverInfo, client->host_name_resolvers);
- AVAHI_LLIST_HEAD_INIT(AddressResolverInfo, client->address_resolvers);
+ AVAHI_LLIST_HEAD_INIT(SyncHostNameResolverInfo, client->sync_host_name_resolvers);
+ AVAHI_LLIST_HEAD_INIT(AsyncHostNameResolverInfo, client->async_host_name_resolvers);
+ AVAHI_LLIST_HEAD_INIT(SyncAddressResolverInfo, client->sync_address_resolvers);
+ AVAHI_LLIST_HEAD_INIT(AsyncAddressResolverInfo, client->async_address_resolvers);
AVAHI_LLIST_HEAD_INIT(DomainBrowserInfo, client->domain_browsers);
AVAHI_LLIST_HEAD_INIT(ServiceTypeBrowserInfo, client->service_type_browsers);
AVAHI_LLIST_HEAD_INIT(ServiceBrowserInfo, client->service_browsers);
- AVAHI_LLIST_HEAD_INIT(ServiceResolverInfo, client->service_resolvers);
+ AVAHI_LLIST_HEAD_INIT(SyncServiceResolverInfo, client->sync_service_resolvers);
+ AVAHI_LLIST_HEAD_INIT(AsyncServiceResolverInfo, client->async_service_resolvers);
AVAHI_LLIST_PREPEND(Client, clients, server->clients, client);
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
-static void host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) {
- HostNameResolverInfo *i = userdata;
+static void sync_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) {
+ SyncHostNameResolverInfo *i = userdata;
assert(r);
assert(host_name);
respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
}
- host_name_resolver_free(i);
+ sync_host_name_resolver_free(i);
}
-static void address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) {
- AddressResolverInfo *i = userdata;
+static void sync_address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) {
+ SyncAddressResolverInfo *i = userdata;
assert(r);
assert(address);
respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
}
- address_resolver_free(i);
+ sync_address_resolver_free(i);
}
static DBusHandlerResult msg_domain_browser_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
dbus_message_unref(m);
}
-static void service_resolver_callback(
+static void append_string_list(DBusMessage *reply, AvahiStringList *txt) {
+ AvahiStringList *p;
+ DBusMessageIter iter, sub;
+
+ assert(reply);
+
+ dbus_message_iter_init_append(reply, &iter);
+ dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub);
+
+ for (p = txt; p; p = p->next) {
+ DBusMessageIter sub2;
+ const uint8_t *data = p->text;
+
+ dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2);
+ dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size);
+ dbus_message_iter_close_container(&sub, &sub2);
+
+ }
+ dbus_message_iter_close_container(&iter, &sub);
+}
+
+static void sync_service_resolver_callback(
AvahiSServiceResolver *r,
AvahiIfIndex interface,
AvahiProtocol protocol,
AvahiStringList *txt,
void* userdata) {
- ServiceResolverInfo *i = userdata;
+ SyncServiceResolverInfo *i = userdata;
assert(r);
assert(i);
if (event == AVAHI_RESOLVER_FOUND) {
char t[256], *pt = t;
int32_t i_interface, i_protocol, i_aprotocol;
- unsigned n, j;
- AvahiStringList *p;
DBusMessage *reply;
- DBusMessageIter iter, sub;
-
+
assert(host_name);
assert(a);
DBUS_TYPE_UINT16, &port,
DBUS_TYPE_INVALID);
- dbus_message_iter_init_append(reply, &iter);
- dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "ay", &sub);
-
- for (p = txt, j = n-1; p; p = p->next, j--) {
- DBusMessageIter sub2;
- const uint8_t *data = p->text;
-
- dbus_message_iter_open_container(&sub, DBUS_TYPE_ARRAY, "y", &sub2);
- dbus_message_iter_append_fixed_array(&sub2, DBUS_TYPE_BYTE, &data, p->size);
- dbus_message_iter_close_container(&sub, &sub2);
-
- }
- dbus_message_iter_close_container(&iter, &sub);
+ append_string_list(reply, txt);
dbus_connection_send(server->bus, reply, NULL);
dbus_message_unref(reply);
respond_error(server->bus, i->message, AVAHI_ERR_TIMEOUT, NULL);
}
- service_resolver_free(i);
+ sync_service_resolver_free(i);
+}
+
+static void async_address_resolver_callback(AvahiSAddressResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const AvahiAddress *address, const char *host_name, void* userdata) {
+ AsyncAddressResolverInfo *i = userdata;
+ DBusMessage *reply;
+
+ assert(r);
+ assert(address);
+ assert(i);
+
+ if (event == AVAHI_RESOLVER_FOUND) {
+ char t[256], *pt = t;
+ int32_t i_interface, i_protocol, i_aprotocol;
+
+ assert(host_name);
+ avahi_address_snprint(t, sizeof(t), address);
+
+ i_interface = (int32_t) interface;
+ i_protocol = (int32_t) protocol;
+ i_aprotocol = (int32_t) address->family;
+
+ reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Found");
+ dbus_message_append_args(
+ reply,
+ DBUS_TYPE_INT32, &i_interface,
+ DBUS_TYPE_INT32, &i_protocol,
+ DBUS_TYPE_INT32, &i_aprotocol,
+ DBUS_TYPE_STRING, &pt,
+ DBUS_TYPE_STRING, &host_name,
+ DBUS_TYPE_INVALID);
+
+ } else {
+ assert(event == AVAHI_RESOLVER_TIMEOUT);
+
+ reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Timeout");
+ }
+
+ dbus_connection_send(server->bus, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static DBusHandlerResult msg_async_address_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
+ DBusError error;
+ AsyncAddressResolverInfo *i = userdata;
+
+ assert(c);
+ assert(m);
+ assert(i);
+
+ dbus_error_init(&error);
+
+ avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
+ dbus_message_get_interface(m),
+ dbus_message_get_path(m),
+ dbus_message_get_member(m));
+
+ /* Introspection */
+ if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
+ return handle_introspect(c, m, "AddressResolver.Introspect");
+
+ /* Access control */
+ if (strcmp(dbus_message_get_sender(m), i->client->name))
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
+
+ if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_ADDRESS_RESOLVER, "Free")) {
+
+ if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
+ avahi_log_warn("Error parsing AddressResolver::Free message");
+ goto fail;
+ }
+
+ async_address_resolver_free(i);
+ return respond_ok(c, m);
+
+ }
+
+ avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
+
+fail:
+ if (dbus_error_is_set(&error))
+ dbus_error_free(&error);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void async_host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex interface, AvahiProtocol protocol, AvahiResolverEvent event, const char *host_name, const AvahiAddress *a, void* userdata) {
+ AsyncHostNameResolverInfo *i = userdata;
+ DBusMessage *reply;
+
+ assert(r);
+ assert(host_name);
+ assert(i);
+
+ if (event == AVAHI_RESOLVER_FOUND) {
+ char t[256], *pt = t;
+ int32_t i_interface, i_protocol, i_aprotocol;
+
+ assert(a);
+ avahi_address_snprint(t, sizeof(t), a);
+
+ i_interface = (int32_t) interface;
+ i_protocol = (int32_t) protocol;
+ i_aprotocol = (int32_t) a->family;
+
+ reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Found");
+ dbus_message_append_args(
+ reply,
+ DBUS_TYPE_INT32, &i_interface,
+ DBUS_TYPE_INT32, &i_protocol,
+ DBUS_TYPE_STRING, &host_name,
+ DBUS_TYPE_INT32, &i_aprotocol,
+ DBUS_TYPE_STRING, &pt,
+ DBUS_TYPE_INVALID);
+ } else {
+ assert(event == AVAHI_RESOLVER_TIMEOUT);
+
+ reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Timeout");
+ }
+
+ dbus_connection_send(server->bus, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static DBusHandlerResult msg_async_host_name_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
+ DBusError error;
+ AsyncHostNameResolverInfo *i = userdata;
+
+ assert(c);
+ assert(m);
+ assert(i);
+
+ dbus_error_init(&error);
+
+ avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
+ dbus_message_get_interface(m),
+ dbus_message_get_path(m),
+ dbus_message_get_member(m));
+
+ /* Introspection */
+ if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
+ return handle_introspect(c, m, "HostNameResolver.Introspect");
+
+ /* Access control */
+ if (strcmp(dbus_message_get_sender(m), i->client->name))
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
+
+ if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_HOST_NAME_RESOLVER, "Free")) {
+
+ if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
+ avahi_log_warn("Error parsing HostNameResolver::Free message");
+ goto fail;
+ }
+
+ async_host_name_resolver_free(i);
+ return respond_ok(c, m);
+ }
+
+ avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
+
+fail:
+ if (dbus_error_is_set(&error))
+ dbus_error_free(&error);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
+static void async_service_resolver_callback(
+ AvahiSServiceResolver *r,
+ AvahiIfIndex interface,
+ AvahiProtocol protocol,
+ AvahiResolverEvent event,
+ const char *name,
+ const char *type,
+ const char *domain,
+ const char *host_name,
+ const AvahiAddress *a,
+ uint16_t port,
+ AvahiStringList *txt,
+ void* userdata) {
+
+ AsyncServiceResolverInfo *i = userdata;
+ DBusMessage *reply;
+
+ assert(r);
+ assert(host_name);
+ assert(i);
+
+ if (event == AVAHI_RESOLVER_FOUND) {
+ char t[256], *pt = t;
+ int32_t i_interface, i_protocol, i_aprotocol;
+
+ assert(host_name);
+
+ assert(a);
+ avahi_address_snprint(t, sizeof(t), a);
+
+ i_interface = (int32_t) interface;
+ i_protocol = (int32_t) protocol;
+ i_aprotocol = (int32_t) a->family;
+
+ reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Found");
+ dbus_message_append_args(
+ reply,
+ DBUS_TYPE_INT32, &i_interface,
+ DBUS_TYPE_INT32, &i_protocol,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_STRING, &type,
+ DBUS_TYPE_STRING, &domain,
+ DBUS_TYPE_STRING, &host_name,
+ DBUS_TYPE_INT32, &i_aprotocol,
+ DBUS_TYPE_STRING, &pt,
+ DBUS_TYPE_UINT16, &port,
+ DBUS_TYPE_INVALID);
+
+ append_string_list(reply, txt);
+
+ } else {
+ assert(event == AVAHI_RESOLVER_TIMEOUT);
+
+ reply = dbus_message_new_signal(i->path, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Timeout");
+ }
+
+ dbus_connection_send(server->bus, reply, NULL);
+ dbus_message_unref(reply);
+}
+
+static DBusHandlerResult msg_async_service_resolver_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
+ DBusError error;
+ AsyncServiceResolverInfo *i = userdata;
+
+ assert(c);
+ assert(m);
+ assert(i);
+
+ dbus_error_init(&error);
+
+ avahi_log_debug("dbus: interface=%s, path=%s, member=%s",
+ dbus_message_get_interface(m),
+ dbus_message_get_path(m),
+ dbus_message_get_member(m));
+
+ /* Introspection */
+ if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect"))
+ return handle_introspect(c, m, "ServiceResolver.Introspect");
+
+ /* Access control */
+ if (strcmp(dbus_message_get_sender(m), i->client->name))
+ return respond_error(c, m, AVAHI_ERR_ACCESS_DENIED, NULL);
+
+ if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVICE_RESOLVER, "Free")) {
+
+ if (!dbus_message_get_args(m, &error, DBUS_TYPE_INVALID)) {
+ avahi_log_warn("Error parsing ServiceResolver::Free message");
+ goto fail;
+ }
+
+ async_service_resolver_free(i);
+ return respond_ok(c, m);
+ }
+
+ avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));
+
+fail:
+ if (dbus_error_is_set(&error))
+ dbus_error_free(&error);
+
+ return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) {
#else
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- char txt[256];
- snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
- return respond_error(c, m, AVAHI_ERR_OS, txt);
- }
+ if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ char txt[256];
+ snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
+ return respond_error(c, m, AVAHI_ERR_OS, txt);
+ }
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = idx;
return respond_int32(c, m, 1);
#else
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
- char txt[256];
- snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
- return respond_error(c, m, AVAHI_ERR_OS, txt);
- }
+ if ((fd = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ char txt[256];
+ snprintf(txt, sizeof(txt), "OS Error: %s", strerror(errno));
+ return respond_error(c, m, AVAHI_ERR_OS, txt);
+ }
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", n);
Client *client;
int32_t interface, protocol, aprotocol;
char *name;
- HostNameResolverInfo *i;
+ SyncHostNameResolverInfo *i;
if (!dbus_message_get_args(
m, &error,
return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
- i = avahi_new(HostNameResolverInfo, 1);
+ i = avahi_new(SyncHostNameResolverInfo, 1);
i->client = client;
i->message = dbus_message_ref(m);
- AVAHI_LLIST_PREPEND(HostNameResolverInfo, host_name_resolvers, client->host_name_resolvers, i);
+ AVAHI_LLIST_PREPEND(SyncHostNameResolverInfo, sync_host_name_resolvers, client->sync_host_name_resolvers, i);
client->n_objects++;
- if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, host_name_resolver_callback, i))) {
- host_name_resolver_free(i);
+ if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, (AvahiProtocol) aprotocol, sync_host_name_resolver_callback, i))) {
+ sync_host_name_resolver_free(i);
return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
Client *client;
int32_t interface, protocol;
char *address;
- AddressResolverInfo *i;
+ SyncAddressResolverInfo *i;
AvahiAddress a;
if (!dbus_message_get_args(
return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
}
- i = avahi_new(AddressResolverInfo, 1);
+ i = avahi_new(SyncAddressResolverInfo, 1);
i->client = client;
i->message = dbus_message_ref(m);
- AVAHI_LLIST_PREPEND(AddressResolverInfo, address_resolvers, client->address_resolvers, i);
+ AVAHI_LLIST_PREPEND(SyncAddressResolverInfo, sync_address_resolvers, client->sync_address_resolvers, i);
client->n_objects++;
- if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, address_resolver_callback, i))) {
- address_resolver_free(i);
+ if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, sync_address_resolver_callback, i))) {
+ sync_address_resolver_free(i);
return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
int32_t interface, protocol, type;
char *domain;
-
if (!dbus_message_get_args(
m, &error,
DBUS_TYPE_INT32, &interface,
dbus_connection_register_object_path(c, i->path, &vtable, i);
return respond_path(c, m, i->path);
- } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew")) {
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceBrowserNew")) {
Client *client;
ServiceBrowserInfo *i;
static const DBusObjectPathVTable vtable = {
Client *client;
int32_t interface, protocol, aprotocol;
char *name, *type, *domain;
- ServiceResolverInfo *i;
+ SyncServiceResolverInfo *i;
if (!dbus_message_get_args(
m, &error,
if (!*domain)
domain = NULL;
- i = avahi_new(ServiceResolverInfo, 1);
+ i = avahi_new(SyncServiceResolverInfo, 1);
i->client = client;
i->message = dbus_message_ref(m);
- AVAHI_LLIST_PREPEND(ServiceResolverInfo, service_resolvers, client->service_resolvers, i);
+ AVAHI_LLIST_PREPEND(SyncServiceResolverInfo, sync_service_resolvers, client->sync_service_resolvers, i);
client->n_objects++;
- if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, service_resolver_callback, i))) {
- service_resolver_free(i);
+ if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, sync_service_resolver_callback, i))) {
+ sync_service_resolver_free(i);
return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
}
return DBUS_HANDLER_RESULT_HANDLED;
- }
+
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "ServiceResolverNew")) {
+ Client *client;
+ int32_t interface, protocol, aprotocol;
+ char *name, *type, *domain;
+ AsyncServiceResolverInfo *i;
+ static const DBusObjectPathVTable vtable = {
+ NULL,
+ msg_async_service_resolver_impl,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+
+ 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_INT32, &aprotocol,
+ DBUS_TYPE_INVALID) || !name || !type) {
+ avahi_log_warn("Error parsing Server::ServiceResolverNew message");
+ goto fail;
+ }
+
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn(__FILE__": Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
+ }
+
+ i = avahi_new(AsyncServiceResolverInfo, 1);
+ i->id = ++client->current_id;
+ i->client = client;
+ i->path = avahi_strdup_printf("/Client%u/ServiceResolver%u", client->id, i->id);
+ AVAHI_LLIST_PREPEND(AsyncServiceResolverInfo, async_service_resolvers, client->async_service_resolvers, i);
+ client->n_objects++;
+
+ if (!(i->service_resolver = avahi_s_service_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, type, domain, (AvahiProtocol) aprotocol, async_service_resolver_callback, i))) {
+ async_service_resolver_free(i);
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
+ }
+
+ dbus_connection_register_object_path(c, i->path, &vtable, i);
+ return respond_path(c, m, i->path);
+
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew")) {
+ Client *client;
+ int32_t interface, protocol, aprotocol;
+ char *name;
+ AsyncHostNameResolverInfo *i;
+ static const DBusObjectPathVTable vtable = {
+ NULL,
+ msg_async_host_name_resolver_impl,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+
+ if (!dbus_message_get_args(
+ m, &error,
+ DBUS_TYPE_INT32, &interface,
+ DBUS_TYPE_INT32, &protocol,
+ DBUS_TYPE_STRING, &name,
+ DBUS_TYPE_INT32, &aprotocol,
+ DBUS_TYPE_INVALID) || !name) {
+ avahi_log_warn("Error parsing Server::HostNameResolverNew message");
+ goto fail;
+ }
+
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn(__FILE__": Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
+ }
+
+ i = avahi_new(AsyncHostNameResolverInfo, 1);
+ i->id = ++client->current_id;
+ i->client = client;
+ i->path = avahi_strdup_printf("/Client%u/HostNameResolver%u", client->id, i->id);
+ AVAHI_LLIST_PREPEND(AsyncHostNameResolverInfo, async_host_name_resolvers, client->async_host_name_resolvers, i);
+ client->n_objects++;
+
+ if (!(i->host_name_resolver = avahi_s_host_name_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, name, aprotocol, async_host_name_resolver_callback, i))) {
+ async_host_name_resolver_free(i);
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
+ }
+
+ dbus_connection_register_object_path(c, i->path, &vtable, i);
+ return respond_path(c, m, i->path);
+
+ } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "AddressResolverNew")) {
+ Client *client;
+ int32_t interface, protocol;
+ char *address;
+ AsyncAddressResolverInfo *i;
+ AvahiAddress a;
+ static const DBusObjectPathVTable vtable = {
+ NULL,
+ msg_async_address_resolver_impl,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ };
+
+ if (!dbus_message_get_args(
+ m, &error,
+ DBUS_TYPE_INT32, &interface,
+ DBUS_TYPE_INT32, &protocol,
+ DBUS_TYPE_STRING, &address,
+ DBUS_TYPE_INVALID) || !address) {
+ avahi_log_warn("Error parsing Server::AddressResolverNew message");
+ goto fail;
+ }
+
+ if (!avahi_address_parse(address, AVAHI_PROTO_UNSPEC, &a))
+ return respond_error(c, m, AVAHI_ERR_INVALID_ADDRESS, NULL);
+
+ if (!(client = client_get(dbus_message_get_sender(m), TRUE))) {
+ avahi_log_warn(__FILE__": Too many clients, client request failed.");
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_CLIENTS, NULL);
+ }
+
+ if (client->n_objects >= MAX_OBJECTS_PER_CLIENT) {
+ avahi_log_warn(__FILE__": Too many objects for client '%s', client request failed.", client->name);
+ return respond_error(c, m, AVAHI_ERR_TOO_MANY_OBJECTS, NULL);
+ }
+
+ i = avahi_new(AsyncAddressResolverInfo, 1);
+ i->id = ++client->current_id;
+ i->client = client;
+ i->path = avahi_strdup_printf("/Client%u/AddressResolver%u", client->id, i->id);
+ AVAHI_LLIST_PREPEND(AsyncAddressResolverInfo, async_address_resolvers, client->async_address_resolvers, i);
+ client->n_objects++;
+
+ if (!(i->address_resolver = avahi_s_address_resolver_new(avahi_server, (AvahiIfIndex) interface, (AvahiProtocol) protocol, &a, async_address_resolver_callback, i))) {
+ async_address_resolver_free(i);
+ return respond_error(c, m, avahi_server_errno(avahi_server), NULL);
+ }
+
+ dbus_connection_register_object_path(c, i->path, &vtable, i);
+ return respond_path(c, m, i->path);
+ }
avahi_log_warn("Missed message %s::%s()", dbus_message_get_interface(m), dbus_message_get_member(m));