From ab5fe8957be052087178d5b96c1f31323f9360fb Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 17 Nov 2022 17:07:38 +0100 Subject: [PATCH] pulse-server: use running servers to publish zeroconf Loop over the servers and use its family and port to publish the zeroconf services. This avoids exposing the services when we don't have any TCP servers running to accept connections. It also avoids exposing the services twice with both IP4 and IP6 addresses. It also exposes the services with a port that is actually usable, in case it's not the same as the default port. --- .../modules/module-zeroconf-publish.c | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c b/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c index 5842d4509..03b1b5574 100644 --- a/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c +++ b/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c @@ -24,6 +24,7 @@ */ #include +#include #include @@ -32,6 +33,7 @@ #include "../manager.h" #include "../module.h" #include "../pulse-server.h" +#include "../server.h" #include "../../module-zeroconf-discover/avahi-poll.h" #include @@ -94,8 +96,6 @@ struct module_zeroconf_publish_data { struct spa_hook core_listener; struct spa_hook manager_listener; - unsigned int port; - AvahiPoll *avahi_poll; AvahiClient *client; @@ -389,16 +389,43 @@ static AvahiStringList *get_service_txt(const struct service *s) return txt; } +static int find_port(struct service *s, int *proto, uint16_t *port) +{ + struct module_zeroconf_publish_data *d = s->userdata; + struct impl *impl = d->module->impl; + struct server *server; + + spa_list_for_each(server, &impl->servers, link) { + if (server->addr.ss_family == AF_INET) { + *proto = AVAHI_PROTO_INET; + *port = ntohs(((struct sockaddr_in*) &server->addr)->sin_port); + return 0; + } else if (server->addr.ss_family == AF_INET6) { + *proto = AVAHI_PROTO_INET6; + *port = ntohs(((struct sockaddr_in6*) &server->addr)->sin6_port); + return 0; + } + } + return -ENODEV; +} + static void publish_service(struct service *s) { - if (!s->userdata->client || avahi_client_get_state(s->userdata->client) != AVAHI_CLIENT_S_RUNNING) + struct module_zeroconf_publish_data *d = s->userdata; + int proto; + uint16_t port; + + if (find_port(s, &proto, &port) < 0) + return; + + if (!d->client || avahi_client_get_state(d->client) != AVAHI_CLIENT_S_RUNNING) return; if (!s->entry_group) { - s->entry_group = avahi_entry_group_new(s->userdata->client, service_entry_group_callback, s); + s->entry_group = avahi_entry_group_new(d->client, service_entry_group_callback, s); if (s->entry_group == NULL) { pw_log_error("avahi_entry_group_new(): %s", - avahi_strerror(avahi_client_errno(s->userdata->client))); + avahi_strerror(avahi_client_errno(d->client))); return; } } else { @@ -410,22 +437,22 @@ static void publish_service(struct service *s) if (avahi_entry_group_add_service_strlst( s->entry_group, - AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + AVAHI_IF_UNSPEC, proto, 0, s->service_name, s->service_type, NULL, NULL, - s->userdata->port, + port, s->txt) < 0) { pw_log_error("avahi_entry_group_add_service_strlst(): %s", - avahi_strerror(avahi_client_errno(s->userdata->client))); + avahi_strerror(avahi_client_errno(d->client))); return; } if (avahi_entry_group_add_service_subtype( s->entry_group, - AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + AVAHI_IF_UNSPEC, proto, 0, s->service_name, s->service_type, @@ -434,33 +461,33 @@ static void publish_service(struct service *s) (s->subtype == SUBTYPE_HARDWARE ? SERVICE_SUBTYPE_SOURCE_HARDWARE : (s->subtype == SUBTYPE_VIRTUAL ? SERVICE_SUBTYPE_SOURCE_VIRTUAL : SERVICE_SUBTYPE_SOURCE_MONITOR))) < 0) { pw_log_error("avahi_entry_group_add_service_subtype(): %s", - avahi_strerror(avahi_client_errno(s->userdata->client))); + avahi_strerror(avahi_client_errno(d->client))); return; } if (!s->is_sink && s->subtype != SUBTYPE_MONITOR) { if (avahi_entry_group_add_service_subtype( s->entry_group, - AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, + AVAHI_IF_UNSPEC, proto, 0, s->service_name, SERVICE_TYPE_SOURCE, NULL, SERVICE_SUBTYPE_SOURCE_NON_MONITOR) < 0) { pw_log_error("avahi_entry_group_add_service_subtype(): %s", - avahi_strerror(avahi_client_errno(s->userdata->client))); + avahi_strerror(avahi_client_errno(d->client))); return; } } if (avahi_entry_group_commit(s->entry_group) < 0) { pw_log_error("avahi_entry_group_commit(): %s", - avahi_strerror(avahi_client_errno(s->userdata->client))); + avahi_strerror(avahi_client_errno(d->client))); return; } spa_list_remove(&s->link); - spa_list_append(&s->userdata->published, &s->link); + spa_list_append(&d->published, &s->link); pw_log_info("created service: %s", s->service_name); } @@ -642,7 +669,6 @@ static int module_zeroconf_publish_unload(struct module *module) static const struct spa_dict_item module_zeroconf_publish_info[] = { { PW_KEY_MODULE_AUTHOR, "Sanchayan Maity " }, { PW_KEY_MODULE_VERSION, PACKAGE_VERSION }, }; @@ -652,7 +678,6 @@ static int module_zeroconf_publish_prepare(struct module * const module) struct module_zeroconf_publish_data * const data = module->user_data; data->module = module; - data->port = pw_properties_get_uint32(module->props, "port", PW_PROTOCOL_PULSE_DEFAULT_PORT); spa_list_init(&data->pending); spa_list_init(&data->published);