From 8a1dae8c22cf1e3cc06ae1b405eaff623974320a Mon Sep 17 00:00:00 2001 From: yrutschle Date: Sat, 7 Nov 2020 18:55:04 +0100 Subject: [PATCH] refactor: move local address resolution into start_listen_socket --- common.c | 41 +++++++++++++++++++++-------------------- common.h | 2 +- echosrv.c | 2 +- sslh-conf.c | 6 +++--- sslh-conf.h | 2 +- sslh-main.c | 41 +++-------------------------------------- sslhconf.cfg | 2 +- 7 files changed, 31 insertions(+), 65 deletions(-) diff --git a/common.c b/common.c index 964e9ed..f38baec 100644 --- a/common.c +++ b/common.c @@ -155,15 +155,15 @@ int listen_single_addr(struct addrinfo* addr) } /* Starts listening sockets on specified addresses. - * IN: addr_list, linked list of addresses to listen to * OUT: *sockfd[] pointer to newly-allocated array of file descriptors * Returns number of addresses bound * Bound file descriptors are returned in newly-allocated *sockfd pointer */ -int start_listen_sockets(int *sockfd[], struct addrinfo *addr_list) +int start_listen_sockets(int *sockfd[]) { - struct addrinfo *addr; - int i; + struct addrinfo *addr, *start_addr; + char buf[NI_MAXHOST]; + int i, res; int num_addr = 0; int sd_socks = 0; @@ -173,26 +173,27 @@ int start_listen_sockets(int *sockfd[], struct addrinfo *addr_list) return sd_socks; } - for (addr = addr_list; addr; addr = addr->ai_next) - num_addr++; + *sockfd = NULL; - if (num_addr == 0) { - fprintf(stderr, "FATAL: No available addresses.\n"); - exit(1); - } + if (cfg.verbose) fprintf(stderr, "Listening to:\n"); - if (cfg.verbose) - fprintf(stderr, "listening to %d addresses\n", num_addr); + for (i = 0; i < cfg.listen_len; i++) { + res = resolve_split_name(&start_addr, cfg.listen[i].host, cfg.listen[i].port); + if (res) exit(4); - *sockfd = malloc(num_addr * sizeof(*sockfd[0])); - CHECK_ALLOC(*sockfd, "malloc"); + for (addr = start_addr; addr; addr = addr->ai_next) { + if (cfg.listen[i].keepalive) + addr->ai_flags = SO_KEEPALIVE; - for (i = 0, addr = addr_list; i < num_addr && addr; i++, addr = addr->ai_next) { - if (!addr) { - fprintf(stderr, "FATAL: Inconsistent listen number. This should not happen.\n"); - exit(1); - } - (*sockfd)[i] = listen_single_addr(addr); + num_addr++; + *sockfd = realloc(*sockfd, num_addr * sizeof(*sockfd)); + (*sockfd)[num_addr-1] = listen_single_addr(addr); +/* printf("%d = %d\n", num_addr-1, (*sockfd)[num_addr-1]); */ + if (cfg.verbose) + fprintf(stderr, "\t%s\t[%s]\n", sprintaddr(buf, sizeof(buf), addr), + cfg.listen[i].keepalive ? "keepalive" : ""); + } + freeaddrinfo(start_addr); } return num_addr; diff --git a/common.h b/common.h index b39f895..5fcd93d 100644 --- a/common.h +++ b/common.h @@ -133,7 +133,7 @@ void log_message(int type, const char* msg, ...); void dump_connection(struct connection *cnx); int resolve_split_name(struct addrinfo **out, char* hostname, char* port); -int start_listen_sockets(int *sockfd[], struct addrinfo *addr_list); +int start_listen_sockets(int *sockfd[]); int defer_write(struct queue *q, void* data, int data_size); int flush_deferred(struct queue *q); diff --git a/echosrv.c b/echosrv.c index b02db9c..73a8686 100644 --- a/echosrv.c +++ b/echosrv.c @@ -124,7 +124,7 @@ int main(int argc, char *argv[]) sslhcfg_fprint(stdout, &cfg, 0); config_resolve_listen(&addr_listen); - num_addr_listen = start_listen_sockets(&listen_sockets, addr_listen); + num_addr_listen = start_listen_sockets(&listen_sockets); main_loop(listen_sockets, num_addr_listen); diff --git a/sslh-conf.c b/sslh-conf.c index ab25702..862f580 100644 --- a/sslh-conf.c +++ b/sslh-conf.c @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Sat Nov 7 09:23:57 2020. + * on Sat Nov 7 09:31:10 2020. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2019 Yves Rutschle @@ -863,9 +863,9 @@ static struct config_desc table_sslhcfg[] = { /* offset_present */ 0, /* size */ sizeof(char*), /* array_type */ -1, - /* mandatory */ 1, + /* mandatory */ 0, /* optional */ 0, - /* default_val*/ .default_val.def_string = NULL + /* default_val*/ .default_val.def_string = "" }, { diff --git a/sslh-conf.h b/sslh-conf.h index df0b845..6edb704 100644 --- a/sslh-conf.h +++ b/sslh-conf.h @@ -1,5 +1,5 @@ /* Generated by conf2struct (https://www.rutschle.net/tech/conf2struct/README) - * on Sat Nov 7 09:23:57 2020. + * on Sat Nov 7 09:31:10 2020. # conf2struct: generate libconf parsers that read to structs # Copyright (C) 2018-2019 Yves Rutschle diff --git a/sslh-main.c b/sslh-main.c index 8c42653..9feec7c 100644 --- a/sslh-main.c +++ b/sslh-main.c @@ -86,7 +86,6 @@ static void printcaps(void) { static void printsettings(void) { char buf[NI_MAXHOST]; - struct addrinfo *a; int i; struct sslhcfg_protocols_item *p; @@ -103,43 +102,11 @@ static void printsettings(void) p->keepalive ? "keepalive" : "", p->fork ? "fork" : ""); } - fprintf(stderr, "listening on:\n"); - for (a = addr_listen; a; a = a->ai_next) { - fprintf(stderr, - "\t%s\t[%s]\n", - sprintaddr(buf, sizeof(buf), a), - a->ai_flags & SO_KEEPALIVE ? "keepalive" : ""); - } fprintf(stderr, "timeout: %d\non-timeout: %s\n", cfg.timeout, timeout_protocol()->name); } -/* Extract configuration on addresses and ports on which to listen. - * out: newly allocated list of addrinfo to listen to - */ -static int config_resolve_listen(struct addrinfo **listen) -{ - int i, res; - for (i = 0; i < cfg.listen_len; i++) { - res = resolve_split_name(listen, cfg.listen[i].host, cfg.listen[i].port); - if (res) return res; - - /* getaddrinfo returned a list of addresses corresponding to the - * specification; move the pointer to the end of that list before - * processing the next specification, while setting flags for - * start_listen_sockets() through ai_flags (which is not meant for - * that, but is only used as hint in getaddrinfo, so it's OK) */ - for (; *listen; listen = &((*listen)->ai_next)) { - if (cfg.listen[i].keepalive) - (*listen)->ai_flags = SO_KEEPALIVE; - } - } - return 0; -} - - - static void setup_regex_probe(struct sslhcfg_protocols_item *p) #ifdef LIBCONFIG { @@ -184,7 +151,7 @@ static void config_protocols() struct sslhcfg_protocols_item* p = &(cfg.protocols[i]); if (resolve_split_name(&(p->saddr), p->host, p->port)) { fprintf(stderr, "cannot resolve %s:%s\n", p->host, p->port); - exit(1); + exit(4); } p->probe = get_probe(p->name); @@ -220,7 +187,7 @@ void config_sanity_check(struct sslhcfg_item* cfg) { /* If compiling with systemd socket support no need to require listen address */ #ifndef SYSTEMD - if (!addr_listen && !cfg->inetd) { + if (!cfg->listen_len && !cfg->inetd) { fprintf(stderr, "No listening address specified; use at least one -p option\n"); exit(1); } @@ -245,8 +212,6 @@ int main(int argc, char *argv[], char* envp[]) if (res) exit(6); if (cfg.verbose > 3) sslhcfg_fprint(stderr, &cfg, 0); - res = config_resolve_listen(&addr_listen); - if (res) exit(4); config_protocols(); config_sanity_check(&cfg); @@ -260,7 +225,7 @@ int main(int argc, char *argv[], char* envp[]) if (cfg.verbose) printsettings(); - num_addr_listen = start_listen_sockets(&listen_sockets, addr_listen); + num_addr_listen = start_listen_sockets(&listen_sockets); #ifdef SYSTEMD if (num_addr_listen < 1) { diff --git a/sslhconf.cfg b/sslhconf.cfg index 76760fd..6062424 100644 --- a/sslhconf.cfg +++ b/sslhconf.cfg @@ -55,7 +55,7 @@ config: { { name: "on-timeout"; type: "string"; default: "ssh"; description: "Target to connect to when timing out"; }, - { name: "prefix"; type: "string"; description: "Reserved for testing" }, # For echosrv only, not sslh + { name: "prefix"; type: "string"; default: ""; description: "Reserved for testing" }, # For echosrv only, not sslh { name: "listen", no_cl_accessors: true; # disable generation of individual cl options for each group element (we create a specific --listen option further below)