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