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