diff options
Diffstat (limited to 'avahi-daemon/dbus-protocol.c')
| -rw-r--r-- | avahi-daemon/dbus-protocol.c | 159 | 
1 files changed, 150 insertions, 9 deletions
| diff --git a/avahi-daemon/dbus-protocol.c b/avahi-daemon/dbus-protocol.c index 36ad690..b998d13 100644 --- a/avahi-daemon/dbus-protocol.c +++ b/avahi-daemon/dbus-protocol.c @@ -198,7 +198,7 @@ static void entry_group_free(EntryGroupInfo *i) {      assert(i->client->n_objects >= 0);      avahi_free(i); - } +}  static void sync_host_name_resolver_free(SyncHostNameResolverInfo *i) {      assert(i); @@ -838,7 +838,7 @@ fail:      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) { +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); @@ -878,7 +878,7 @@ static void host_name_resolver_callback(AvahiSHostNameResolver *r, AvahiIfIndex      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) { +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); @@ -1127,7 +1127,7 @@ static void service_browser_callback(AvahiSServiceBrowser *b, AvahiIfIndex inter      dbus_message_unref(m);  } -static void service_resolver_callback( +static void sync_service_resolver_callback(      AvahiSServiceResolver *r,      AvahiIfIndex interface,      AvahiProtocol protocol, @@ -1202,6 +1202,89 @@ static void service_resolver_callback(      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 DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void *userdata) {      DBusError error; @@ -1435,7 +1518,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          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))) { +        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);          } @@ -1478,7 +1561,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          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))) { +        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);          } @@ -1592,7 +1675,7 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          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 = { @@ -1684,13 +1767,71 @@ static DBusHandlerResult msg_server_impl(DBusConnection *c, DBusMessage *m, void          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))) { +        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")) { + +    } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "HostNameResolverNew")) { + +    } else if (dbus_message_is_method_call(m, AVAHI_DBUS_INTERFACE_SERVER, "AddressResolverNew")) { +          +        Client *client; +        static const DBusObjectPathVTable vtable = { +            NULL, +            msg_async_address_resolver_impl, +            NULL, +            NULL, +            NULL, +            NULL +        }; +         +        int32_t interface, protocol; +        char *address; +        AsyncAddressResolverInfo *i; +        AvahiAddress a; +             +        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)); | 
