pulse-server: improve server registration

Take a list of addresses to listen on.
This commit is contained in:
Wim Taymans 2020-10-09 13:26:14 +02:00
parent 5b8a52cc78
commit 8b70a83c96
2 changed files with 44 additions and 80 deletions

View file

@ -32,6 +32,7 @@
#include <errno.h> #include <errno.h>
#include <math.h> #include <math.h>
#include <time.h> #include <time.h>
#include <limits.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
@ -2692,7 +2693,7 @@ static void server_free(struct server *server)
free(server); free(server);
} }
static int make_local_socket(struct server *server, const char *name) static int make_local_socket(struct server *server, char *name)
{ {
const char *runtime_dir; const char *runtime_dir;
socklen_t size; socklen_t size;
@ -2748,10 +2749,29 @@ error:
return res; return res;
} }
static int make_inet_socket(struct server *server, uint32_t address, uint16_t port) static int make_inet_socket(struct server *server, char *name)
{ {
struct sockaddr_in addr; struct sockaddr_in addr;
int res, fd, on; int res, fd, on;
uint32_t address = INADDR_ANY;
uint16_t port;
char *col;
col = strchr(name, ':');
if (col) {
struct in_addr ipv4;
port = atoi(col+1);
*col = '\0';
if (inet_pton(AF_INET, name, &ipv4) > 0)
address = ntohl(ipv4.s_addr);
else
address = INADDR_ANY;
} else {
address = INADDR_ANY;
port = atoi(name);
}
if (port == 0)
port = PW_PROTOCOL_PULSE_DEFAULT_PORT;
if ((fd = socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0) { if ((fd = socket(PF_INET, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) < 0) {
res = -errno; res = -errno;
@ -2788,42 +2808,7 @@ error:
return res; return res;
} }
static struct server *create_local_server(struct impl *impl, const char *name) static struct server *create_server(struct impl *impl, char *address)
{
struct server *server;
int fd, res;
server = calloc(1, sizeof(struct server));
if (server == NULL)
return NULL;
server->impl = impl;
spa_list_init(&server->clients);
spa_list_append(&impl->servers, &server->link);
fd = make_local_socket(server, name);
if (fd < 0) {
res = fd;
goto error;
}
server->source = pw_loop_add_io(impl->loop, fd, SPA_IO_IN, true, on_connect, server);
if (server->source == NULL) {
res = -errno;
pw_log_error(NAME" %p: can't create server source: %m", impl);
goto error_close;
}
return server;
error_close:
close(fd);
error:
server_free(server);
errno = -res;
return NULL;
}
static struct server *create_inet_server(struct impl *impl, uint32_t address, uint16_t port)
{ {
int fd, res; int fd, res;
struct server *server; struct server *server;
@ -2836,7 +2821,13 @@ static struct server *create_inet_server(struct impl *impl, uint32_t address, ui
spa_list_init(&server->clients); spa_list_init(&server->clients);
spa_list_append(&impl->servers, &server->link); spa_list_append(&impl->servers, &server->link);
fd = make_inet_socket(server, address, port); if (strstr(address, "unix:") == address) {
fd = make_local_socket(server, address+5);
} else if (strstr(address, "tcp:") == address) {
fd = make_inet_socket(server, address+4);
} else {
fd = -EINVAL;
}
if (fd < 0) { if (fd < 0) {
res = fd; res = fd;
goto error; goto error;
@ -2858,7 +2849,6 @@ error:
} }
static void impl_free(struct impl *impl) static void impl_free(struct impl *impl)
{ {
struct server *s; struct server *s;
@ -2874,7 +2864,8 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
{ {
struct impl *impl; struct impl *impl;
const char *str; const char *str;
int res; int i, n_addr;
char **addr;
impl = calloc(1, sizeof(struct impl) + user_data_size); impl = calloc(1, sizeof(struct impl) + user_data_size);
if (impl == NULL) if (impl == NULL)
@ -2930,48 +2921,20 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
str = NULL; str = NULL;
if (props != NULL) if (props != NULL)
str = pw_properties_get(props, "unix.socket"); str = pw_properties_get(props, "server.address");
if (str == NULL) if (str == NULL)
str = PW_PROTOCOL_PULSE_DEFAULT_SOCKET; str = PW_PROTOCOL_PULSE_DEFAULT_SERVER;
if (create_local_server(impl, str) == NULL) { addr = pw_split_strv(str, ",", INT_MAX, &n_addr);
res = -errno; for (i = 0; i < n_addr; i++) {
goto error; if (create_server(impl, addr[i]) == NULL) {
} pw_log_warn(NAME" %p: can't create server for %s: %m",
impl, addr[i]);
str = NULL;
if (props != NULL)
str = pw_properties_get(props, "tcp.listen");
if (str != NULL) {
uint32_t address = INADDR_ANY;
uint16_t port;
const char *col = strchr(str, ':');
if (col) {
struct in_addr ipv4;
port = atoi(col+1);
if (inet_pton(AF_INET, str, &ipv4) > 0)
address = ntohl(ipv4.s_addr);
else
address = INADDR_ANY;
} else {
address = INADDR_ANY;
port = atoi(str);
}
if (port == 0)
port = PW_PROTOCOL_PULSE_DEFAULT_PORT;
if (create_inet_server(impl, address, port) == NULL) {
res = -errno;
goto error;
} }
} }
pw_free_strv(addr);
return (struct pw_protocol_pulse*)impl; return (struct pw_protocol_pulse*)impl;
error:
impl_free(impl);
errno = -res;
return NULL;
} }
void *pw_protocol_pulse_get_user_data(struct pw_protocol_pulse *pulse) void *pw_protocol_pulse_get_user_data(struct pw_protocol_pulse *pulse)

View file

@ -35,8 +35,9 @@ extern "C" {
#define PW_PROTOCOL_PULSE_DEFAULT_PORT 4713 #define PW_PROTOCOL_PULSE_DEFAULT_PORT 4713
#define PW_PROTOCOL_PULSE_DEFAULT_SOCKET "native" #define PW_PROTOCOL_PULSE_DEFAULT_SOCKET "native"
#define PW_PROTOCOL_PULSE_USAGE "[ tcp.listen=[ip:]<port>[,...] ] " \ #define PW_PROTOCOL_PULSE_DEFAULT_SERVER "unix:native"
"[ unix.socket=<path>[,...] ] " \
#define PW_PROTOCOL_PULSE_USAGE "[ server.address=(tcp:[<ip>:]<port>|unix:<path>)[,...] ] " \
struct pw_protocol_pulse; struct pw_protocol_pulse;
struct pw_protocol_pulse_server; struct pw_protocol_pulse_server;