From 54edca09d97989bb96fbafc01065e4a7557afa25 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Wed, 13 Nov 2019 18:41:17 +0100 Subject: [PATCH] syslogd: Close open UNIX and inet sockets on SIGTERM When creating Inet sockets we may get multiple struct addrinfo records. With this patch we support up to 16 records per Internet peer. When closing we iterate over all peers and all records. Refactor socket_close() to clean up any lingering socket path when closing UNIX socket. Signed-off-by: Joachim Nilsson --- src/socket.c | 19 ++++++++++++------- src/syslogd.c | 29 ++++++++++++++++++++--------- src/syslogd.h | 3 ++- 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/socket.c b/src/socket.c index d389bd0..bd2c912 100644 --- a/src/socket.c +++ b/src/socket.c @@ -186,18 +186,23 @@ err: close(sd); int socket_close(int sd) { + struct sockaddr_un *sun; struct sock *entry, *tmp; LIST_FOREACH_SAFE(entry, &sl, link, tmp) { - if (entry->sd == sd) { - LIST_REMOVE(entry, link); - close(entry->sd); - if (entry->ai.ai_family == AF_UNIX) - free(entry->ai.ai_addr); - free(entry); + if (entry->sd != sd) + continue; - return 0; + LIST_REMOVE(entry, link); + close(entry->sd); + if (entry->ai.ai_family == AF_UNIX) { + sun = (struct sockaddr_un *)entry->ai.ai_addr; + (void)unlink(sun->sun_path); } + free(entry->ai.ai_addr); + free(entry); + + return 0; } errno = ENOENT; diff --git a/src/syslogd.c b/src/syslogd.c index c801566..dc30eee 100644 --- a/src/syslogd.c +++ b/src/syslogd.c @@ -572,6 +572,8 @@ static void create_unix_socket(struct peer *pe) if (sd < 0) goto err; + logit("Created UNIX socket %d ...\n", sd); + pe->pe_sock[pe->pe_socknum++] = sd; return; err: ERR("cannot create %s", pe->pe_name); @@ -658,6 +660,11 @@ static void create_inet_socket(struct peer *pe) } for (r = res; r; r = r->ai_next) { + if (pe->pe_socknum + 1 >= NELEMS(pe->pe_sock)) { + WARN("Only %zd IP addresses per socket supported.", NELEMS(pe->pe_sock)); + break; + } + if (SecureMode) r->ai_flags |= AI_SECURE; else @@ -667,7 +674,8 @@ static void create_inet_socket(struct peer *pe) if (sd < 0) continue; - logit("Created inet socket %d ...\n", sd); + logit("Created inet socket %d for %s:%s ...\n", sd, pe->pe_name, pe->pe_serv); + pe->pe_sock[pe->pe_socknum++] = sd; } freeaddrinfo(res); @@ -1973,6 +1981,7 @@ void die(int signo) { struct filed *f, *next; int was_initialized = Initialized; + struct peer *pe, *penext; Initialized = 0; /* Don't log SIGCHLDs in case we receive one during exiting */ @@ -2011,14 +2020,16 @@ void die(int signo) free(f); } - /* Close the UNIX sockets. */ - /* XXX */ - - /* Close the inet sockets. */ - /* XXX */ - - /* Clean-up UNIX sockets. */ - /* XXX */ + /* + * Close all UNIX and inet sockets + */ + SIMPLEQ_FOREACH_SAFE(pe, &pqueue, pe_link, penext) { + for (size_t i = 0; i < pe->pe_socknum; i++) { + logit("Closing socket %d ...\n", pe->pe_sock[i]); + socket_close(pe->pe_sock[i]); + } + free(pe); + } exit(0); } diff --git a/src/syslogd.h b/src/syslogd.h index d115dfd..9996c0a 100644 --- a/src/syslogd.h +++ b/src/syslogd.h @@ -190,7 +190,8 @@ struct peer { const char *pe_name; const char *pe_serv; mode_t pe_mode; - int pe_sock; + int pe_sock[16]; + size_t pe_socknum; }; /*