1 #include "first.h" 2 3 #include "network.h" 4 #include "base.h" 5 #include "fdevent.h" 6 #include "log.h" 7 #include "connections.h" 8 #include "plugin.h" 9 #include "sock_addr.h" 10 11 #include "network_write.h" 12 #include "sys-socket.h" 13 14 #include <sys/types.h> 15 #include <sys/stat.h> 16 #include <sys/time.h> 17 18 #include <errno.h> 19 #include <fcntl.h> 20 #include <unistd.h> 21 #include <string.h> 22 #include <stdlib.h> 23 24 void 25 network_accept_tcp_nagle_disable (const int fd) 26 { 27 static int noinherit_tcpnodelay = -1; 28 int opt; 29 30 if (!noinherit_tcpnodelay) /* TCP_NODELAY inherited from listen socket */ 31 return; 32 33 if (noinherit_tcpnodelay < 0) { 34 socklen_t optlen = sizeof(opt); 35 if (0 == getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen)) { 36 noinherit_tcpnodelay = !opt; 37 if (opt) /* TCP_NODELAY inherited from listen socket */ 38 return; 39 } 40 } 41 42 opt = 1; 43 (void)setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); 44 } 45 46 static handler_t network_server_handle_fdevent(void *context, int revents) { 47 server_socket * const srv_socket = (server_socket *)context; 48 server * const srv = srv_socket->srv; 49 connection *con; 50 int loops; 51 52 if (0 == (revents & FDEVENT_IN)) { 53 log_error(srv->errh, __FILE__, __LINE__, 54 "strange event for server socket %d %d", srv_socket->fd, revents); 55 return HANDLER_ERROR; 56 } 57 58 /* accept()s at most 100 connections directly 59 * 60 * we jump out after 100 to give the waiting connections a chance */ 61 if (srv->conns.used >= srv->max_conns) return HANDLER_GO_ON; 62 loops = (int)(srv->max_conns - srv->conns.used + 1); 63 if (loops > 100) loops = 101; 64 65 while (--loops && NULL != (con = connection_accept(srv, srv_socket))) 66 connection_state_machine(con); 67 68 return HANDLER_GO_ON; 69 } 70 71 static void network_host_normalize_addr_str(buffer *host, sock_addr *addr) { 72 buffer_clear(host); 73 sock_addr_stringify_append_buffer(host, addr); 74 } 75 76 static int network_host_parse_addr(server *srv, sock_addr *addr, socklen_t *addr_len, buffer *host, int use_ipv6) { 77 char *h; 78 char *colon = NULL; 79 const char *chost; 80 sa_family_t family = use_ipv6 ? AF_INET6 : AF_INET; 81 unsigned int port = srv->srvconf.port; 82 if (buffer_string_is_empty(host)) { 83 log_error(srv->errh, __FILE__, __LINE__, 84 "value of $SERVER[\"socket\"] must not be empty"); 85 return -1; 86 } 87 h = host->ptr; 88 if (h[0] == '/') { 89 #ifdef HAVE_SYS_UN_H 90 return (1 == 91 sock_addr_from_str_hints(addr,addr_len,h,AF_UNIX,0,srv->errh)) 92 ? 0 93 : -1; 94 #else 95 log_error(srv, __FILE__, __LINE__, 96 "ERROR: Unix Domain sockets are not supported."); 97 return -1; 98 #endif 99 } 100 buffer * const tb = srv->tmp_buf; 101 buffer_copy_buffer(tb, host); 102 h = tb->ptr; 103 if (h[0] == '[') { 104 family = AF_INET6; 105 if ((h = strchr(h, ']'))) { 106 *h++ = '\0'; 107 if (*h == ':') colon = h; 108 } /*(else should not happen; validated in configparser.y)*/ 109 h = tb->ptr+1; 110 } 111 else { 112 colon = strrchr(h, ':'); 113 } 114 if (colon) { 115 *colon++ = '\0'; 116 port = (unsigned int)strtol(colon, NULL, 10); 117 if (port == 0 || port > 65535) { 118 log_error(srv->errh, __FILE__, __LINE__, 119 "port not set or out of range: %u", port); 120 return -1; 121 } 122 } 123 chost = *h ? h : family == AF_INET ? "0.0.0.0" : "::"; 124 if (1 != 125 sock_addr_from_str_hints(addr,addr_len,chost,family,port,srv->errh)) { 126 return -1; 127 } 128 return 0; 129 } 130 131 static void network_srv_sockets_append(server *srv, server_socket *srv_socket) { 132 if (srv->srv_sockets.used == srv->srv_sockets.size) { 133 srv->srv_sockets.size += 4; 134 srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket*)); 135 force_assert(NULL != srv->srv_sockets.ptr); 136 } 137 138 srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket; 139 } 140 141 typedef struct { 142 /* global or per-socket config; not patched per connection */ 143 int listen_backlog; 144 unsigned char ssl_enabled; 145 unsigned char use_ipv6; 146 unsigned char set_v6only; /* set_v6only is only a temporary option */ 147 unsigned char defer_accept; 148 const buffer *socket_perms; 149 const buffer *bsd_accept_filter; 150 } network_socket_config; 151 152 typedef struct { 153 PLUGIN_DATA; 154 network_socket_config defaults; 155 network_socket_config conf; 156 } network_plugin_data; 157 158 static void network_merge_config_cpv(network_socket_config * const pconf, const config_plugin_value_t * const cpv) { 159 switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */ 160 case 0: /* ssl.engine */ 161 pconf->ssl_enabled = (0 != cpv->v.u); 162 break; 163 case 1: /* server.listen-backlog */ 164 pconf->listen_backlog = (int)cpv->v.u; 165 break; 166 case 2: /* server.socket-perms */ 167 pconf->socket_perms = cpv->v.b; 168 break; 169 case 3: /* server.bsd-accept-filter */ 170 pconf->bsd_accept_filter = cpv->v.b; 171 break; 172 case 4: /* server.defer-accept */ 173 pconf->defer_accept = (0 != cpv->v.u); 174 break; 175 case 5: /* server.use-ipv6 */ 176 pconf->use_ipv6 = (0 != cpv->v.u); 177 break; 178 case 6: /* server.set-v6only */ 179 pconf->set_v6only = (0 != cpv->v.u); 180 break; 181 default:/* should not happen */ 182 return; 183 } 184 } 185 186 static void network_merge_config(network_socket_config * const pconf, const config_plugin_value_t *cpv) { 187 do { 188 network_merge_config_cpv(pconf, cpv); 189 } while ((++cpv)->k_id != -1); 190 } 191 192 static int network_server_init(server *srv, network_socket_config *s, buffer *host_token, size_t sidx, int stdin_fd) { 193 server_socket *srv_socket; 194 const char *host; 195 socklen_t addr_len = sizeof(sock_addr); 196 sock_addr addr; 197 int family = 0; 198 int set_v6only = 0; 199 200 if (buffer_string_is_empty(host_token)) { 201 log_error(srv->errh, __FILE__, __LINE__, 202 "value of $SERVER[\"socket\"] must not be empty"); 203 return -1; 204 } 205 206 /* check if we already know this socket, and if yes, don't init it 207 * (optimization: check strings here to filter out exact matches; 208 * binary addresses are matched further below) */ 209 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 210 if (buffer_is_equal(srv->srv_sockets.ptr[i]->srv_token, host_token)) { 211 return 0; 212 } 213 } 214 215 host = host_token->ptr; 216 if ((s->use_ipv6 && (*host == '\0' || *host == ':')) || (host[0] == '[' && host[1] == ']')) { 217 log_error(srv->errh, __FILE__, __LINE__, 218 "warning: please use server.use-ipv6 only for hostnames, " 219 "not without server.bind / empty address; your config will " 220 "break if the kernel default for IPV6_V6ONLY changes"); 221 } 222 if (*host == '[') s->use_ipv6 = 1; 223 224 memset(&addr, 0, sizeof(addr)); 225 if (-1 != stdin_fd) { 226 if (-1 == getsockname(stdin_fd, (struct sockaddr *)&addr, &addr_len)) { 227 log_perror(srv->errh, __FILE__, __LINE__, "getsockname()"); 228 return -1; 229 } 230 } else if (0 != network_host_parse_addr(srv, &addr, &addr_len, host_token, s->use_ipv6)) { 231 return -1; 232 } 233 234 family = sock_addr_get_family(&addr); 235 236 #ifdef HAVE_IPV6 237 if (*host != '\0' && AF_INET6 == family) { 238 if (s->set_v6only) { 239 set_v6only = 1; 240 } else { 241 log_error(srv->errh, __FILE__, __LINE__, 242 "warning: server.set-v6only will be removed soon, " 243 "update your config to have different sockets for ipv4 and ipv6"); 244 } 245 } 246 #endif 247 248 network_host_normalize_addr_str(host_token, &addr); 249 host = host_token->ptr; 250 251 if (srv->srvconf.preflight_check) { 252 return 0; 253 } 254 255 /* check if we already know this socket (after potential DNS resolution), and if yes, don't init it */ 256 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 257 if (0 == memcmp(&srv->srv_sockets.ptr[i]->addr, &addr, sizeof(addr))) { 258 return 0; 259 } 260 } 261 262 srv_socket = calloc(1, sizeof(*srv_socket)); 263 force_assert(NULL != srv_socket); 264 memcpy(&srv_socket->addr, &addr, addr_len); 265 srv_socket->fd = -1; 266 srv_socket->sidx = sidx; 267 srv_socket->is_ssl = s->ssl_enabled; 268 srv_socket->srv = srv; 269 srv_socket->srv_token = buffer_init_buffer(host_token); 270 271 network_srv_sockets_append(srv, srv_socket); 272 273 if (srv->sockets_disabled) { /* lighttpd -1 (one-shot mode) */ 274 return 0; 275 } 276 277 if (srv->srvconf.systemd_socket_activation) { 278 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 279 if (0 != memcmp(&srv->srv_sockets_inherited.ptr[i]->addr, &srv_socket->addr, addr_len)) continue; 280 if ((unsigned short)~0u == srv->srv_sockets_inherited.ptr[i]->sidx) { 281 srv->srv_sockets_inherited.ptr[i]->sidx = sidx; 282 } 283 stdin_fd = srv->srv_sockets_inherited.ptr[i]->fd; 284 break; 285 } 286 } 287 288 if (-1 != stdin_fd) { 289 srv_socket->fd = stdin_fd; 290 if (-1 == fdevent_fcntl_set_nb_cloexec(stdin_fd)) { 291 log_perror(srv->errh, __FILE__, __LINE__, "fcntl"); 292 return -1; 293 } 294 } else 295 #ifdef HAVE_SYS_UN_H 296 if (AF_UNIX == family) { 297 /* check if the socket exists and try to connect to it. */ 298 force_assert(host); /*(static analysis hint)*/ 299 if (-1 == (srv_socket->fd = fdevent_socket_cloexec(AF_UNIX, SOCK_STREAM, 0))) { 300 log_perror(srv->errh, __FILE__, __LINE__, "socket"); 301 return -1; 302 } 303 if (0 == connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { 304 log_error(srv->errh, __FILE__, __LINE__, 305 "server socket is still in use: %s", host); 306 return -1; 307 } 308 309 /* connect failed */ 310 switch(errno) { 311 case ECONNREFUSED: 312 unlink(host); 313 break; 314 case ENOENT: 315 break; 316 default: 317 log_perror(srv->errh, __FILE__, __LINE__, 318 "testing socket failed: %s", host); 319 return -1; 320 } 321 322 if (-1 == fdevent_fcntl_set_nb(srv_socket->fd)) { 323 log_perror(srv->errh, __FILE__, __LINE__, "fcntl"); 324 return -1; 325 } 326 } else 327 #endif 328 { 329 if (-1 == (srv_socket->fd = fdevent_socket_nb_cloexec(family, SOCK_STREAM, IPPROTO_TCP))) { 330 log_perror(srv->errh, __FILE__, __LINE__, "socket"); 331 return -1; 332 } 333 } 334 335 #ifdef HAVE_IPV6 336 if (set_v6only && -1 == stdin_fd) { 337 int val = 1; 338 if (-1 == setsockopt(srv_socket->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) { 339 log_perror(srv->errh, __FILE__, __LINE__, "setsockopt(IPV6_V6ONLY)"); 340 return -1; 341 } 342 } 343 #endif 344 345 /* */ 346 srv->cur_fds = srv_socket->fd; 347 348 if (fdevent_set_so_reuseaddr(srv_socket->fd, 1) < 0) { 349 log_perror(srv->errh, __FILE__, __LINE__, "setsockopt(SO_REUSEADDR)"); 350 return -1; 351 } 352 353 if (family != AF_UNIX) { 354 if (fdevent_set_tcp_nodelay(srv_socket->fd, 1) < 0) { 355 log_perror(srv->errh, __FILE__, __LINE__, "setsockopt(TCP_NODELAY)"); 356 return -1; 357 } 358 } 359 360 if (-1 != stdin_fd) { } else 361 if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { 362 log_perror(srv->errh, __FILE__, __LINE__, 363 "can't bind to socket: %s", host); 364 return -1; 365 } 366 367 if (-1 != stdin_fd) { } else 368 if (AF_UNIX == family && !buffer_string_is_empty(s->socket_perms)) { 369 mode_t m = 0; 370 for (char *str = s->socket_perms->ptr; *str; ++str) { 371 m <<= 3; 372 m |= (*str - '0'); 373 } 374 if (0 != m && -1 == chmod(host, m)) { 375 log_perror(srv->errh, __FILE__, __LINE__, 376 "chmod(\"%s\", %s)", host, s->socket_perms->ptr); 377 } 378 } 379 380 if (-1 != stdin_fd) { } else 381 if (-1 == listen(srv_socket->fd, s->listen_backlog)) { 382 log_perror(srv->errh, __FILE__, __LINE__, "listen"); 383 return -1; 384 } 385 386 if (s->ssl_enabled) { 387 #ifdef TCP_DEFER_ACCEPT 388 } else if (s->defer_accept) { 389 int v = s->defer_accept; 390 if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) { 391 log_perror(srv->errh, __FILE__, __LINE__, "can't set TCP_DEFER_ACCEPT"); 392 } 393 #endif 394 #if defined(__FreeBSD__) || defined(__NetBSD__) \ 395 || defined(__OpenBSD__) || defined(__DragonFly__) 396 } else if (!buffer_is_empty(s->bsd_accept_filter) 397 && (buffer_is_equal_string(s->bsd_accept_filter, CONST_STR_LEN("httpready")) 398 || buffer_is_equal_string(s->bsd_accept_filter, CONST_STR_LEN("dataready")))) { 399 #ifdef SO_ACCEPTFILTER 400 /* FreeBSD accf_http filter */ 401 struct accept_filter_arg afa; 402 memset(&afa, 0, sizeof(afa)); 403 strncpy(afa.af_name, s->bsd_accept_filter->ptr, sizeof(afa.af_name)); 404 if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) { 405 if (errno != ENOENT) { 406 log_perror(srv->errh, __FILE__, __LINE__, 407 "can't set accept-filter '%s'", s->bsd_accept_filter->ptr); 408 } 409 } 410 #endif 411 #endif 412 } 413 414 return 0; 415 } 416 417 int network_close(server *srv) { 418 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 419 server_socket *srv_socket = srv->srv_sockets.ptr[i]; 420 if (srv_socket->fd != -1) { 421 network_unregister_sock(srv, srv_socket); 422 close(srv_socket->fd); 423 } 424 425 buffer_free(srv_socket->srv_token); 426 427 free(srv_socket); 428 } 429 430 free(srv->srv_sockets.ptr); 431 srv->srv_sockets.ptr = NULL; 432 srv->srv_sockets.used = 0; 433 srv->srv_sockets.size = 0; 434 435 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 436 server_socket *srv_socket = srv->srv_sockets_inherited.ptr[i]; 437 if (srv_socket->fd != -1 && srv_socket->sidx != (unsigned short)~0u) { 438 close(srv_socket->fd); 439 } 440 441 buffer_free(srv_socket->srv_token); 442 443 free(srv_socket); 444 } 445 446 free(srv->srv_sockets_inherited.ptr); 447 srv->srv_sockets_inherited.ptr = NULL; 448 srv->srv_sockets_inherited.used = 0; 449 srv->srv_sockets_inherited.size = 0; 450 451 return 0; 452 } 453 454 static int network_socket_activation_nfds(server *srv, network_socket_config *s, int nfds) { 455 buffer *host = buffer_init(); 456 socklen_t addr_len; 457 sock_addr addr; 458 int rc = 0; 459 nfds += 3; /* #define SD_LISTEN_FDS_START 3 */ 460 for (int fd = 3; fd < nfds; ++fd) { 461 addr_len = sizeof(sock_addr); 462 if (-1 == (rc = getsockname(fd, (struct sockaddr *)&addr, &addr_len))) { 463 log_perror(srv->errh, __FILE__, __LINE__, 464 "socket activation getsockname()"); 465 break; 466 } 467 network_host_normalize_addr_str(host, &addr); 468 rc = network_server_init(srv, s, host, 0, fd); 469 if (0 != rc) break; 470 srv->srv_sockets.ptr[srv->srv_sockets.used-1]->sidx = (unsigned short)~0u; 471 } 472 buffer_free(host); 473 memcpy(&srv->srv_sockets_inherited, &srv->srv_sockets, sizeof(server_socket_array)); 474 memset(&srv->srv_sockets, 0, sizeof(server_socket_array)); 475 return rc; 476 } 477 478 static int network_socket_activation_from_env(server *srv, network_socket_config *s) { 479 char *listen_pid = getenv("LISTEN_PID"); 480 char *listen_fds = getenv("LISTEN_FDS"); 481 pid_t lpid = listen_pid ? (pid_t)strtoul(listen_pid,NULL,10) : 0; 482 int nfds = listen_fds ? atoi(listen_fds) : 0; 483 int rc = (lpid == getpid() && nfds > 0) 484 ? network_socket_activation_nfds(srv, s, nfds) 485 : 0; 486 unsetenv("LISTEN_PID"); 487 unsetenv("LISTEN_FDS"); 488 unsetenv("LISTEN_FDNAMES"); 489 /*(upon graceful restart, unsetenv will result in no-op above)*/ 490 return rc; 491 } 492 493 int network_init(server *srv, int stdin_fd) { 494 /*(network params used during setup (from $SERVER["socket"] condition))*/ 495 static const config_plugin_keys_t cpk[] = { 496 { CONST_STR_LEN("ssl.engine"), 497 T_CONFIG_BOOL, 498 T_CONFIG_SCOPE_CONNECTION } 499 ,{ CONST_STR_LEN("server.listen-backlog"), 500 T_CONFIG_INT, 501 T_CONFIG_SCOPE_CONNECTION } 502 ,{ CONST_STR_LEN("server.socket-perms"), 503 T_CONFIG_STRING, 504 T_CONFIG_SCOPE_CONNECTION } 505 ,{ CONST_STR_LEN("server.bsd-accept-filter"), 506 T_CONFIG_STRING, 507 T_CONFIG_SCOPE_CONNECTION } 508 ,{ CONST_STR_LEN("server.defer-accept"), 509 T_CONFIG_BOOL, 510 T_CONFIG_SCOPE_CONNECTION } 511 ,{ CONST_STR_LEN("server.use-ipv6"), 512 T_CONFIG_BOOL, 513 T_CONFIG_SCOPE_CONNECTION } 514 ,{ CONST_STR_LEN("server.set-v6only"), 515 T_CONFIG_BOOL, 516 T_CONFIG_SCOPE_CONNECTION } 517 ,{ NULL, 0, 518 T_CONFIG_UNSET, 519 T_CONFIG_SCOPE_UNSET } 520 }; 521 522 #ifdef __WIN32 523 WSADATA wsaData; 524 WORD wVersionRequested = MAKEWORD(2, 2); 525 if (0 != WSAStartup(wVersionRequested, &wsaData)) { 526 /* Tell the user that we could not find a usable WinSock DLL */ 527 return -1; 528 } 529 #endif 530 531 if (0 != network_write_init(srv)) return -1; 532 533 network_plugin_data np; 534 memset(&np, 0, sizeof(network_plugin_data)); 535 network_plugin_data *p = &np; 536 537 if (!config_plugin_values_init(srv, p, cpk, "network")) 538 return HANDLER_ERROR; 539 540 p->defaults.listen_backlog = 1024; 541 p->defaults.defer_accept = 0; 542 p->defaults.use_ipv6 = 0; 543 p->defaults.set_v6only = 1; 544 545 /* initialize p->defaults from global config context */ 546 if (p->nconfig > 0 && p->cvlist->v.u2[1]) { 547 const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0]; 548 if (-1 != cpv->k_id) 549 network_merge_config(&p->defaults, cpv); 550 } 551 552 int rc = 0; 553 do { 554 555 if (srv->srvconf.systemd_socket_activation) { 556 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 557 srv->srv_sockets_inherited.ptr[i]->sidx = (unsigned short)~0u; 558 } 559 rc = network_socket_activation_from_env(srv, &p->defaults); 560 if (0 != rc) break; 561 if (0 == srv->srv_sockets_inherited.used) { 562 srv->srvconf.systemd_socket_activation = 0; 563 } 564 } 565 566 /* process srv->srvconf.bindhost 567 * (skip if systemd socket activation is enabled and bindhost is empty; 568 * do not additionally listen on "*") */ 569 if (!srv->srvconf.systemd_socket_activation 570 || !buffer_string_is_empty(srv->srvconf.bindhost)) { 571 buffer *b = buffer_init(); 572 buffer_copy_buffer(b, srv->srvconf.bindhost); 573 if (b->ptr[0] != '/') { /*(skip adding port if unix socket path)*/ 574 buffer_append_string_len(b, CONST_STR_LEN(":")); 575 buffer_append_int(b, srv->srvconf.port); 576 } 577 578 rc = (-1 == stdin_fd || 0 == srv->srv_sockets.used) 579 ? network_server_init(srv, &p->defaults, b, 0, stdin_fd) 580 : close(stdin_fd);/*(graceful restart listening to "/dev/stdin")*/ 581 buffer_free(b); 582 if (0 != rc) break; 583 } 584 585 /* check for $SERVER["socket"] */ 586 for (uint32_t i = 1; i < srv->config_context->used; ++i) { 587 config_cond_info cfginfo; 588 config_get_config_cond_info(&cfginfo, i); 589 if (COMP_SERVER_SOCKET != cfginfo.comp) continue;/* not our stage */ 590 591 buffer *host_token; 592 *(const buffer **)&host_token = cfginfo.string; 593 /*(cfginfo.string is modified during config)*/ 594 595 memcpy(&p->conf, &p->defaults, sizeof(network_socket_config)); 596 for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) { 597 if ((int)i != p->cvlist[j].k_id) continue; 598 const config_plugin_value_t *cpv = 599 p->cvlist + p->cvlist[j].v.u2[0]; 600 network_merge_config(&p->conf, cpv); 601 break; 602 } 603 604 if (cfginfo.cond == CONFIG_COND_EQ) { 605 rc = network_server_init(srv, &p->conf, host_token, i, -1); 606 if (0 != rc) break; 607 } 608 else if (cfginfo.cond == CONFIG_COND_NE) { 609 socklen_t addr_len = sizeof(sock_addr); 610 sock_addr addr; 611 rc = network_host_parse_addr(srv, &addr, &addr_len, 612 host_token, p->conf.use_ipv6); 613 if (0 != rc) break; 614 network_host_normalize_addr_str(host_token, &addr); 615 } 616 } 617 if (0 != rc) break; 618 619 if (srv->srvconf.systemd_socket_activation) { 620 /* activate any inherited sockets not explicitly listed in config */ 621 server_socket *srv_socket; 622 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 623 if ((unsigned short)~0u 624 != srv->srv_sockets_inherited.ptr[i]->sidx) 625 continue; 626 srv->srv_sockets_inherited.ptr[i]->sidx = 0; 627 srv_socket = calloc(1, sizeof(server_socket)); 628 force_assert(NULL != srv_socket); 629 memcpy(srv_socket, srv->srv_sockets_inherited.ptr[i], 630 sizeof(server_socket)); 631 network_srv_sockets_append(srv, srv_socket); 632 } 633 } 634 635 } while (0); 636 637 free(p->cvlist); 638 return rc; 639 } 640 641 void network_unregister_sock(server *srv, server_socket *srv_socket) { 642 fdnode *fdn = srv_socket->fdn; 643 if (NULL == fdn) return; 644 fdevent_fdnode_event_del(srv->ev, fdn); 645 fdevent_unregister(srv->ev, fdn->fd); 646 srv_socket->fdn = NULL; 647 } 648 649 int network_register_fdevents(server *srv) { 650 if (-1 == fdevent_reset(srv->ev)) { 651 return -1; 652 } 653 654 if (srv->sockets_disabled) return 0; /* lighttpd -1 (one-shot mode) */ 655 656 /* register fdevents after reset */ 657 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 658 server_socket *srv_socket = srv->srv_sockets.ptr[i]; 659 660 srv_socket->fdn = fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket); 661 fdevent_fdnode_event_set(srv->ev, srv_socket->fdn, FDEVENT_IN); 662 } 663 return 0; 664 } 665