From 5ddd5c15a5a1a2c112bf1d0bda0e8ebd7f07cbd3 Mon Sep 17 00:00:00 2001 From: Joachim Nilsson Date: Wed, 4 Mar 2015 15:19:16 +0100 Subject: [PATCH] inetd.c:spawn_socket() - Set socket options for reusing address and port Without this patch binding to sockets when restarting them fails. This was found when quickly changing between runlevels where a service runs, not runs, then back to a runlevel where is shall run. Also, refactor previous setsockopt() call to use new common macro. Signed-off-by: Joachim Nilsson --- inetd.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/inetd.c b/inetd.c index 9274d448..306ca2fa 100644 --- a/inetd.c +++ b/inetd.c @@ -36,6 +36,13 @@ #include "private.h" #include "svc.h" +#define ENABLE_SOCKOPT(sd, level, opt) \ + do { \ + int val = 1; \ + if (setsockopt(sd, level, opt, &val, sizeof(val)) < 0) \ + FLOG_PERROR("Failed setting %s on %s service.", \ + #opt, inetd->name); \ + } while (0); /* Socket callback, looks up correct svc and starts it as an inetd service */ static void socket_cb(uev_ctx_t *UNUSED(ctx), uev_t *w, void *arg, int UNUSED(events)) @@ -65,12 +72,16 @@ static void spawn_socket(inetd_t *inetd) return; } - sd = socket(AF_INET, inetd->type | SOCK_NONBLOCK, inetd->proto); + _d("Spawning server socket for inetd %s ...", inetd->name); + sd = socket(AF_INET, inetd->type | SOCK_NONBLOCK | SOCK_CLOEXEC, inetd->proto); if (-1 == sd) { FLOG_PERROR("Failed opening inetd socket type %d proto %d", inetd->type, inetd->proto); return; } + ENABLE_SOCKOPT(sd, SOL_SOCKET, SO_REUSEADDR); + ENABLE_SOCKOPT(sd, SOL_SOCKET, SO_REUSEPORT); + memset(&s, 0, sizeof(s)); s.sin_family = AF_INET; s.sin_addr.s_addr = INADDR_ANY; @@ -90,11 +101,8 @@ static void spawn_socket(inetd_t *inetd) return; } } else { /* SOCK_DGRAM */ - int opt = 1; - /* Set extra sockopt to get ifindex from inbound packets */ - if (-1 == setsockopt(sd, SOL_IP, IP_PKTINFO, &opt, sizeof(opt))) - _pe("Failed enabling IP_PKTINFO on socket"); + ENABLE_SOCKOPT(sd, SOL_IP, IP_PKTINFO); } }