From e82080a5f62991e2892b88dce108537f64960e55 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 7 Nov 2013 11:00:19 +0100 Subject: [BB#63] conf: Allow multiple Listen statements in the config. This introduces a list (vector) of addresses instead of having just one address string. Signed-off-by: Michael Adam --- src/child.c | 39 ++++++++++++++++++++++++++++++++++++--- src/child.h | 4 +++- src/conf.c | 40 +++++++++++++++++++++++++++++++++------- src/conf.h | 2 +- src/main.c | 4 ++-- 5 files changed, 75 insertions(+), 14 deletions(-) diff --git a/src/child.c b/src/child.c index c7490fd..01ef178 100644 --- a/src/child.c +++ b/src/child.c @@ -522,9 +522,16 @@ void child_kill_children (int sig) } } -int child_listening_sock (const char *addr, uint16_t port) + +/** + * Listen on the various configured interfaces + */ +int child_listening_sockets(vector_t listen_addrs, uint16_t port) { int ret; + ssize_t i; + + assert (port > 0); if (listen_fds == NULL) { listen_fds = vector_create(); @@ -535,8 +542,34 @@ int child_listening_sock (const char *addr, uint16_t port) } } - ret = listen_sock (addr, port, listen_fds); - return ret; + if ((listen_addrs == NULL) || + (vector_length(config.listen_addrs) == 0)) + { + /* + * no Listen directive: + * listen on the wildcard address(es) + */ + ret = listen_sock(NULL, port, listen_fds); + return ret; + } + + for (i = 0; i < vector_length(config.listen_addrs); i++) { + const char *addr; + + addr = (char *)vector_getentry(config.listen_addrs, i, NULL); + if (addr == NULL) { + log_message(LOG_WARNING, + "got NULL from listen_addrs - skipping"); + continue; + } + + ret = listen_sock(addr, port, listen_fds); + if (ret != 0) { + return ret; + } + } + + return 0; } void child_close_sock (void) diff --git a/src/child.h b/src/child.h index 774431f..70f52b7 100644 --- a/src/child.h +++ b/src/child.h @@ -21,6 +21,8 @@ #ifndef TINYPROXY_CHILD_H #define TINYPROXY_CHILD_H +#include "vector.h" + typedef enum { CHILD_MAXCLIENTS, CHILD_MAXSPARESERVERS, @@ -30,7 +32,7 @@ typedef enum { } child_config_t; extern short int child_pool_create (void); -extern int child_listening_sock (const char *addr, uint16_t port); +extern int child_listening_sockets (vector_t listen_addrs, uint16_t port); extern void child_close_sock (void); extern void child_main_loop (void); extern void child_kill_children (int sig); diff --git a/src/conf.c b/src/conf.c index 59630a2..740c7f4 100644 --- a/src/conf.c +++ b/src/conf.c @@ -288,7 +288,7 @@ static void free_config (struct config_s *conf) safefree (conf->stathost); safefree (conf->user); safefree (conf->group); - safefree (conf->ipAddr); + vector_delete(conf->listen_addrs); #ifdef FILTER_ENABLE safefree (conf->filter); #endif /* FILTER_ENABLE */ @@ -465,8 +465,18 @@ static void initialize_with_defaults (struct config_s *conf, conf->group = safestrdup (defaults->group); } - if (defaults->ipAddr) { - conf->ipAddr = safestrdup (defaults->ipAddr); + if (defaults->listen_addrs) { + ssize_t i; + + conf->listen_addrs = vector_create(); + for (i=0; i < vector_length(defaults->listen_addrs); i++) { + char *addr; + size_t size; + addr = (char *)vector_getentry(defaults->listen_addrs, + i, &size); + vector_append(conf->listen_addrs, addr, size); + } + } #ifdef FILTER_ENABLE @@ -882,11 +892,26 @@ static HANDLE_FUNC (handle_bind) static HANDLE_FUNC (handle_listen) { - int r = set_string_arg (&conf->ipAddr, line, &match[2]); + char *arg = get_string_arg (line, &match[2]); - if (r) - return r; - log_message (LOG_INFO, "Listening on IP %s", conf->ipAddr); + if (arg == NULL) { + return -1; + } + + if (conf->listen_addrs == NULL) { + conf->listen_addrs = vector_create(); + if (conf->listen_addrs == NULL) { + log_message(LOG_WARNING, "Could not create a list " + "of listen addresses."); + return -1; + } + } + + vector_append (conf->listen_addrs, arg, strlen(arg) + 1); + + log_message(LOG_INFO, "Added address [%s] to listen addresses.", arg); + + safefree (arg); return 0; } @@ -933,6 +958,7 @@ static HANDLE_FUNC (handle_addheader) /* * Log level's strings. + */ struct log_levels_s { const char *string; diff --git a/src/conf.h b/src/conf.h index f62a854..0fb4226 100644 --- a/src/conf.h +++ b/src/conf.h @@ -46,7 +46,7 @@ struct config_s { unsigned int quit; /* boolean */ char *user; char *group; - char *ipAddr; + vector_t listen_addrs; #ifdef FILTER_ENABLE char *filter; unsigned int filter_url; /* boolean */ diff --git a/src/main.c b/src/main.c index 99ab664..00c0750 100644 --- a/src/main.c +++ b/src/main.c @@ -430,8 +430,8 @@ main (int argc, char **argv) #endif /* FILTER_ENABLE */ /* Start listening on the selected port. */ - if (child_listening_sock (config.ipAddr, config.port) < 0) { - fprintf (stderr, "%s: Could not create listening socket.\n", + if (child_listening_sockets(config.listen_addrs, config.port) < 0) { + fprintf (stderr, "%s: Could not create listening sockets.\n", argv[0]); exit (EX_OSERR); } -- cgit v1.2.3