aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--kike.c63
1 files changed, 39 insertions, 24 deletions
diff --git a/kike.c b/kike.c
index 32be85c..bd30529 100644
--- a/kike.c
+++ b/kike.c
@@ -508,11 +508,11 @@ channel_user_count (const struct channel *chan)
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
- struct client *clients; ///< Clients
SSL_CTX *ssl_ctx; ///< SSL context
+ struct client *clients; ///< Clients
unsigned n_clients; ///< Current number of connections
struct str_map users; ///< Maps nicknames to clients
@@ -535,6 +535,7 @@ struct server_context
static void
server_context_init (struct server_context *self)
{
+ self->listen_fds = NULL;
self->n_listen_fds = 0;
self->clients = NULL;
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++)
xclose (self->listen_fds[i]);
+ free (self->listen_fds);
+
if (self->ssl_ctx)
SSL_CTX_free (self->ssl_ctx);
-
struct client *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",
real_host, real_port, strerror (errno));
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));
else
{
- print_status ("listening at %s:%s", real_host, real_port);
+ print_status ("listening on %s:%s", real_host, real_port);
return fd;
}
@@ -2948,32 +2950,22 @@ irc_listen (struct addrinfo *gai_iter)
return -1;
}
-static bool
-irc_setup_listen_fds (struct server_context *ctx, struct error **e)
+static void
+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");
- 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, *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);
+ struct addrinfo *gai_result, *gai_iter;
+ int err = getaddrinfo (host, port, gai_hints, &gai_result);
if (err)
{
- error_set (e, "%s: %s: %s",
- "network setup failed", "getaddrinfo", gai_strerror (err));
- return false;
+ print_error ("bind to %s:%s failed: %s: %s",
+ host, port, "getaddrinfo", gai_strerror (err));
+ return;
}
int fd;
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)
continue;
@@ -2984,10 +2976,33 @@ irc_setup_listen_fds (struct server_context *ctx, struct error **e)
break;
}
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)
{
- error_set (e, "network setup failed");
+ error_set (e, "%s: %s",
+ "network setup failed", "no ports to listen on");
return false;
}
return true;