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 for (loops
= 0; loops
< 100 && NULL
!= (con
= connection_accept(srv
, srv_socket
)); loops
++) {
65 connection_state_machine(srv
, con
);
70 static void network_host_normalize_addr_str(buffer
*host
, sock_addr
*addr
) {
72 sock_addr_stringify_append_buffer(host
, addr
);
75 static int network_host_parse_addr(server
*srv
, sock_addr
*addr
, socklen_t
*addr_len
, buffer
*host
, int use_ipv6
) {
79 sa_family_t family
= use_ipv6
? AF_INET6
: AF_INET
;
80 unsigned int port
= srv
->srvconf
.port
;
81 if (buffer_string_is_empty(host
)) {
82 log_error_write(srv
, __FILE__
, __LINE__
, "s", "value of $SERVER[\"socket\"] must not be empty");
88 return (1 == sock_addr_from_str_hints(srv
,addr
,addr_len
,h
,AF_UNIX
,0))
92 log_error_write(srv
, __FILE__
, __LINE__
, "s",
93 "ERROR: Unix Domain sockets are not supported.");
97 buffer_copy_buffer(srv
->tmp_buf
, host
);
98 h
= srv
->tmp_buf
->ptr
;
101 if ((h
= strchr(h
, ']'))) {
103 if (*h
== ':') colon
= h
;
104 } /*(else should not happen; validated in configparser.y)*/
105 h
= srv
->tmp_buf
->ptr
+1;
108 colon
= strrchr(h
, ':');
112 port
= strtol(colon
, NULL
, 10);
113 if (port
== 0 || port
> 65535) {
114 log_error_write(srv
, __FILE__
, __LINE__
, "sd",
115 "port not set or out of range:", port
);
119 chost
= *h
? h
: family
== AF_INET
? "0.0.0.0" : "::";
120 if (1 != sock_addr_from_str_hints(srv
,addr
,addr_len
,chost
,family
,port
)) {
126 static void network_srv_sockets_append(server
*srv
, server_socket
*srv_socket
) {
127 if (srv
->srv_sockets
.used
== srv
->srv_sockets
.size
) {
128 srv
->srv_sockets
.size
+= 4;
129 srv
->srv_sockets
.ptr
= realloc(srv
->srv_sockets
.ptr
, srv
->srv_sockets
.size
* sizeof(server_socket
*));
130 force_assert(NULL
!= srv
->srv_sockets
.ptr
);
133 srv
->srv_sockets
.ptr
[srv
->srv_sockets
.used
++] = srv_socket
;
136 static int network_server_init(server
*srv
, buffer
*host_token
, size_t sidx
, int stdin_fd
) {
137 server_socket
*srv_socket
;
139 specific_config
*s
= srv
->config_storage
[sidx
];
140 socklen_t addr_len
= sizeof(sock_addr
);
145 if (buffer_string_is_empty(host_token
)) {
146 log_error_write(srv
, __FILE__
, __LINE__
, "s", "value of $SERVER[\"socket\"] must not be empty");
150 /* check if we already know this socket, and if yes, don't init it
151 * (optimization: check strings here to filter out exact matches;
152 * binary addresses are matched further below) */
153 for (size_t i
= 0; i
< srv
->srv_sockets
.used
; ++i
) {
154 if (buffer_is_equal(srv
->srv_sockets
.ptr
[i
]->srv_token
, host_token
)) {
155 buffer_copy_buffer(host_token
, srv
->srv_sockets
.ptr
[i
]->srv_token
);
160 host
= host_token
->ptr
;
161 if ((s
->use_ipv6
&& (*host
== '\0' || *host
== ':')) || (host
[0] == '[' && host
[1] == ']')) {
162 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");
164 if (*host
== '[') s
->use_ipv6
= 1;
166 memset(&addr
, 0, sizeof(addr
));
167 if (-1 != stdin_fd
) {
168 if (-1 == getsockname(stdin_fd
, (struct sockaddr
*)&addr
, &addr_len
)) {
169 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
170 "getsockname()", strerror(errno
));
173 } else if (0 != network_host_parse_addr(srv
, &addr
, &addr_len
, host_token
, s
->use_ipv6
)) {
177 family
= sock_addr_get_family(&addr
);
180 if (*host
!= '\0' && AF_INET6
== family
) {
184 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");
189 network_host_normalize_addr_str(host_token
, &addr
);
190 host
= host_token
->ptr
;
192 if (srv
->srvconf
.preflight_check
) {
196 /* check if we already know this socket (after potential DNS resolution), and if yes, don't init it */
197 for (size_t i
= 0; i
< srv
->srv_sockets
.used
; ++i
) {
198 if (0 == memcmp(&srv
->srv_sockets
.ptr
[i
]->addr
, &addr
, sizeof(addr
))) {
203 srv_socket
= calloc(1, sizeof(*srv_socket
));
204 force_assert(NULL
!= srv_socket
);
205 memcpy(&srv_socket
->addr
, &addr
, addr_len
);
207 srv_socket
->sidx
= sidx
;
208 srv_socket
->is_ssl
= s
->ssl_enabled
;
209 srv_socket
->srv_token
= buffer_init_buffer(host_token
);
211 network_srv_sockets_append(srv
, srv_socket
);
213 if (srv
->sockets_disabled
) { /* lighttpd -1 (one-shot mode) */
217 if (srv
->srvconf
.systemd_socket_activation
) {
218 for (size_t i
= 0; i
< srv
->srv_sockets_inherited
.used
; ++i
) {
219 if (0 != memcmp(&srv
->srv_sockets_inherited
.ptr
[i
]->addr
, &srv_socket
->addr
, addr_len
)) continue;
220 if ((unsigned short)~0u == srv
->srv_sockets_inherited
.ptr
[i
]->sidx
) {
221 srv
->srv_sockets_inherited
.ptr
[i
]->sidx
= sidx
;
223 stdin_fd
= srv
->srv_sockets_inherited
.ptr
[i
]->fd
;
228 if (-1 != stdin_fd
) {
229 srv_socket
->fd
= stdin_fd
;
230 if (-1 == fdevent_fcntl_set_nb_cloexec(srv
->ev
, stdin_fd
)) {
231 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "fcntl:", strerror(errno
));
236 if (AF_UNIX
== family
) {
237 /* check if the socket exists and try to connect to it. */
238 force_assert(host
); /*(static analysis hint)*/
239 if (-1 == (srv_socket
->fd
= fdevent_socket_cloexec(AF_UNIX
, SOCK_STREAM
, 0))) {
240 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "socket failed:", strerror(errno
));
243 if (0 == connect(srv_socket
->fd
, (struct sockaddr
*) &(srv_socket
->addr
), addr_len
)) {
244 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
245 "server socket is still in use:",
260 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
261 "testing socket failed:",
262 host
, strerror(errno
));
267 if (-1 == fdevent_fcntl_set_nb(srv
->ev
, srv_socket
->fd
)) {
268 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "fcntl:", strerror(errno
));
274 if (-1 == (srv_socket
->fd
= fdevent_socket_nb_cloexec(family
, SOCK_STREAM
, IPPROTO_TCP
))) {
275 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "socket failed:", strerror(errno
));
281 if (set_v6only
&& -1 == stdin_fd
) {
283 if (-1 == setsockopt(srv_socket
->fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
))) {
284 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(IPV6_V6ONLY) failed:", strerror(errno
));
291 srv
->cur_fds
= srv_socket
->fd
;
293 if (fdevent_set_so_reuseaddr(srv_socket
->fd
, 1) < 0) {
294 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(SO_REUSEADDR) failed:", strerror(errno
));
298 if (family
!= AF_UNIX
) {
299 if (fdevent_set_tcp_nodelay(srv_socket
->fd
, 1) < 0) {
300 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(TCP_NODELAY) failed:", strerror(errno
));
305 if (-1 != stdin_fd
) { } else
306 if (0 != bind(srv_socket
->fd
, (struct sockaddr
*) &(srv_socket
->addr
), addr_len
)) {
307 log_error_write(srv
, __FILE__
, __LINE__
, "sss",
308 "can't bind to socket:", host
, strerror(errno
));
312 if (-1 != stdin_fd
) { } else
313 if (AF_UNIX
== family
&& !buffer_string_is_empty(s
->socket_perms
)) {
315 for (char *str
= s
->socket_perms
->ptr
; *str
; ++str
) {
319 if (0 != m
&& -1 == chmod(host
, m
)) {
320 log_error_write(srv
, __FILE__
, __LINE__
, "sssbss", "chmod(\"", host
, "\", ", s
->socket_perms
, "):", strerror(errno
));
324 if (-1 != stdin_fd
) { } else
325 if (-1 == listen(srv_socket
->fd
, s
->listen_backlog
)) {
326 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "listen failed: ", strerror(errno
));
330 if (s
->ssl_enabled
) {
331 #ifdef TCP_DEFER_ACCEPT
332 } else if (s
->defer_accept
) {
333 int v
= s
->defer_accept
;
334 if (-1 == setsockopt(srv_socket
->fd
, IPPROTO_TCP
, TCP_DEFER_ACCEPT
, &v
, sizeof(v
))) {
335 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno
));
338 #if defined(__FreeBSD__) || defined(__NetBSD__) \
339 || defined(__OpenBSD__) || defined(__DragonFly__)
340 } else if (!buffer_is_empty(s
->bsd_accept_filter
)
341 && (buffer_is_equal_string(s
->bsd_accept_filter
, CONST_STR_LEN("httpready"))
342 || buffer_is_equal_string(s
->bsd_accept_filter
, CONST_STR_LEN("dataready")))) {
343 #ifdef SO_ACCEPTFILTER
344 /* FreeBSD accf_http filter */
345 struct accept_filter_arg afa
;
346 memset(&afa
, 0, sizeof(afa
));
347 strncpy(afa
.af_name
, s
->bsd_accept_filter
->ptr
, sizeof(afa
.af_name
));
348 if (setsockopt(srv_socket
->fd
, SOL_SOCKET
, SO_ACCEPTFILTER
, &afa
, sizeof(afa
)) < 0) {
349 if (errno
!= ENOENT
) {
350 log_error_write(srv
, __FILE__
, __LINE__
, "SBss", "can't set accept-filter '", s
->bsd_accept_filter
, "':", strerror(errno
));
360 int network_close(server
*srv
) {
362 for (i
= 0; i
< srv
->srv_sockets
.used
; i
++) {
363 server_socket
*srv_socket
= srv
->srv_sockets
.ptr
[i
];
364 if (srv_socket
->fd
!= -1) {
365 network_unregister_sock(srv
, srv_socket
);
366 close(srv_socket
->fd
);
369 buffer_free(srv_socket
->srv_token
);
374 free(srv
->srv_sockets
.ptr
);
375 srv
->srv_sockets
.ptr
= NULL
;
376 srv
->srv_sockets
.used
= 0;
377 srv
->srv_sockets
.size
= 0;
379 for (i
= 0; i
< srv
->srv_sockets_inherited
.used
; i
++) {
380 server_socket
*srv_socket
= srv
->srv_sockets_inherited
.ptr
[i
];
381 if (srv_socket
->fd
!= -1 && srv_socket
->sidx
!= (unsigned short)~0u) {
382 close(srv_socket
->fd
);
385 buffer_free(srv_socket
->srv_token
);
390 free(srv
->srv_sockets_inherited
.ptr
);
391 srv
->srv_sockets_inherited
.ptr
= NULL
;
392 srv
->srv_sockets_inherited
.used
= 0;
393 srv
->srv_sockets_inherited
.size
= 0;
398 static int network_socket_activation_nfds(server
*srv
, int nfds
) {
399 buffer
*host
= buffer_init();
403 nfds
+= 3; /* #define SD_LISTEN_FDS_START 3 */
404 for (int fd
= 3; fd
< nfds
; ++fd
) {
405 addr_len
= sizeof(sock_addr
);
406 if (-1 == (rc
= getsockname(fd
, (struct sockaddr
*)&addr
, &addr_len
))) {
407 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
408 "socket activation getsockname()", strerror(errno
));
411 network_host_normalize_addr_str(host
, &addr
);
412 rc
= network_server_init(srv
, host
, 0, fd
);
414 srv
->srv_sockets
.ptr
[srv
->srv_sockets
.used
-1]->sidx
= (unsigned short)~0u;
417 memcpy(&srv
->srv_sockets_inherited
, &srv
->srv_sockets
, sizeof(server_socket_array
));
418 memset(&srv
->srv_sockets
, 0, sizeof(server_socket_array
));
422 static int network_socket_activation_from_env(server
*srv
) {
423 char *listen_pid
= getenv("LISTEN_PID");
424 char *listen_fds
= getenv("LISTEN_FDS");
425 pid_t lpid
= listen_pid
? (pid_t
)strtoul(listen_pid
,NULL
,10) : 0;
426 int nfds
= listen_fds
? atoi(listen_fds
) : 0;
427 int rc
= (lpid
== getpid() && nfds
> 0)
428 ? network_socket_activation_nfds(srv
, nfds
)
430 unsetenv("LISTEN_PID");
431 unsetenv("LISTEN_FDS");
432 unsetenv("LISTEN_FDNAMES");
433 /*(upon graceful restart, unsetenv will result in no-op above)*/
437 int network_init(server
*srv
, int stdin_fd
) {
440 WORD wVersionRequested
= MAKEWORD(2, 2);
441 if (0 != WSAStartup(wVersionRequested
, &wsaData
)) {
442 /* Tell the user that we could not find a usable WinSock DLL */
447 if (0 != network_write_init(srv
)) return -1;
449 if (srv
->srvconf
.systemd_socket_activation
) {
450 for (size_t i
= 0; i
< srv
->srv_sockets_inherited
.used
; ++i
) {
451 srv
->srv_sockets_inherited
.ptr
[i
]->sidx
= (unsigned short)~0u;
453 if (0 != network_socket_activation_from_env(srv
)) return -1;
454 if (0 == srv
->srv_sockets_inherited
.used
) {
455 srv
->srvconf
.systemd_socket_activation
= 0;
459 /* process srv->srvconf.bindhost
460 * (skip if systemd socket activation is enabled and bindhost is empty; do not additionally listen on "*") */
461 if (!srv
->srvconf
.systemd_socket_activation
|| !buffer_string_is_empty(srv
->srvconf
.bindhost
)) {
463 buffer
*b
= buffer_init();
464 buffer_copy_buffer(b
, srv
->srvconf
.bindhost
);
465 if (b
->ptr
[0] != '/') { /*(skip adding port if unix socket path)*/
466 buffer_append_string_len(b
, CONST_STR_LEN(":"));
467 buffer_append_int(b
, srv
->srvconf
.port
);
470 rc
= (-1 == stdin_fd
|| 0 == srv
->srv_sockets
.used
)
471 ? network_server_init(srv
, b
, 0, stdin_fd
)
472 : close(stdin_fd
);/*(graceful restart listening to "/dev/stdin")*/
474 if (0 != rc
) return -1;
477 /* check for $SERVER["socket"] */
478 for (size_t i
= 1; i
< srv
->config_context
->used
; ++i
) {
479 data_config
*dc
= (data_config
*)srv
->config_context
->data
[i
];
482 if (COMP_SERVER_SOCKET
!= dc
->comp
) continue;
484 if (dc
->cond
== CONFIG_COND_NE
) {
485 socklen_t addr_len
= sizeof(sock_addr
);
487 if (0 != network_host_parse_addr(srv
, &addr
, &addr_len
, dc
->string
, srv
->config_storage
[i
]->use_ipv6
)) {
490 network_host_normalize_addr_str(dc
->string
, &addr
);
494 if (dc
->cond
!= CONFIG_COND_EQ
) continue;
496 if (0 != network_server_init(srv
, dc
->string
, i
, -1)) return -1;
499 if (srv
->srvconf
.systemd_socket_activation
) {
500 /* activate any inherited sockets not explicitly listed in config file */
501 server_socket
*srv_socket
;
502 for (size_t i
= 0; i
< srv
->srv_sockets_inherited
.used
; ++i
) {
503 if ((unsigned short)~0u != srv
->srv_sockets_inherited
.ptr
[i
]->sidx
) continue;
504 srv
->srv_sockets_inherited
.ptr
[i
]->sidx
= 0;
505 srv_socket
= calloc(1, sizeof(server_socket
));
506 force_assert(NULL
!= srv_socket
);
507 memcpy(srv_socket
, srv
->srv_sockets_inherited
.ptr
[i
], sizeof(server_socket
));
508 network_srv_sockets_append(srv
, srv_socket
);
515 void network_unregister_sock(server
*srv
, server_socket
*srv_socket
) {
516 fdnode
*fdn
= srv_socket
->fdn
;
517 if (NULL
== fdn
) return;
518 fdevent_fdnode_event_del(srv
->ev
, fdn
);
519 fdevent_unregister(srv
->ev
, fdn
->fd
);
520 srv_socket
->fdn
= NULL
;
523 int network_register_fdevents(server
*srv
) {
526 if (-1 == fdevent_reset(srv
->ev
)) {
530 if (srv
->sockets_disabled
) return 0; /* lighttpd -1 (one-shot mode) */
532 /* register fdevents after reset */
533 for (i
= 0; i
< srv
->srv_sockets
.used
; i
++) {
534 server_socket
*srv_socket
= srv
->srv_sockets
.ptr
[i
];
536 srv_socket
->fdn
= fdevent_register(srv
->ev
, srv_socket
->fd
, network_server_handle_fdevent
, srv_socket
);
537 fdevent_fdnode_event_set(srv
->ev
, srv_socket
->fdn
, FDEVENT_IN
);