mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	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.
This commit is contained in:
		
							parent
							
								
									80983b9fb6
								
							
						
					
					
						commit
						ab5fe8957b
					
				
					 1 changed files with 41 additions and 16 deletions
				
			
		| 
						 | 
				
			
			@ -24,6 +24,7 @@
 | 
			
		|||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/utsname.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
 | 
			
		||||
#include <pipewire/pipewire.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <avahi-client/client.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <sanchayan@asymptotic.io" },
 | 
			
		||||
	{ PW_KEY_MODULE_DESCRIPTION, "mDNS/DNS-SD Service Publish" },
 | 
			
		||||
	{ PW_KEY_MODULE_USAGE, "port=<TCP port number>" },
 | 
			
		||||
	{ 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);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue