kike: allow listening on multiple ports
This commit is contained in:
parent
b8f002eaf5
commit
9977a07353
63
kike.c
63
kike.c
|
@ -508,11 +508,11 @@ channel_user_count (const struct channel *chan)
|
||||||
|
|
||||||
struct server_context
|
struct server_context
|
||||||
{
|
{
|
||||||
int listen_fds[1]; ///< Listening socket FD's
|
int *listen_fds; ///< Listening socket FD's
|
||||||
size_t n_listen_fds; ///< Number of listening sockets
|
size_t n_listen_fds; ///< Number of listening sockets
|
||||||
|
|
||||||
struct client *clients; ///< Clients
|
|
||||||
SSL_CTX *ssl_ctx; ///< SSL context
|
SSL_CTX *ssl_ctx; ///< SSL context
|
||||||
|
struct client *clients; ///< Clients
|
||||||
unsigned n_clients; ///< Current number of connections
|
unsigned n_clients; ///< Current number of connections
|
||||||
|
|
||||||
struct str_map users; ///< Maps nicknames to clients
|
struct str_map users; ///< Maps nicknames to clients
|
||||||
|
@ -535,6 +535,7 @@ struct server_context
|
||||||
static void
|
static void
|
||||||
server_context_init (struct server_context *self)
|
server_context_init (struct server_context *self)
|
||||||
{
|
{
|
||||||
|
self->listen_fds = NULL;
|
||||||
self->n_listen_fds = 0;
|
self->n_listen_fds = 0;
|
||||||
self->clients = NULL;
|
self->clients = NULL;
|
||||||
self->n_clients = 0;
|
self->n_clients = 0;
|
||||||
|
@ -572,9 +573,10 @@ server_context_free (struct server_context *self)
|
||||||
|
|
||||||
for (size_t i = 0; i < self->n_listen_fds; i++)
|
for (size_t i = 0; i < self->n_listen_fds; i++)
|
||||||
xclose (self->listen_fds[i]);
|
xclose (self->listen_fds[i]);
|
||||||
|
free (self->listen_fds);
|
||||||
|
|
||||||
if (self->ssl_ctx)
|
if (self->ssl_ctx)
|
||||||
SSL_CTX_free (self->ssl_ctx);
|
SSL_CTX_free (self->ssl_ctx);
|
||||||
|
|
||||||
struct client *link, *tmp;
|
struct client *link, *tmp;
|
||||||
for (link = self->clients; link; link = tmp)
|
for (link = self->clients; link; link = tmp)
|
||||||
{
|
{
|
||||||
|
@ -2936,11 +2938,11 @@ irc_listen (struct addrinfo *gai_iter)
|
||||||
print_error ("bind to %s:%s failed: %s",
|
print_error ("bind to %s:%s failed: %s",
|
||||||
real_host, real_port, strerror (errno));
|
real_host, real_port, strerror (errno));
|
||||||
else if (listen (fd, 16 /* arbitrary number */))
|
else if (listen (fd, 16 /* arbitrary number */))
|
||||||
print_error ("listen at %s:%s failed: %s",
|
print_error ("listen on %s:%s failed: %s",
|
||||||
real_host, real_port, strerror (errno));
|
real_host, real_port, strerror (errno));
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
print_status ("listening at %s:%s", real_host, real_port);
|
print_status ("listening on %s:%s", real_host, real_port);
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2948,32 +2950,22 @@ irc_listen (struct addrinfo *gai_iter)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
irc_setup_listen_fds (struct server_context *ctx, struct error **e)
|
irc_listen_resolve (struct server_context *ctx,
|
||||||
|
const char *host, const char *port, struct addrinfo *gai_hints)
|
||||||
{
|
{
|
||||||
const char *bind_host = str_map_find (&ctx->config, "bind_host");
|
struct addrinfo *gai_result, *gai_iter;
|
||||||
const char *bind_port = str_map_find (&ctx->config, "bind_port");
|
int err = getaddrinfo (host, port, gai_hints, &gai_result);
|
||||||
hard_assert (bind_port != NULL); // We have a default value for this
|
|
||||||
|
|
||||||
struct addrinfo gai_hints, *gai_result, *gai_iter;
|
|
||||||
memset (&gai_hints, 0, sizeof gai_hints);
|
|
||||||
|
|
||||||
gai_hints.ai_socktype = SOCK_STREAM;
|
|
||||||
gai_hints.ai_flags = AI_PASSIVE;
|
|
||||||
|
|
||||||
int err = getaddrinfo (bind_host, bind_port, &gai_hints, &gai_result);
|
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
error_set (e, "%s: %s: %s",
|
print_error ("bind to %s:%s failed: %s: %s",
|
||||||
"network setup failed", "getaddrinfo", gai_strerror (err));
|
host, port, "getaddrinfo", gai_strerror (err));
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
for (gai_iter = gai_result; gai_iter; gai_iter = gai_iter->ai_next)
|
for (gai_iter = gai_result; gai_iter; gai_iter = gai_iter->ai_next)
|
||||||
{
|
{
|
||||||
if (ctx->n_listen_fds >= N_ELEMENTS (ctx->listen_fds))
|
|
||||||
break;
|
|
||||||
if ((fd = irc_listen (gai_iter)) == -1)
|
if ((fd = irc_listen (gai_iter)) == -1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -2984,10 +2976,33 @@ irc_setup_listen_fds (struct server_context *ctx, struct error **e)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
freeaddrinfo (gai_result);
|
freeaddrinfo (gai_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
irc_setup_listen_fds (struct server_context *ctx, struct error **e)
|
||||||
|
{
|
||||||
|
const char *bind_host = str_map_find (&ctx->config, "bind_host");
|
||||||
|
const char *bind_port = str_map_find (&ctx->config, "bind_port");
|
||||||
|
hard_assert (bind_port != NULL); // We have a default value for this
|
||||||
|
|
||||||
|
struct addrinfo gai_hints;
|
||||||
|
memset (&gai_hints, 0, sizeof gai_hints);
|
||||||
|
|
||||||
|
gai_hints.ai_socktype = SOCK_STREAM;
|
||||||
|
gai_hints.ai_flags = AI_PASSIVE;
|
||||||
|
|
||||||
|
struct str_vector ports;
|
||||||
|
str_vector_init (&ports);
|
||||||
|
split_str_ignore_empty (bind_port, ',', &ports);
|
||||||
|
ctx->listen_fds = xcalloc (ports.len, sizeof *ctx->listen_fds);
|
||||||
|
for (size_t i = 0; i < ports.len; i++)
|
||||||
|
irc_listen_resolve (ctx, bind_host, ports.vector[i], &gai_hints);
|
||||||
|
str_vector_free (&ports);
|
||||||
|
|
||||||
if (!ctx->n_listen_fds)
|
if (!ctx->n_listen_fds)
|
||||||
{
|
{
|
||||||
error_set (e, "network setup failed");
|
error_set (e, "%s: %s",
|
||||||
|
"network setup failed", "no ports to listen on");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue