From f522a261259ffb3e2d43bf4deff62af3dd1cc06d Mon Sep 17 00:00:00 2001 From: Jonas Johansson Date: Thu, 3 May 2018 08:54:06 +0200 Subject: [PATCH 1/2] inetd: only restart inetd services when neccessary Do not restart a inetd service if the listening interface is changed. Only bring down established connection which are no longer allowed, i.e. do not touch already allowed established connections. Signed-off-by: Jonas Johansson --- src/inetd.c | 36 ++++++++++++++++++++++++------------ src/inetd.h | 1 + src/service.c | 5 ++++- src/svc.h | 1 + 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/inetd.c b/src/inetd.c index 043fbe47..a5ed80e7 100644 --- a/src/inetd.c +++ b/src/inetd.c @@ -122,7 +122,7 @@ static int inetd_stream_peek(int sd, char *ifname) return 0; } -static int get_stdin(svc_t *svc) +static int get_stdin(svc_t *svc, char* iifname) { int stdin = svc->inetd.watcher.fd; char ifname[IF_NAMESIZE] = "UNKNOWN"; @@ -152,6 +152,9 @@ static int get_stdin(svc_t *svc) return -1; } + /* Return ingress interface */ + strncpy(iifname, ifname, IF_NAMESIZE); + return stdin; } @@ -160,6 +163,7 @@ static void socket_cb(uev_t *w, void *arg, int events) { svc_t *svc = (svc_t *)arg, *task; const char *conn = " connection"; + char iifname[IF_NAMESIZE] = "UNKNOWN"; int stdin; _d("%s: Got socket event ...", svc->cmd); @@ -168,7 +172,7 @@ static void socket_cb(uev_t *w, void *arg, int events) return; } - stdin = get_stdin(svc); + stdin = get_stdin(svc, iifname); if (stdin < 0) { logit(LOG_CRIT, "%s: Unable to accept incoming connection", svc->cmd); return; @@ -216,6 +220,7 @@ static void socket_cb(uev_t *w, void *arg, int events) memcpy(task->args, svc->args, sizeof(task->args)); strlcpy(task->desc, svc->desc, sizeof(task->desc) - strlen(conn)); strlcat(task->desc, conn, sizeof(task->desc)); + strncpy(task->iifname, iifname, sizeof(task->iifname)); task->stdin_fd = stdin; service_step(task); @@ -335,6 +340,22 @@ int inetd_start(inetd_t *inetd) return 0; } +void inetd_stop_children(inetd_t *inetd, int check_allowed) +{ + svc_t *svc, *iter = NULL; + + svc = svc_job_iterator(&iter, 1, inetd->svc->job); + while (svc) { + if (!svc_is_inetd(svc)) { + if (!check_allowed || !inetd_is_allowed(inetd, svc->iifname)) { + svc_stop(svc); + service_step(svc); + } + } + svc = svc_job_iterator(&iter, 0, inetd->svc->job); + } +} + void inetd_stop(inetd_t *inetd) { if (!inetd || !inetd->svc) { @@ -351,20 +372,11 @@ void inetd_stop(inetd_t *inetd) * and halt the watcher, so don't close the socket! */ if (!svc_is_busy(inetd->svc)) { - svc_t *svc, *iter = NULL; - _d("Shutting down inet socket %d ...", inetd->watcher.fd); close(inetd->watcher.fd); inetd->watcher.fd = -1; - svc = svc_job_iterator(&iter, 1, inetd->svc->job); - while (svc) { - if (!svc_is_inetd(svc)) { - svc_stop(svc); - service_step(svc); - } - svc = svc_job_iterator(&iter, 0, inetd->svc->job); - } + inetd_stop_children(inetd, 0); } } } diff --git a/src/inetd.h b/src/inetd.h index bf349836..babc2ddf 100644 --- a/src/inetd.h +++ b/src/inetd.h @@ -58,6 +58,7 @@ int inetd_check_loop(struct sockaddr *sa, socklen_t len, char *name); int inetd_start (inetd_t *inetd); void inetd_stop (inetd_t *inetd); +void inetd_stop_children (inetd_t *inetd, int check_allowed); int inetd_new (inetd_t *inetd, char *name, char *service, char *proto, int forking, svc_t *svc); int inetd_del (inetd_t *inetd); diff --git a/src/service.c b/src/service.c index 187bd962..3aa77833 100644 --- a/src/service.c +++ b/src/service.c @@ -1114,7 +1114,10 @@ restart: break; service_restart(svc); } else { - service_stop(svc); + if (svc_is_inetd(svc)) + inetd_stop_children(&svc->inetd, 1); + else + service_stop(svc); } svc_mark_clean(svc); } diff --git a/src/svc.h b/src/svc.h index 84405048..53189e0e 100644 --- a/src/svc.h +++ b/src/svc.h @@ -109,6 +109,7 @@ typedef struct svc { /* For inetd services */ inetd_t inetd; int stdin_fd; + char iifname[IF_NAMESIZE]; /* Ingress interface for connection */ /* Set for services we need to redirect stdout/stderr to syslog */ struct { From 59f22c7d27ace782ac7bdf65a3ebef91f6802797 Mon Sep 17 00:00:00 2001 From: Jonas Johansson Date: Mon, 7 May 2018 09:25:55 +0200 Subject: [PATCH 2/2] fixup! inetd: only restart inetd services when neccessary Signed-off-by: Jonas Johansson --- src/service.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/service.c b/src/service.c index 3aa77833..43aac6e9 100644 --- a/src/service.c +++ b/src/service.c @@ -1114,9 +1114,11 @@ restart: break; service_restart(svc); } else { +#ifdef INETD_ENABLED if (svc_is_inetd(svc)) inetd_stop_children(&svc->inetd, 1); else +#endif service_stop(svc); } svc_mark_clean(svc);