|
|
|
@ -219,6 +219,17 @@ static int network_server_init(server *srv, buffer *host_token, size_t sidx, int
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srv->srvconf.systemd_socket_activation) {
|
|
|
|
|
for (size_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
|
|
|
|
if (0 != memcmp(&srv->srv_sockets_inherited.ptr[i]->addr, &srv_socket->addr, addr_len)) continue;
|
|
|
|
|
if ((unsigned short)~0u == srv->srv_sockets_inherited.ptr[i]->sidx) {
|
|
|
|
|
srv->srv_sockets_inherited.ptr[i]->sidx = sidx;
|
|
|
|
|
}
|
|
|
|
|
stdin_fd = srv->srv_sockets_inherited.ptr[i]->fd;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (-1 != stdin_fd) {
|
|
|
|
|
srv_socket->fd = stdin_fd;
|
|
|
|
|
if (-1 == fdevent_fcntl_set_nb_cloexec(srv->ev, stdin_fd)) {
|
|
|
|
@ -367,12 +378,65 @@ int network_close(server *srv) {
|
|
|
|
|
srv->srv_sockets.used = 0;
|
|
|
|
|
srv->srv_sockets.size = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < srv->srv_sockets_inherited.used; i++) {
|
|
|
|
|
server_socket *srv_socket = srv->srv_sockets_inherited.ptr[i];
|
|
|
|
|
if (srv_socket->fd != -1 && srv_socket->sidx != (unsigned short)~0u) {
|
|
|
|
|
close(srv_socket->fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
buffer_free(srv_socket->srv_token);
|
|
|
|
|
|
|
|
|
|
free(srv_socket);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
free(srv->srv_sockets_inherited.ptr);
|
|
|
|
|
srv->srv_sockets_inherited.ptr = NULL;
|
|
|
|
|
srv->srv_sockets_inherited.used = 0;
|
|
|
|
|
srv->srv_sockets_inherited.size = 0;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int network_init(server *srv, int stdin_fd) {
|
|
|
|
|
size_t i;
|
|
|
|
|
static int network_socket_activation_nfds(server *srv, int nfds) {
|
|
|
|
|
buffer *host = buffer_init();
|
|
|
|
|
socklen_t addr_len;
|
|
|
|
|
sock_addr addr;
|
|
|
|
|
int rc = 0;
|
|
|
|
|
nfds += 3; /* #define SD_LISTEN_FDS_START 3 */
|
|
|
|
|
for (int fd = 3; fd < nfds; ++fd) {
|
|
|
|
|
addr_len = sizeof(sock_addr);
|
|
|
|
|
if (-1 == (rc = getsockname(fd, (struct sockaddr *)&addr, &addr_len))) {
|
|
|
|
|
log_error_write(srv, __FILE__, __LINE__, "ss",
|
|
|
|
|
"socket activation getsockname()", strerror(errno));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
network_host_normalize_addr_str(host, &addr);
|
|
|
|
|
rc = network_server_init(srv, host, 0, fd);
|
|
|
|
|
if (0 != rc) break;
|
|
|
|
|
srv->srv_sockets.ptr[srv->srv_sockets.used-1]->sidx = (unsigned short)~0u;
|
|
|
|
|
}
|
|
|
|
|
buffer_free(host);
|
|
|
|
|
memcpy(&srv->srv_sockets_inherited, &srv->srv_sockets, sizeof(server_socket_array));
|
|
|
|
|
memset(&srv->srv_sockets, 0, sizeof(server_socket_array));
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int network_socket_activation_from_env(server *srv) {
|
|
|
|
|
char *listen_pid = getenv("LISTEN_PID");
|
|
|
|
|
char *listen_fds = getenv("LISTEN_FDS");
|
|
|
|
|
pid_t lpid = listen_pid ? (pid_t)strtoul(listen_pid,NULL,10) : 0;
|
|
|
|
|
int nfds = listen_fds ? atoi(listen_fds) : 0;
|
|
|
|
|
int rc = (lpid == getpid() && nfds > 0)
|
|
|
|
|
? network_socket_activation_nfds(srv, nfds)
|
|
|
|
|
: 0;
|
|
|
|
|
unsetenv("LISTEN_PID");
|
|
|
|
|
unsetenv("LISTEN_FDS");
|
|
|
|
|
unsetenv("LISTEN_FDNAMES");
|
|
|
|
|
/*(upon graceful restart, unsetenv will result in no-op above)*/
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int network_init(server *srv, int stdin_fd) {
|
|
|
|
|
#ifdef __WIN32
|
|
|
|
|
WSADATA wsaData;
|
|
|
|
|
WORD wVersionRequested = MAKEWORD(2, 2);
|
|
|
|
@ -384,7 +448,19 @@ int network_init(server *srv, int stdin_fd) {
|
|
|
|
|
|
|
|
|
|
if (0 != network_write_init(srv)) return -1;
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
if (srv->srvconf.systemd_socket_activation) {
|
|
|
|
|
for (size_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
|
|
|
|
srv->srv_sockets_inherited.ptr[i]->sidx = (unsigned short)~0u;
|
|
|
|
|
}
|
|
|
|
|
if (0 != network_socket_activation_from_env(srv)) return -1;
|
|
|
|
|
if (0 == srv->srv_sockets_inherited.used) {
|
|
|
|
|
srv->srvconf.systemd_socket_activation = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* process srv->srvconf.bindhost
|
|
|
|
|
* (skip if systemd socket activation is enabled and bindhost is empty; do not additionally listen on "*") */
|
|
|
|
|
if (!srv->srvconf.systemd_socket_activation || !buffer_string_is_empty(srv->srvconf.bindhost)) {
|
|
|
|
|
int rc;
|
|
|
|
|
buffer *b = buffer_init();
|
|
|
|
|
buffer_copy_buffer(b, srv->srvconf.bindhost);
|
|
|
|
@ -401,7 +477,7 @@ int network_init(server *srv, int stdin_fd) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* check for $SERVER["socket"] */
|
|
|
|
|
for (i = 1; i < srv->config_context->used; i++) {
|
|
|
|
|
for (size_t i = 1; i < srv->config_context->used; ++i) {
|
|
|
|
|
data_config *dc = (data_config *)srv->config_context->data[i];
|
|
|
|
|
|
|
|
|
|
/* not our stage */
|
|
|
|
@ -422,6 +498,19 @@ int network_init(server *srv, int stdin_fd) {
|
|
|
|
|
if (0 != network_server_init(srv, dc->string, i, -1)) return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (srv->srvconf.systemd_socket_activation) {
|
|
|
|
|
/* activate any inherited sockets not explicitly listed in config file */
|
|
|
|
|
server_socket *srv_socket;
|
|
|
|
|
for (size_t i = 0; i < srv->srv_sockets_inherited.used; ++i) {
|
|
|
|
|
if ((unsigned short)~0u != srv->srv_sockets_inherited.ptr[i]->sidx) continue;
|
|
|
|
|
srv->srv_sockets_inherited.ptr[i]->sidx = 0;
|
|
|
|
|
srv_socket = calloc(1, sizeof(server_socket));
|
|
|
|
|
force_assert(NULL != srv_socket);
|
|
|
|
|
memcpy(srv_socket, srv->srv_sockets_inherited.ptr[i], sizeof(server_socket));
|
|
|
|
|
network_srv_sockets_append(srv, srv_socket);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|