7 #include "connections.h"
8 #include "configfile.h"
11 #include "network_write.h"
12 #include "sys-socket.h"
14 #include <sys/types.h>
25 network_accept_tcp_nagle_disable (const int fd
)
27 static int noinherit_tcpnodelay
= -1;
30 if (!noinherit_tcpnodelay
) /* TCP_NODELAY inherited from listen socket */
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 */
43 (void)setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &opt
, sizeof(opt
));
46 static handler_t
network_server_handle_fdevent(server
*srv
, void *context
, int revents
) {
47 server_socket
*srv_socket
= (server_socket
*)context
;
53 if (0 == (revents
& FDEVENT_IN
)) {
54 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
55 "strange event for server socket",
61 /* accept()s at most 100 connections directly
63 * we jump out after 100 to give the waiting connections a chance */
64 if (srv
->conns
->used
>= srv
->max_conns
) return HANDLER_GO_ON
;
65 loops
= (int)(srv
->max_conns
- srv
->conns
->used
+ 1);
66 if (loops
> 100) loops
= 101;
68 while (--loops
&& NULL
!= (con
= connection_accept(srv
, srv_socket
)))
69 connection_state_machine(srv
, con
);
74 static void network_host_normalize_addr_str(buffer
*host
, sock_addr
*addr
) {
76 sock_addr_stringify_append_buffer(host
, addr
);
79 static int network_host_parse_addr(server
*srv
, sock_addr
*addr
, socklen_t
*addr_len
, buffer
*host
, int use_ipv6
) {
83 sa_family_t family
= use_ipv6
? AF_INET6
: AF_INET
;
84 unsigned int port
= srv
->srvconf
.port
;
85 if (buffer_string_is_empty(host
)) {
86 log_error_write(srv
, __FILE__
, __LINE__
, "s", "value of $SERVER[\"socket\"] must not be empty");
92 return (1 == sock_addr_from_str_hints(srv
,addr
,addr_len
,h
,AF_UNIX
,0))
96 log_error_write(srv
, __FILE__
, __LINE__
, "s",
97 "ERROR: Unix Domain sockets are not supported.");
101 buffer_copy_buffer(srv
->tmp_buf
, host
);
102 h
= srv
->tmp_buf
->ptr
;
105 if ((h
= strchr(h
, ']'))) {
107 if (*h
== ':') colon
= h
;
108 } /*(else should not happen; validated in configparser.y)*/
109 h
= srv
->tmp_buf
->ptr
+1;
112 colon
= strrchr(h
, ':');
116 port
= strtol(colon
, NULL
, 10);
117 if (port
== 0 || port
> 65535) {
118 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
119 "port not set or out of range:", port
);
123 chost
= *h
? h
: family
== AF_INET
? "0.0.0.0" : "::";
124 if (1 != sock_addr_from_str_hints(srv
,addr
,addr_len
,chost
,family
,port
)) {
130 static void network_srv_sockets_append(server
*srv
, server_socket
*srv_socket
) {
131 if (srv
->srv_sockets
.used
== srv
->srv_sockets
.size
) {
132 srv
->srv_sockets
.size
+= 4;
133 srv
->srv_sockets
.ptr
= realloc(srv
->srv_sockets
.ptr
, srv
->srv_sockets
.size
* sizeof(server_socket
*));
134 force_assert(NULL
!= srv
->srv_sockets
.ptr
);
137 srv
->srv_sockets
.ptr
[srv
->srv_sockets
.used
++] = srv_socket
;
140 static int network_server_init(server
*srv
, buffer
*host_token
, size_t sidx
, int stdin_fd
) {
141 server_socket
*srv_socket
;
143 specific_config
*s
= srv
->config_storage
[sidx
];
144 socklen_t addr_len
= sizeof(sock_addr
);
149 if (buffer_string_is_empty(host_token
)) {
150 log_error_write(srv
, __FILE__
, __LINE__
, "s", "value of $SERVER[\"socket\"] must not be empty");
154 /* check if we already know this socket, and if yes, don't init it
155 * (optimization: check strings here to filter out exact matches;
156 * binary addresses are matched further below) */
157 for (size_t i
= 0; i
< srv
->srv_sockets
.used
; ++i
) {
158 if (buffer_is_equal(srv
->srv_sockets
.ptr
[i
]->srv_token
, host_token
)) {
159 buffer_copy_buffer(host_token
, srv
->srv_sockets
.ptr
[i
]->srv_token
);
164 host
= host_token
->ptr
;
165 if ((s
->use_ipv6
&& (*host
== '\0' || *host
== ':')) || (host
[0] == '[' && host
[1] == ']')) {
166 log_error_write(srv
, __FILE__
, __LINE__
, "s", "warning: please use server.use-ipv6 only for hostnames, not without server.bind / empty address; your config will break if the kernel default for IPV6_V6ONLY changes");
168 if (*host
== '[') s
->use_ipv6
= 1;
170 memset(&addr
, 0, sizeof(addr
));
171 if (-1 != stdin_fd
) {
172 if (-1 == getsockname(stdin_fd
, (struct sockaddr
*)&addr
, &addr_len
)) {
173 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
174 "getsockname()", strerror(errno
));
177 } else if (0 != network_host_parse_addr(srv
, &addr
, &addr_len
, host_token
, s
->use_ipv6
)) {
181 family
= sock_addr_get_family(&addr
);
184 if (*host
!= '\0' && AF_INET6
== family
) {
188 log_error_write(srv
, __FILE__
, __LINE__
, "s", "warning: server.set-v6only will be removed soon, update your config to have different sockets for ipv4 and ipv6");
193 network_host_normalize_addr_str(host_token
, &addr
);
194 host
= host_token
->ptr
;
196 if (srv
->srvconf
.preflight_check
) {
200 /* check if we already know this socket (after potential DNS resolution), and if yes, don't init it */
201 for (size_t i
= 0; i
< srv
->srv_sockets
.used
; ++i
) {
202 if (0 == memcmp(&srv
->srv_sockets
.ptr
[i
]->addr
, &addr
, sizeof(addr
))) {
207 srv_socket
= calloc(1, sizeof(*srv_socket
));
208 force_assert(NULL
!= srv_socket
);
209 memcpy(&srv_socket
->addr
, &addr
, addr_len
);
211 srv_socket
->sidx
= sidx
;
212 srv_socket
->is_ssl
= s
->ssl_enabled
;
213 srv_socket
->srv_token
= buffer_init_buffer(host_token
);
215 network_srv_sockets_append(srv
, srv_socket
);
217 if (srv
->sockets_disabled
) { /* lighttpd -1 (one-shot mode) */
221 if (srv
->srvconf
.systemd_socket_activation
) {
222 for (size_t i
= 0; i
< srv
->srv_sockets_inherited
.used
; ++i
) {
223 if (0 != memcmp(&srv
->srv_sockets_inherited
.ptr
[i
]->addr
, &srv_socket
->addr
, addr_len
)) continue;
224 if ((unsigned short)~0u == srv
->srv_sockets_inherited
.ptr
[i
]->sidx
) {
225 srv
->srv_sockets_inherited
.ptr
[i
]->sidx
= sidx
;
227 stdin_fd
= srv
->srv_sockets_inherited
.ptr
[i
]->fd
;
232 if (-1 != stdin_fd
) {
233 srv_socket
->fd
= stdin_fd
;
234 if (-1 == fdevent_fcntl_set_nb_cloexec(srv
->ev
, stdin_fd
)) {
235 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "fcntl:", strerror(errno
));
240 if (AF_UNIX
== family
) {
241 /* check if the socket exists and try to connect to it. */
242 force_assert(host
); /*(static analysis hint)*/
243 if (-1 == (srv_socket
->fd
= fdevent_socket_cloexec(AF_UNIX
, SOCK_STREAM
, 0))) {
244 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "socket failed:", strerror(errno
));
247 if (0 == connect(srv_socket
->fd
, (struct sockaddr
*) &(srv_socket
->addr
), addr_len
)) {
248 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
249 "server socket is still in use:",
264 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
265 "testing socket failed:",
266 host
, strerror(errno
));
271 if (-1 == fdevent_fcntl_set_nb(srv
->ev
, srv_socket
->fd
)) {
272 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "fcntl:", strerror(errno
));
278 if (-1 == (srv_socket
->fd
= fdevent_socket_nb_cloexec(family
, SOCK_STREAM
, IPPROTO_TCP
))) {
279 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "socket failed:", strerror(errno
));
285 if (set_v6only
&& -1 == stdin_fd
) {
287 if (-1 == setsockopt(srv_socket
->fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
))) {
288 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(IPV6_V6ONLY) failed:", strerror(errno
));
295 srv
->cur_fds
= srv_socket
->fd
;
297 if (fdevent_set_so_reuseaddr(srv_socket
->fd
, 1) < 0) {
298 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(SO_REUSEADDR) failed:", strerror(errno
));
302 if (family
!= AF_UNIX
) {
303 if (fdevent_set_tcp_nodelay(srv_socket
->fd
, 1) < 0) {
304 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(TCP_NODELAY) failed:", strerror(errno
));
309 if (-1 != stdin_fd
) { } else
310 if (0 != bind(srv_socket
->fd
, (struct sockaddr
*) &(srv_socket
->addr
), addr_len
)) {
311 log_error_write(srv
, __FILE__
, __LINE__
, "sss",
312 "can't bind to socket:", host
, strerror(errno
));
316 if (-1 != stdin_fd
) { } else
317 if (AF_UNIX
== family
&& !buffer_string_is_empty(s
->socket_perms
)) {
319 for (char *str
= s
->socket_perms
->ptr
; *str
; ++str
) {
323 if (0 != m
&& -1 == chmod(host
, m
)) {
324 log_error_write(srv
, __FILE__
, __LINE__
, "sssbss", "chmod(\"", host
, "\", ", s
->socket_perms
, "):", strerror(errno
));
328 if (-1 != stdin_fd
) { } else
329 if (-1 == listen(srv_socket
->fd
, s
->listen_backlog
)) {
330 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "listen failed: ", strerror(errno
));
334 if (s
->ssl_enabled
) {
335 #ifdef TCP_DEFER_ACCEPT
336 } else if (s
->defer_accept
) {
337 int v
= s
->defer_accept
;
338 if (-1 == setsockopt(srv_socket
->fd
, IPPROTO_TCP
, TCP_DEFER_ACCEPT
, &v
, sizeof(v
))) {
339 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno
));
342 #if defined(__FreeBSD__) || defined(__NetBSD__) \
343 || defined(__OpenBSD__) || defined(__DragonFly__)
344 } else if (!buffer_is_empty(s
->bsd_accept_filter
)
345 && (buffer_is_equal_string(s
->bsd_accept_filter
, CONST_STR_LEN("httpready"))
346 || buffer_is_equal_string(s
->bsd_accept_filter
, CONST_STR_LEN("dataready")))) {
347 #ifdef SO_ACCEPTFILTER
348 /* FreeBSD accf_http filter */
349 struct accept_filter_arg afa
;
350 memset(&afa
, 0, sizeof(afa
));
351 strncpy(afa
.af_name
, s
->bsd_accept_filter
->ptr
, sizeof(afa
.af_name
));
352 if (setsockopt(srv_socket
->fd
, SOL_SOCKET
, SO_ACCEPTFILTER
, &afa
, sizeof(afa
)) < 0) {
353 if (errno
!= ENOENT
) {
354 log_error_write(srv
, __FILE__
, __LINE__
, "SBss", "can't set accept-filter '", s
->bsd_accept_filter
, "':", strerror(errno
));
364 int network_close(server
*srv
) {
366 for (i
= 0; i
< srv
->srv_sockets
.used
; i
++) {
367 server_socket
*srv_socket
= srv
->srv_sockets
.ptr
[i
];
368 if (srv_socket
->fd
!= -1) {
369 network_unregister_sock(srv
, srv_socket
);
370 close(srv_socket
->fd
);
373 buffer_free(srv_socket
->srv_token
);
378 free(srv
->srv_sockets
.ptr
);
379 srv
->srv_sockets
.ptr
= NULL
;
380 srv
->srv_sockets
.used
= 0;
381 srv
->srv_sockets
.size
= 0;
383 for (i
= 0; i
< srv
->srv_sockets_inherited
.used
; i
++) {
384 server_socket
*srv_socket
= srv
->srv_sockets_inherited
.ptr
[i
];
385 if (srv_socket
->fd
!= -1 && srv_socket
->sidx
!= (unsigned short)~0u) {
386 close(srv_socket
->fd
);
389 buffer_free(srv_socket
->srv_token
);
394 free(srv
->srv_sockets_inherited
.ptr
);
395 srv
->srv_sockets_inherited
.ptr
= NULL
;
396 srv
->srv_sockets_inherited
.used
= 0;
397 srv
->srv_sockets_inherited
.size
= 0;
402 static int network_socket_activation_nfds(server
*srv
, int nfds
) {
403 buffer
*host
= buffer_init();
407 nfds
+= 3; /* #define SD_LISTEN_FDS_START 3 */
408 for (int fd
= 3; fd
< nfds
; ++fd
) {
409 addr_len
= sizeof(sock_addr
);
410 if (-1 == (rc
= getsockname(fd
, (struct sockaddr
*)&addr
, &addr_len
))) {
411 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
412 "socket activation getsockname()", strerror(errno
));
415 network_host_normalize_addr_str(host
, &addr
);
416 rc
= network_server_init(srv
, host
, 0, fd
);
418 srv
->srv_sockets
.ptr
[srv
->srv_sockets
.used
-1]->sidx
= (unsigned short)~0u;
421 memcpy(&srv
->srv_sockets_inherited
, &srv
->srv_sockets
, sizeof(server_socket_array
));
422 memset(&srv
->srv_sockets
, 0, sizeof(server_socket_array
));
426 static int network_socket_activation_from_env(server
*srv
) {
427 char *listen_pid
= getenv("LISTEN_PID");
428 char *listen_fds
= getenv("LISTEN_FDS");
429 pid_t lpid
= listen_pid
? (pid_t
)strtoul(listen_pid
,NULL
,10) : 0;
430 int nfds
= listen_fds
? atoi(listen_fds
) : 0;
431 int rc
= (lpid
== getpid() && nfds
> 0)
432 ? network_socket_activation_nfds(srv
, nfds
)
434 unsetenv("LISTEN_PID");
435 unsetenv("LISTEN_FDS");
436 unsetenv("LISTEN_FDNAMES");
437 /*(upon graceful restart, unsetenv will result in no-op above)*/
441 int network_init(server
*srv
, int stdin_fd
) {
444 WORD wVersionRequested
= MAKEWORD(2, 2);
445 if (0 != WSAStartup(wVersionRequested
, &wsaData
)) {
446 /* Tell the user that we could not find a usable WinSock DLL */
451 if (0 != network_write_init(srv
)) return -1;
453 if (srv
->srvconf
.systemd_socket_activation
) {
454 for (size_t i
= 0; i
< srv
->srv_sockets_inherited
.used
; ++i
) {
455 srv
->srv_sockets_inherited
.ptr
[i
]->sidx
= (unsigned short)~0u;
457 if (0 != network_socket_activation_from_env(srv
)) return -1;
458 if (0 == srv
->srv_sockets_inherited
.used
) {
459 srv
->srvconf
.systemd_socket_activation
= 0;
463 /* process srv->srvconf.bindhost
464 * (skip if systemd socket activation is enabled and bindhost is empty; do not additionally listen on "*") */
465 if (!srv
->srvconf
.systemd_socket_activation
|| !buffer_string_is_empty(srv
->srvconf
.bindhost
)) {
467 buffer
*b
= buffer_init();
468 buffer_copy_buffer(b
, srv
->srvconf
.bindhost
);
469 if (b
->ptr
[0] != '/') { /*(skip adding port if unix socket path)*/
470 buffer_append_string_len(b
, CONST_STR_LEN(":"));
471 buffer_append_int(b
, srv
->srvconf
.port
);
474 rc
= (-1 == stdin_fd
|| 0 == srv
->srv_sockets
.used
)
475 ? network_server_init(srv
, b
, 0, stdin_fd
)
476 : close(stdin_fd
);/*(graceful restart listening to "/dev/stdin")*/
478 if (0 != rc
) return -1;
481 /* check for $SERVER["socket"] */
482 for (size_t i
= 1; i
< srv
->config_context
->used
; ++i
) {
483 data_config
*dc
= (data_config
*)srv
->config_context
->data
[i
];
486 if (COMP_SERVER_SOCKET
!= dc
->comp
) continue;
488 if (dc
->cond
== CONFIG_COND_NE
) {
489 socklen_t addr_len
= sizeof(sock_addr
);
491 if (0 != network_host_parse_addr(srv
, &addr
, &addr_len
, dc
->string
, srv
->config_storage
[i
]->use_ipv6
)) {
494 network_host_normalize_addr_str(dc
->string
, &addr
);
498 if (dc
->cond
!= CONFIG_COND_EQ
) continue;
500 if (0 != network_server_init(srv
, dc
->string
, i
, -1)) return -1;
503 if (srv
->srvconf
.systemd_socket_activation
) {
504 /* activate any inherited sockets not explicitly listed in config file */
505 server_socket
*srv_socket
;
506 for (size_t i
= 0; i
< srv
->srv_sockets_inherited
.used
; ++i
) {
507 if ((unsigned short)~0u != srv
->srv_sockets_inherited
.ptr
[i
]->sidx
) continue;
508 srv
->srv_sockets_inherited
.ptr
[i
]->sidx
= 0;
509 srv_socket
= calloc(1, sizeof(server_socket
));
510 force_assert(NULL
!= srv_socket
);
511 memcpy(srv_socket
, srv
->srv_sockets_inherited
.ptr
[i
], sizeof(server_socket
));
512 network_srv_sockets_append(srv
, srv_socket
);
519 void network_unregister_sock(server
*srv
, server_socket
*srv_socket
) {
520 fdnode
*fdn
= srv_socket
->fdn
;
521 if (NULL
== fdn
) return;
522 fdevent_fdnode_event_del(srv
->ev
, fdn
);
523 fdevent_unregister(srv
->ev
, fdn
->fd
);
524 srv_socket
->fdn
= NULL
;
527 int network_register_fdevents(server
*srv
) {
530 if (-1 == fdevent_reset(srv
->ev
)) {
534 if (srv
->sockets_disabled
) return 0; /* lighttpd -1 (one-shot mode) */
536 /* register fdevents after reset */
537 for (i
= 0; i
< srv
->srv_sockets
.used
; i
++) {
538 server_socket
*srv_socket
= srv
->srv_sockets
.ptr
[i
];
540 srv_socket
->fdn
= fdevent_register(srv
->ev
, srv_socket
->fd
, network_server_handle_fdevent
, srv_socket
);
541 fdevent_fdnode_event_set(srv
->ev
, srv_socket
->fdn
, FDEVENT_IN
);