Merge pull request #27 from westermo/wmo/2.4

Westermo fixes for UDP inetd services and more

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
This commit is contained in:
Joachim Nilsson committed 2016-04-24 12:06:43 +02:00
commit 4b0f78c1b5
5 files changed
+65 -29

No files matched your search

+1 -1
View File
@@ -351,7 +351,7 @@ int api_init(uev_ctx_t *ctx)
.sun_path = INIT_SOCKET,
};
sd = socket(AF_UNIX, SOCK_STREAM, 0);
sd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (-1 == sd) {
_pe("Failed starting external API socket");
return 1;
+3 -3
View File
@@ -245,9 +245,9 @@ pid_t run_getty(char *cmd, char *args[], int console)
if (fd != STDIN_FILENO)
exit(1);
dup2(0, STDIN_FILENO);
dup2(0, STDOUT_FILENO);
dup2(0, STDERR_FILENO);
dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO);
dup2(fd, STDERR_FILENO);
prctl(PR_SET_NAME, "console", 0, 0, 0);
}
+57 -23
View File
@@ -127,8 +127,7 @@ static int get_stdin(svc_t *svc)
}
if (!inetd_is_allowed(&svc->inetd, ifname)) {
FLOG_INFO("Service %s on port %d not allowed from interface %s.",
svc->inetd.name, svc->inetd.port, ifname);
FLOG_INFO("Service %s on %s:%d is not allowed.", svc->inetd.name, ifname, svc->inetd.port);
if (svc->inetd.type == SOCK_STREAM)
close(stdin);
@@ -144,10 +143,19 @@ static void socket_cb(uev_t *UNUSED(w), void *arg, int UNUSED(events))
svc_t *svc = (svc_t *)arg, *task;
int stdin;
_d("Got event on %s socket ...", svc->cmd);
stdin = get_stdin(svc);
if (stdin < 0) {
FLOG_ERROR("%s: Unable to accept incoming connection",
svc->cmd);
FLOG_ERROR("%s: Unable to accept incoming connection", svc->cmd);
return;
}
/*
* Make sure to disable O_NONBLOCK on the descriptor before
* passing it to the inetd service, that's what is expected.
*/
if (fcntl(stdin, F_SETFL, fcntl(stdin, F_GETFL, 0) & ~O_NONBLOCK) < 0) {
FLOG_ERROR("Failed disabling non-blocking on %s socket", svc->cmd);
return;
}
@@ -158,22 +166,27 @@ static void socket_cb(uev_t *UNUSED(w), void *arg, int UNUSED(events))
return;
}
/* Copy inherited attributes from inetd */
task->runlevels = svc->runlevels;
task->inetd = svc->inetd;
memcpy(task->cond, svc->cond, sizeof(task->cond));
memcpy(task->username, svc->username, sizeof(task->username));
memcpy(task->group, svc->group, sizeof(task->group));
memcpy(task->args, svc->args, sizeof(task->args));
snprintf(task->desc, sizeof(task->desc), "%s Connection", svc->desc);
task->stdin_fd = stdin;
service_step(task);
if (!svc->inetd.forking) {
svc->block = SVC_BLOCK_INETD_BUSY;
service_step(svc);
}
/* Copy inherited attributes from inetd service's svc */
task->runlevels = svc->runlevels;
/* Only copy the most relevant parts of inetd, in particular we
* must *not* copy the watcher data to the clone! */
task->inetd.svc = svc;
task->inetd.type = svc->inetd.type;
memcpy(task->cond, svc->cond, sizeof(task->cond));
memcpy(task->username, svc->username, sizeof(task->username));
memcpy(task->group, svc->group, sizeof(task->group));
memcpy(task->args, svc->args, sizeof(task->args));
snprintf(task->desc, sizeof(task->desc), "%s connection", svc->desc);
task->stdin_fd = stdin;
service_step(task);
}
/* Launch Inet socket for service.
@@ -190,7 +203,7 @@ static int spawn_socket(inetd_t *inetd)
return -EINVAL;
}
_d("Spawning server socket for inetd %s ...", inetd->name);
_d("Spawning server socket for inetd %s, type %s ...", inetd->name, inetd->type == SOCK_STREAM ? "stream" : "dgram");
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);
@@ -215,7 +228,7 @@ static int spawn_socket(inetd_t *inetd)
if (inetd->port) {
if (inetd->type == SOCK_STREAM) {
if (-1 == listen(sd, 20)) {
if (-1 == listen(sd, 10)) {
FLOG_PERROR("Failed listening to inetd service %s", inetd->name);
close(sd);
return -errno;
@@ -232,19 +245,40 @@ static int spawn_socket(inetd_t *inetd)
int inetd_start(inetd_t *inetd)
{
if (inetd->watcher.fd == -1)
int sd;
char buf[BUFSIZ];
ssize_t len;
sd = inetd->watcher.fd;
if (sd == -1)
return spawn_socket(inetd);
return -EEXIST;
/* Read anything lingering, or clean up socket after failure */
len = recv(sd, buf, sizeof(buf), MSG_DONTWAIT);
_d("Read %d lingering bytes from socket before restarting %s ...", len, inetd->svc->cmd);
/* Restore O_NONBLOCK for socket */
fcntl(sd, F_SETFL, fcntl(sd, F_GETFL, 0) | O_NONBLOCK);
_d("Re-starting %s socket watcher ...", inetd->svc->cmd);
uev_io_start(&inetd->watcher);
return 0;
}
void inetd_stop(inetd_t *inetd)
{
if (inetd->watcher.fd != -1) {
_d("Stopping %s socket watcher ...", inetd->svc->cmd);
uev_io_stop(&inetd->watcher);
shutdown(inetd->watcher.fd, SHUT_RDWR);
close(inetd->watcher.fd);
inetd->watcher.fd = -1;
/* For dgram inetd services we block the parent SVC
* and halt the watcher, so don't close the socket! */
if (inetd->svc->block != SVC_BLOCK_INETD_BUSY) {
shutdown(inetd->watcher.fd, SHUT_RDWR);
close(inetd->watcher.fd);
inetd->watcher.fd = -1;
}
}
}
+1 -1
View File
@@ -128,7 +128,7 @@ static plugin_t plugin = {
PLUGIN_INIT(plugin_init)
{
pidfile_ctx.fd = inotify_init();
pidfile_ctx.fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (pidfile_ctx.fd < 0) {
_pe("inotify_init()");
return;
+3 -1
View File
@@ -97,7 +97,9 @@ svc_t *svc_new(char *cmd, int id, int type)
*/
int svc_del(svc_t *svc)
{
svc->type = SVC_TYPE_FREE;
/* Clear any old references and set SVC_TYPE_FREE */
memset(svc, 0, sizeof(*svc));
return 0;
}