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 <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson
2015-03-04 15:21:43 +01:00
parent 957586db09
commit 5ddd5c15a5
+13 -5
View File
@@ -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);
}
}