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 const server_socket * const srv_socket = (server_socket *)context; 48 server * const srv = srv_socket->srv; 49 50 if (0 == (revents & FDEVENT_IN)) { 51 log_error(srv->errh, __FILE__, __LINE__, 52 "strange event for server socket %d %d", srv_socket->fd, revents); 53 return HANDLER_ERROR; 54 } 55 56 /* accept()s at most 100 new connections before 57 * jumping out to process events on other connections */ 58 int loops = (int)srv->lim_conns; 59 if (loops > 100) 60 loops = 100; 61 else if (loops <= 0) 62 return HANDLER_GO_ON; 63 64 const int nagle_disable = 65 (sock_addr_get_family(&srv_socket->addr) != AF_UNIX); 66 67 sock_addr addr; 68 size_t addrlen; /*(size_t intentional; not socklen_t)*/ 69 do { 70 addrlen = sizeof(addr); 71 int fd = fdevent_accept_listenfd(srv_socket->fd, 72 (struct sockaddr *)&addr, &addrlen); 73 if (-1 == fd) break; 74 75 if (nagle_disable) 76 network_accept_tcp_nagle_disable(fd); 77 78 connection *con = connection_accepted(srv, srv_socket, &addr, fd); 79 if (__builtin_expect( (!con), 0)) return HANDLER_GO_ON; 80 connection_state_machine(con); 81 } while (--loops); 82 83 if (loops) { 84 switch (errno) { 85 case EAGAIN: 86 #if EWOULDBLOCK != EAGAIN 87 case EWOULDBLOCK: 88 #endif 89 case EINTR: 90 case ECONNABORTED: 91 case EMFILE: 92 break; 93 default: 94 log_perror(srv->errh, __FILE__, __LINE__, "accept()"); 95 } 96 } 97 98 return HANDLER_GO_ON; 99 } 100 101 static void network_host_normalize_addr_str(buffer *host, sock_addr *addr) { 102 buffer_clear(host); 103 sock_addr_stringify_append_buffer(host, addr); 104 } 105 106 static int network_host_parse_addr(server *srv, sock_addr *addr, socklen_t *addr_len, buffer *host, int use_ipv6) { 107 char *h; 108 char *colon = NULL; 109 const char *chost; 110 sa_family_t family = use_ipv6 ? AF_INET6 : AF_INET; 111 unsigned int port = srv->srvconf.port; 112 if (buffer_is_blank(host)) { 113 log_error(srv->errh, __FILE__, __LINE__, 114 "value of $SERVER[\"socket\"] must not be empty"); 115 return -1; 116 } 117 h = host->ptr; 118 if (h[0] == '/') { 119 #ifdef HAVE_SYS_UN_H 120 return (1 == 121 sock_addr_from_str_hints(addr,addr_len,h,AF_UNIX,0,srv->errh)) 122 ? 0 123 : -1; 124 #else 125 log_error(srv, __FILE__, __LINE__, 126 "ERROR: Unix Domain sockets are not supported."); 127 return -1; 128 #endif 129 } 130 buffer * const tb = srv->tmp_buf; 131 buffer_copy_buffer(tb, host); 132 h = tb->ptr; 133 if (h[0] == '[') { 134 family = AF_INET6; 135 if ((h = strchr(h, ']'))) { 136 *h++ = '\0'; 137 if (*h == ':') colon = h; 138 } /*(else should not happen; validated in configparser.y)*/ 139 h = tb->ptr+1; 140 } 141 else { 142 colon = strrchr(h, ':'); 143 } 144 if (colon) { 145 *colon++ = '\0'; 146 port = (unsigned int)strtol(colon, NULL, 10); 147 if (port == 0 || port > 65535) { 148 log_error(srv->errh, __FILE__, __LINE__, 149 "port not set or out of range: %u", port); 150 return -1; 151 } 152 } 153 if (h[0] == '*' && h[1] == '\0') { 154 family = AF_INET; 155 ++h; 156 } 157 chost = *h ? h : family == AF_INET ? "0.0.0.0" : "::"; 158 if (1 != 159 sock_addr_from_str_hints(addr,addr_len,chost,family,port,srv->errh)) { 160 return -1; 161 } 162 return 0; 163 } 164 165 static void network_srv_sockets_append(server *srv, server_socket *srv_socket) { 166 if (srv->srv_sockets.used == srv->srv_sockets.size) { 167 srv->srv_sockets.size += 4; 168 srv->srv_sockets.ptr = realloc(srv->srv_sockets.ptr, srv->srv_sockets.size * sizeof(server_socket*)); 169 force_assert(NULL != srv->srv_sockets.ptr); 170 } 171 172 srv->srv_sockets.ptr[srv->srv_sockets.used++] = srv_socket; 173 } 174 175 typedef struct { 176 /* global or per-socket config; not patched per connection */ 177 int listen_backlog; 178 unsigned char ssl_enabled; 179 unsigned char use_ipv6; 180 unsigned char set_v6only; /* set_v6only is only a temporary option */ 181 unsigned char defer_accept; 182 int8_t v4mapped; 183 const buffer *socket_perms; 184 const buffer *bsd_accept_filter; 185 } network_socket_config; 186 187 typedef struct { 188 PLUGIN_DATA; 189 network_socket_config defaults; 190 network_socket_config conf; 191 } network_plugin_data; 192 193 static void network_merge_config_cpv(network_socket_config * const pconf, const config_plugin_value_t * const cpv) { 194 switch (cpv->k_id) { /* index into static config_plugin_keys_t cpk[] */ 195 case 0: /* ssl.engine */ 196 pconf->ssl_enabled = (0 != cpv->v.u); 197 break; 198 case 1: /* server.listen-backlog */ 199 pconf->listen_backlog = (int)cpv->v.u; 200 break; 201 case 2: /* server.socket-perms */ 202 pconf->socket_perms = cpv->v.b; 203 break; 204 case 3: /* server.bsd-accept-filter */ 205 pconf->bsd_accept_filter = cpv->v.b; 206 break; 207 case 4: /* server.defer-accept */ 208 pconf->defer_accept = (0 != cpv->v.u); 209 break; 210 case 5: /* server.use-ipv6 */ 211 pconf->use_ipv6 = (0 != cpv->v.u); 212 break; 213 case 6: /* server.set-v6only */ 214 pconf->set_v6only = (0 != cpv->v.u); 215 break; 216 case 7: /* server.v4mapped */ 217 pconf->v4mapped = (0 != cpv->v.u); 218 break; 219 default:/* should not happen */ 220 return; 221 } 222 } 223 224 static void network_merge_config(network_socket_config * const pconf, const config_plugin_value_t *cpv) { 225 do { 226 network_merge_config_cpv(pconf, cpv); 227 } while ((++cpv)->k_id != -1); 228 } 229 230 __attribute_pure__ 231 static uint8_t network_srv_token_colon (const buffer * const b) { 232 const char *colon = NULL; 233 const char * const p = b->ptr; 234 if (*p == '[') { 235 colon = strstr(p, "]:"); 236 if (colon) ++colon; 237 } 238 else if (*p != '/') { 239 colon = strchr(p, ':'); 240 } 241 return colon ? (uint8_t)(colon - p) : (uint8_t)buffer_clen(b); 242 } 243 244 static int network_server_init(server *srv, network_socket_config *s, buffer *host_token, size_t sidx, int stdin_fd) { 245 server_socket *srv_socket; 246 const char *host; 247 socklen_t addr_len = sizeof(sock_addr); 248 sock_addr addr; 249 int family = 0; 250 int set_v6only = 0; 251 252 if (buffer_is_blank(host_token)) { 253 log_error(srv->errh, __FILE__, __LINE__, 254 "value of $SERVER[\"socket\"] must not be empty"); 255 return -1; 256 } 257 258 /* check if we already know this socket, and if yes, don't init it 259 * (optimization: check strings here to filter out exact matches; 260 * binary addresses are matched further below) */ 261 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 262 if (buffer_is_equal(srv->srv_sockets.ptr[i]->srv_token, host_token)) { 263 return 0; 264 } 265 } 266 267 host = host_token->ptr; 268 if ((s->use_ipv6 && (*host == '\0' || *host == ':')) || (host[0] == '[' && host[1] == ']')) { 269 log_error(srv->errh, __FILE__, __LINE__, 270 "warning: please use server.use-ipv6 only for hostnames, " 271 "not without server.bind / empty address; your config will " 272 "break if the kernel default for IPV6_V6ONLY changes"); 273 } 274 if (*host == '[') s->use_ipv6 = 1; 275 276 memset(&addr, 0, sizeof(addr)); 277 if (-1 != stdin_fd) { 278 if (-1 == getsockname(stdin_fd, (struct sockaddr *)&addr, &addr_len)) { 279 log_perror(srv->errh, __FILE__, __LINE__, "getsockname()"); 280 return -1; 281 } 282 } else if (0 != network_host_parse_addr(srv, &addr, &addr_len, host_token, s->use_ipv6)) { 283 return -1; 284 } 285 286 family = sock_addr_get_family(&addr); 287 288 #ifdef HAVE_IPV6 289 if (*host != '\0' && AF_INET6 == family) { 290 if (s->set_v6only) { 291 set_v6only = 1; 292 } else { 293 log_error(srv->errh, __FILE__, __LINE__, 294 "warning: server.set-v6only will be removed soon, " 295 "update your config to have different sockets for ipv4 and ipv6"); 296 } 297 } 298 if (AF_INET6 == family && -1 != s->v4mapped) { /*(configured; -1 is unset)*/ 299 set_v6only = (s->v4mapped ? -1 : 1); 300 } 301 #endif 302 303 network_host_normalize_addr_str(host_token, &addr); 304 host = host_token->ptr; 305 306 if (srv->srvconf.preflight_check) { 307 return 0; 308 } 309 310 /* check if we already know this socket (after potential DNS resolution), and if yes, don't init it */ 311 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 312 if (0 == memcmp(&srv->srv_sockets.ptr[i]->addr, &addr, sizeof(addr))) { 313 return 0; 314 } 315 } 316 317 srv_socket = calloc(1, sizeof(*srv_socket)); 318 force_assert(NULL != srv_socket); 319 memcpy(&srv_socket->addr, &addr, addr_len); 320 srv_socket->fd = -1; 321 srv_socket->sidx = sidx; 322 srv_socket->is_ssl = s->ssl_enabled; 323 srv_socket->srv = srv; 324 srv_socket->srv_token = buffer_init_buffer(host_token); 325 srv_socket->srv_token_colon = 326 network_srv_token_colon(srv_socket->srv_token); 327 328 network_srv_sockets_append(srv, srv_socket); 329 330 if (srv->sockets_disabled) { /* lighttpd -1 (one-shot mode) */ 331 return 0; 332 } 333 334 if (srv->srvconf.systemd_socket_activation) { 335 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 336 if (0 != memcmp(&srv->srv_sockets_inherited.ptr[i]->addr, &srv_socket->addr, addr_len)) continue; 337 if ((unsigned short)~0u == srv->srv_sockets_inherited.ptr[i]->sidx) { 338 srv->srv_sockets_inherited.ptr[i]->sidx = sidx; 339 } 340 stdin_fd = srv->srv_sockets_inherited.ptr[i]->fd; 341 break; 342 } 343 } 344 345 if (-1 != stdin_fd) { 346 srv_socket->fd = stdin_fd; 347 if (-1 == fdevent_fcntl_set_nb_cloexec(stdin_fd)) { 348 log_perror(srv->errh, __FILE__, __LINE__, "fcntl"); 349 return -1; 350 } 351 } else 352 #ifdef HAVE_SYS_UN_H 353 if (AF_UNIX == family) { 354 /* check if the socket exists and try to connect to it. */ 355 force_assert(host); /*(static analysis hint)*/ 356 if (-1 == (srv_socket->fd = fdevent_socket_cloexec(AF_UNIX, SOCK_STREAM, 0))) { 357 log_perror(srv->errh, __FILE__, __LINE__, "socket"); 358 return -1; 359 } 360 if (0 == connect(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { 361 log_error(srv->errh, __FILE__, __LINE__, 362 "server socket is still in use: %s", host); 363 return -1; 364 } 365 366 /* connect failed */ 367 switch(errno) { 368 case ECONNREFUSED: 369 unlink(host); 370 break; 371 case ENOENT: 372 break; 373 default: 374 log_perror(srv->errh, __FILE__, __LINE__, 375 "testing socket failed: %s", host); 376 return -1; 377 } 378 379 if (-1 == fdevent_fcntl_set_nb(srv_socket->fd)) { 380 log_perror(srv->errh, __FILE__, __LINE__, "fcntl"); 381 return -1; 382 } 383 } else 384 #endif 385 { 386 if (-1 == (srv_socket->fd = fdevent_socket_nb_cloexec(family, SOCK_STREAM, IPPROTO_TCP))) { 387 log_perror(srv->errh, __FILE__, __LINE__, "socket"); 388 return -1; 389 } 390 391 #ifdef HAVE_IPV6 392 if (set_v6only) { 393 int val = (set_v6only > 0); 394 if (-1 == setsockopt(srv_socket->fd, IPPROTO_IPV6, IPV6_V6ONLY, &val, sizeof(val))) { 395 log_perror(srv->errh, __FILE__, __LINE__, "setsockopt(IPV6_V6ONLY)"); 396 return -1; 397 } 398 } 399 #endif 400 } 401 402 /* */ 403 srv->cur_fds = srv_socket->fd; 404 405 if (fdevent_set_so_reuseaddr(srv_socket->fd, 1) < 0) { 406 log_perror(srv->errh, __FILE__, __LINE__, "setsockopt(SO_REUSEADDR)"); 407 return -1; 408 } 409 410 if (family != AF_UNIX) { 411 if (fdevent_set_tcp_nodelay(srv_socket->fd, 1) < 0) { 412 log_perror(srv->errh, __FILE__, __LINE__, "setsockopt(TCP_NODELAY)"); 413 return -1; 414 } 415 } 416 417 if (-1 != stdin_fd) { } else 418 if (0 != bind(srv_socket->fd, (struct sockaddr *) &(srv_socket->addr), addr_len)) { 419 log_perror(srv->errh, __FILE__, __LINE__, 420 "can't bind to socket: %s", host); 421 return -1; 422 } 423 424 if (-1 != stdin_fd) { } else 425 if (AF_UNIX == family && s->socket_perms) { 426 mode_t m = 0; 427 for (char *str = s->socket_perms->ptr; *str; ++str) { 428 m <<= 3; 429 m |= (*str - '0'); 430 } 431 if (0 != m && -1 == chmod(host, m)) { 432 log_perror(srv->errh, __FILE__, __LINE__, 433 "chmod(\"%s\", %s)", host, s->socket_perms->ptr); 434 return -1; 435 } 436 } 437 438 if (-1 != stdin_fd) { } else 439 if (-1 == listen(srv_socket->fd, s->listen_backlog)) { 440 log_perror(srv->errh, __FILE__, __LINE__, "listen"); 441 return -1; 442 } 443 444 if (s->ssl_enabled) { 445 } 446 #ifdef TCP_DEFER_ACCEPT 447 else if (s->defer_accept) { 448 int v = s->defer_accept; 449 if (-1 == setsockopt(srv_socket->fd, IPPROTO_TCP, TCP_DEFER_ACCEPT, &v, sizeof(v))) { 450 log_perror(srv->errh, __FILE__, __LINE__, "can't set TCP_DEFER_ACCEPT"); 451 } 452 } 453 #endif 454 #if defined(__FreeBSD__) || defined(__NetBSD__) \ 455 || defined(__OpenBSD__) || defined(__DragonFly__) 456 #ifdef SO_ACCEPTFILTER 457 else if (s->bsd_accept_filter 458 && (buffer_is_equal_string(s->bsd_accept_filter, CONST_STR_LEN("httpready")) 459 || buffer_is_equal_string(s->bsd_accept_filter, CONST_STR_LEN("dataready")))) { 460 /* FreeBSD accf_http filter */ 461 struct accept_filter_arg afa; 462 memset(&afa, 0, sizeof(afa)); 463 strncpy(afa.af_name, s->bsd_accept_filter->ptr, sizeof(afa.af_name)-1); 464 if (setsockopt(srv_socket->fd, SOL_SOCKET, SO_ACCEPTFILTER, &afa, sizeof(afa)) < 0) { 465 if (errno != ENOENT) { 466 log_perror(srv->errh, __FILE__, __LINE__, 467 "can't set accept-filter '%s'", s->bsd_accept_filter->ptr); 468 } 469 } 470 } 471 #endif 472 #endif 473 474 return 0; 475 } 476 477 int network_close(server *srv) { 478 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 479 server_socket *srv_socket = srv->srv_sockets.ptr[i]; 480 if (srv_socket->fd != -1) { 481 network_unregister_sock(srv, srv_socket); 482 close(srv_socket->fd); 483 } 484 485 buffer_free(srv_socket->srv_token); 486 487 free(srv_socket); 488 } 489 490 free(srv->srv_sockets.ptr); 491 srv->srv_sockets.ptr = NULL; 492 srv->srv_sockets.used = 0; 493 srv->srv_sockets.size = 0; 494 495 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 496 server_socket *srv_socket = srv->srv_sockets_inherited.ptr[i]; 497 if (srv_socket->fd != -1 && srv_socket->sidx != (unsigned short)~0u) { 498 close(srv_socket->fd); 499 } 500 501 buffer_free(srv_socket->srv_token); 502 503 free(srv_socket); 504 } 505 506 free(srv->srv_sockets_inherited.ptr); 507 srv->srv_sockets_inherited.ptr = NULL; 508 srv->srv_sockets_inherited.used = 0; 509 srv->srv_sockets_inherited.size = 0; 510 511 return 0; 512 } 513 514 void network_socket_activation_to_env (server * const srv) { 515 /* set up listening sockets for systemd socket activation 516 * and ensure FD_CLOEXEC flag is not set on listen fds */ 517 int fd = 3; /* #define SD_LISTEN_FDS_START 3 */ 518 for (uint32_t n = 0, i; n < srv->srv_sockets.used; ++n) { 519 server_socket *srv_socket = srv->srv_sockets.ptr[n]; 520 if (srv_socket->fd < fd) continue; 521 if (srv_socket->fd == fd) { 522 fdevent_clrfd_cloexec(fd); 523 ++fd; 524 continue; 525 } 526 /* (expecting ordered list, but check if fd is later in list)*/ 527 for (i = n+1; i < srv->srv_sockets.used; ++i) { 528 if (fd == srv->srv_sockets.ptr[i]->fd) 529 break; 530 } 531 if (i < srv->srv_sockets.used) { 532 fdevent_clrfd_cloexec(fd); 533 ++fd; 534 --n; /* loop to reprocess this entry */ 535 continue; 536 } 537 538 /* dup2() removes FD_CLOEXEC on newfd */ 539 if (fd != dup2(srv_socket->fd, fd)) continue; 540 ++fd; 541 /* old fd will be closed upon execv() due to its FD_CLOEXEC flag 542 * (if not already closed by another dup2() over it) */ 543 } 544 fd -= 3; /* now num fds; #define SD_LISTEN_FDS_START 3 */ 545 if (0 == fd) return; /*(no active sockets?)*/ 546 buffer * const tb = srv->tmp_buf; 547 buffer_clear(tb); 548 buffer_append_int(tb, fd); 549 setenv("LISTEN_FDS", tb->ptr, 1); 550 buffer_clear(tb); 551 buffer_append_int(tb, srv->pid); /* getpid() */ 552 setenv("LISTEN_PID", tb->ptr, 1); 553 } 554 555 static int network_socket_activation_nfds(server *srv, network_socket_config *s, int nfds) { 556 buffer *host = buffer_init(); 557 socklen_t addr_len; 558 sock_addr addr; 559 int rc = 0; 560 nfds += 3; /* #define SD_LISTEN_FDS_START 3 */ 561 for (int fd = 3; fd < nfds; ++fd) { 562 addr_len = sizeof(sock_addr); 563 if (-1 == (rc = getsockname(fd, (struct sockaddr *)&addr, &addr_len))) { 564 log_perror(srv->errh, __FILE__, __LINE__, 565 "socket activation getsockname()"); 566 break; 567 } 568 network_host_normalize_addr_str(host, &addr); 569 rc = network_server_init(srv, s, host, 0, fd); 570 if (0 != rc) break; 571 srv->srv_sockets.ptr[srv->srv_sockets.used-1]->sidx = (unsigned short)~0u; 572 } 573 buffer_free(host); 574 memcpy(&srv->srv_sockets_inherited, &srv->srv_sockets, sizeof(server_socket_array)); 575 memset(&srv->srv_sockets, 0, sizeof(server_socket_array)); 576 return rc; 577 } 578 579 static int network_socket_activation_from_env(server *srv, network_socket_config *s) { 580 char *listen_pid = getenv("LISTEN_PID"); 581 char *listen_fds = getenv("LISTEN_FDS"); 582 pid_t lpid = listen_pid ? (pid_t)strtoul(listen_pid,NULL,10) : 0; 583 int nfds = listen_fds ? atoi(listen_fds) : 0; 584 int rc = (lpid == getpid() && nfds > 0 && nfds < 5000) 585 ? network_socket_activation_nfds(srv, s, nfds) 586 : 0; 587 unsetenv("LISTEN_PID"); 588 unsetenv("LISTEN_FDS"); 589 unsetenv("LISTEN_FDNAMES"); 590 /*(upon graceful restart, unsetenv will result in no-op above)*/ 591 return rc; 592 } 593 594 int network_init(server *srv, int stdin_fd) { 595 /*(network params used during setup (from $SERVER["socket"] condition))*/ 596 static const config_plugin_keys_t cpk[] = { 597 { CONST_STR_LEN("ssl.engine"), 598 T_CONFIG_BOOL, 599 T_CONFIG_SCOPE_CONNECTION } 600 ,{ CONST_STR_LEN("server.listen-backlog"), 601 T_CONFIG_INT, 602 T_CONFIG_SCOPE_CONNECTION } 603 ,{ CONST_STR_LEN("server.socket-perms"), 604 T_CONFIG_STRING, 605 T_CONFIG_SCOPE_CONNECTION } 606 ,{ CONST_STR_LEN("server.bsd-accept-filter"), 607 T_CONFIG_STRING, 608 T_CONFIG_SCOPE_CONNECTION } 609 ,{ CONST_STR_LEN("server.defer-accept"), 610 T_CONFIG_BOOL, 611 T_CONFIG_SCOPE_CONNECTION } 612 ,{ CONST_STR_LEN("server.use-ipv6"), 613 T_CONFIG_BOOL, 614 T_CONFIG_SCOPE_CONNECTION } 615 ,{ CONST_STR_LEN("server.set-v6only"), 616 T_CONFIG_BOOL, 617 T_CONFIG_SCOPE_CONNECTION } 618 ,{ CONST_STR_LEN("server.v4mapped"), 619 T_CONFIG_BOOL, 620 T_CONFIG_SCOPE_CONNECTION } 621 #if 0 /* TODO: more integration needed ... */ 622 ,{ CONST_STR_LEN("mbedtls.engine"), 623 T_CONFIG_BOOL, 624 T_CONFIG_SCOPE_CONNECTION } 625 #endif 626 ,{ NULL, 0, 627 T_CONFIG_UNSET, 628 T_CONFIG_SCOPE_UNSET } 629 }; 630 631 #ifdef __WIN32 632 WSADATA wsaData; 633 WORD wVersionRequested = MAKEWORD(2, 2); 634 if (0 != WSAStartup(wVersionRequested, &wsaData)) { 635 /* Tell the user that we could not find a usable WinSock DLL */ 636 return -1; 637 } 638 #endif 639 640 if (0 != network_write_init(srv)) return -1; 641 642 network_plugin_data np; 643 memset(&np, 0, sizeof(network_plugin_data)); 644 network_plugin_data *p = &np; 645 646 if (!config_plugin_values_init(srv, p, cpk, "network")) 647 return HANDLER_ERROR; 648 649 p->defaults.listen_backlog = 1024; 650 p->defaults.defer_accept = 0; 651 p->defaults.use_ipv6 = 0; 652 p->defaults.set_v6only = 1; 653 p->defaults.v4mapped = -1; /*(-1 for unset; not 0 or 1)*/ 654 655 /* initialize p->defaults from global config context */ 656 if (p->nconfig > 0 && p->cvlist->v.u2[1]) { 657 const config_plugin_value_t *cpv = p->cvlist + p->cvlist->v.u2[0]; 658 if (-1 != cpv->k_id) 659 network_merge_config(&p->defaults, cpv); 660 } 661 662 int rc = 0; 663 do { 664 665 if (srv->srvconf.systemd_socket_activation) { 666 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 667 srv->srv_sockets_inherited.ptr[i]->sidx = (unsigned short)~0u; 668 } 669 rc = network_socket_activation_from_env(srv, &p->defaults); 670 if (0 != rc) break; 671 if (0 == srv->srv_sockets_inherited.used) { 672 srv->srvconf.systemd_socket_activation = 0; 673 } 674 } 675 676 /* special-case srv->srvconf.bindhost = "/dev/stdin" (see server.c) */ 677 if (-1 != stdin_fd) { 678 buffer *b = buffer_init(); 679 buffer_copy_buffer(b, srv->srvconf.bindhost); 680 /*assert(buffer_eq_slen(b, CONST_STR_LEN("/dev/stdin")));*/ 681 rc = (0 == srv->srv_sockets.used) 682 ? network_server_init(srv, &p->defaults, b, 0, stdin_fd) 683 : close(stdin_fd);/*(graceful restart listening to "/dev/stdin")*/ 684 buffer_free(b); 685 if (0 != rc) break; 686 } 687 688 /* check for $SERVER["socket"] */ 689 for (uint32_t i = 1; i < srv->config_context->used; ++i) { 690 config_cond_info cfginfo; 691 config_get_config_cond_info(&cfginfo, i); 692 if (COMP_SERVER_SOCKET != cfginfo.comp) continue;/* not our stage */ 693 694 buffer *host_token; 695 *(const buffer **)&host_token = cfginfo.string; 696 /*(cfginfo.string is modified during config)*/ 697 698 memcpy(&p->conf, &p->defaults, sizeof(network_socket_config)); 699 for (int j = !p->cvlist[0].v.u2[1]; j < p->nconfig; ++j) { 700 if ((int)i != p->cvlist[j].k_id) continue; 701 const config_plugin_value_t *cpv = 702 p->cvlist + p->cvlist[j].v.u2[0]; 703 network_merge_config(&p->conf, cpv); 704 break; 705 } 706 707 if (cfginfo.cond == CONFIG_COND_EQ) { 708 rc = network_server_init(srv, &p->conf, host_token, i, -1); 709 if (0 != rc) break; 710 } 711 else if (cfginfo.cond == CONFIG_COND_NE) { 712 socklen_t addr_len = sizeof(sock_addr); 713 sock_addr addr; 714 rc = network_host_parse_addr(srv, &addr, &addr_len, 715 host_token, p->conf.use_ipv6); 716 if (0 != rc) break; 717 network_host_normalize_addr_str(host_token, &addr); 718 } 719 } 720 if (0 != rc) break; 721 722 /* process srv->srvconf.bindhost 723 * init global config for server.bindhost and server.port after 724 * initializing $SERVER["socket"] so that if bindhost and port match 725 * another $SERVER["socket"], the $SERVER["socket"] config is used, 726 * as the $SERVER["socket"] config inherits from the global scope and 727 * can then be overridden. (bindhost = "/dev/stdin" is handled above) 728 * (skip if systemd socket activation is enabled and bindhost is empty; 729 * do not additionally listen on "*") */ 730 if ((!srv->srvconf.systemd_socket_activation || srv->srvconf.bindhost) 731 && -1 == stdin_fd) { 732 buffer *b = buffer_init(); 733 if (srv->srvconf.bindhost) 734 buffer_copy_buffer(b, srv->srvconf.bindhost); 735 /*(skip adding port if unix socket path)*/ 736 if (!b->ptr || b->ptr[0] != '/') { 737 buffer_append_string_len(b, CONST_STR_LEN(":")); 738 buffer_append_int(b, srv->srvconf.port); 739 } 740 #ifdef __COVERITY__ 741 force_assert(b->ptr); 742 #endif 743 744 rc = network_server_init(srv, &p->defaults, b, 0, -1); 745 buffer_free(b); 746 if (0 != rc) break; 747 } 748 749 if (srv->srvconf.systemd_socket_activation) { 750 /* activate any inherited sockets not explicitly listed in config */ 751 server_socket *srv_socket; 752 for (uint32_t i = 0; i < srv->srv_sockets_inherited.used; ++i) { 753 if ((unsigned short)~0u 754 != srv->srv_sockets_inherited.ptr[i]->sidx) 755 continue; 756 srv->srv_sockets_inherited.ptr[i]->sidx = 0; 757 srv_socket = calloc(1, sizeof(server_socket)); 758 force_assert(NULL != srv_socket); 759 memcpy(srv_socket, srv->srv_sockets_inherited.ptr[i], 760 sizeof(server_socket)); 761 srv_socket->srv_token = 762 buffer_init_buffer(srv_socket->srv_token); 763 srv_socket->srv_token_colon = 764 network_srv_token_colon(srv_socket->srv_token); 765 network_srv_sockets_append(srv, srv_socket); 766 } 767 } 768 769 } while (0); 770 771 free(p->cvlist); 772 return rc; 773 } 774 775 void network_unregister_sock(server *srv, server_socket *srv_socket) { 776 fdnode *fdn = srv_socket->fdn; 777 if (NULL == fdn) return; 778 fdevent_fdnode_event_del(srv->ev, fdn); 779 fdevent_unregister(srv->ev, fdn->fd); 780 srv_socket->fdn = NULL; 781 } 782 783 int network_register_fdevents(server *srv) { 784 if (-1 == fdevent_reset(srv->ev)) { 785 return -1; 786 } 787 788 if (srv->sockets_disabled) return 0; /* lighttpd -1 (one-shot mode) */ 789 790 /* register fdevents after reset */ 791 for (uint32_t i = 0; i < srv->srv_sockets.used; ++i) { 792 server_socket *srv_socket = srv->srv_sockets.ptr[i]; 793 794 srv_socket->fdn = fdevent_register(srv->ev, srv_socket->fd, network_server_handle_fdevent, srv_socket); 795 fdevent_fdnode_event_set(srv->ev, srv_socket->fdn, FDEVENT_IN); 796 } 797 return 0; 798 } 799