6 #include "connections.h"
9 #include "configfile.h"
10 #include "inet_ntop_cache.h"
12 #include "network_backends.h"
14 #include "sys-socket.h"
16 #include <sys/types.h>
27 network_accept_tcp_nagle_disable (const int fd
)
29 static int noinherit_tcpnodelay
= -1;
32 if (!noinherit_tcpnodelay
) /* TCP_NODELAY inherited from listen socket */
35 if (noinherit_tcpnodelay
< 0) {
36 socklen_t optlen
= sizeof(opt
);
37 if (0 == getsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &opt
, &optlen
)) {
38 noinherit_tcpnodelay
= !opt
;
39 if (opt
) /* TCP_NODELAY inherited from listen socket */
45 (void)setsockopt(fd
, IPPROTO_TCP
, TCP_NODELAY
, &opt
, sizeof(opt
));
48 static handler_t
network_server_handle_fdevent(server
*srv
, void *context
, int revents
) {
49 server_socket
*srv_socket
= (server_socket
*)context
;
55 if (0 == (revents
& FDEVENT_IN
)) {
56 log_error_write(srv
, __FILE__
, __LINE__
, "sdd",
57 "strange event for server socket",
63 /* accept()s at most 100 connections directly
65 * we jump out after 100 to give the waiting connections a chance */
66 for (loops
= 0; loops
< 100 && NULL
!= (con
= connection_accept(srv
, srv_socket
)); loops
++) {
67 connection_state_machine(srv
, con
);
72 static int network_server_init(server
*srv
, buffer
*host_token
, size_t sidx
) {
74 server_socket
*srv_socket
;
75 unsigned int port
= 0;
77 specific_config
*s
= srv
->config_storage
[sidx
];
82 WORD wVersionRequested
;
85 wVersionRequested
= MAKEWORD( 2, 2 );
87 err
= WSAStartup( wVersionRequested
, &wsaData
);
89 /* Tell the user that we could not find a usable */
96 srv_socket
= calloc(1, sizeof(*srv_socket
));
97 force_assert(NULL
!= srv_socket
);
98 srv_socket
->addr
.plain
.sa_family
= AF_INET
; /* default */
100 srv_socket
->fde_ndx
= -1;
101 srv_socket
->sidx
= sidx
;
103 srv_socket
->srv_token
= buffer_init();
104 buffer_copy_buffer(srv_socket
->srv_token
, host_token
);
107 buffer_copy_buffer(b
, host_token
); /*(allocates b->ptr even if host_token is NULL)*/
111 if (host
[0] == '/') {
112 /* host is a unix-domain-socket */
114 srv_socket
->addr
.plain
.sa_family
= AF_UNIX
;
116 log_error_write(srv
, __FILE__
, __LINE__
, "s",
117 "ERROR: Unix Domain sockets are not supported.");
118 goto error_free_socket
;
124 size_t len
= buffer_string_length(b
);
127 log_error_write(srv
, __FILE__
, __LINE__
, "s", "value of $SERVER[\"socket\"] must not be empty");
128 goto error_free_socket
;
130 if ((b
->ptr
[0] == '[' && b
->ptr
[len
-1] == ']') || NULL
== (sp
= strrchr(b
->ptr
, ':'))) {
131 /* use server.port if set in config, or else default from config_set_defaults() */
132 port
= srv
->srvconf
.port
;
133 sp
= b
->ptr
+ len
; /* point to '\0' at end of string so end of IPv6 address can be found below */
135 /* found ip:port separator at *sp; port doesn't end in ']', so *sp hopefully doesn't split an IPv6 address */
137 port
= strtol(sp
+1, NULL
, 10);
140 /* check for [ and ] */
141 if (b
->ptr
[0] == '[' && *(sp
-1) == ']') {
148 if (port
== 0 || port
> 65535) {
149 log_error_write(srv
, __FILE__
, __LINE__
, "sd", "port not set or out of range:", port
);
151 goto error_free_socket
;
157 srv_socket
->addr
.plain
.sa_family
= AF_INET6
;
162 if (srv_socket
->addr
.plain
.sa_family
== AF_INET6
) {
163 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");
165 } else if (srv_socket
->addr
.plain
.sa_family
== AF_INET
) {
170 if (1 != sock_addr_from_str_hints(srv
, &srv_socket
->addr
, &addr_len
, host
, srv_socket
->addr
.plain
.sa_family
, port
)) {
171 goto error_free_socket
;
174 if (srv
->srvconf
.preflight_check
) {
176 goto error_free_socket
;
179 if (srv
->sockets_disabled
) { /* lighttpd -1 (one-shot mode) */
180 goto srv_sockets_append
;
184 if (AF_UNIX
== srv_socket
->addr
.plain
.sa_family
) {
185 /* check if the socket exists and try to connect to it. */
186 force_assert(host
); /*(static analysis hint)*/
187 if (-1 == (srv_socket
->fd
= fdevent_socket_cloexec(srv_socket
->addr
.plain
.sa_family
, SOCK_STREAM
, 0))) {
188 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "socket failed:", strerror(errno
));
189 goto error_free_socket
;
191 if (0 == connect(srv_socket
->fd
, (struct sockaddr
*) &(srv_socket
->addr
), addr_len
)) {
192 log_error_write(srv
, __FILE__
, __LINE__
, "ss",
193 "server socket is still in use:",
197 goto error_free_socket
;
208 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
209 "testing socket failed:",
210 host
, strerror(errno
));
212 goto error_free_socket
;
215 fdevent_fcntl_set_nb(srv
->ev
, srv_socket
->fd
);
219 if (-1 == (srv_socket
->fd
= fdevent_socket_nb_cloexec(srv_socket
->addr
.plain
.sa_family
, SOCK_STREAM
, IPPROTO_TCP
))) {
220 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "socket failed:", strerror(errno
));
221 goto error_free_socket
;
225 if (AF_INET6
== srv_socket
->addr
.plain
.sa_family
229 if (-1 == setsockopt(srv_socket
->fd
, IPPROTO_IPV6
, IPV6_V6ONLY
, &val
, sizeof(val
))) {
230 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(IPV6_V6ONLY) failed:", strerror(errno
));
231 goto error_free_socket
;
234 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");
241 srv
->cur_fds
= srv_socket
->fd
;
243 if (fdevent_set_so_reuseaddr(srv_socket
->fd
, 1) < 0) {
244 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(SO_REUSEADDR) failed:", strerror(errno
));
245 goto error_free_socket
;
248 if (srv_socket
->addr
.plain
.sa_family
!= AF_UNIX
) {
249 if (fdevent_set_tcp_nodelay(srv_socket
->fd
, 1) < 0) {
250 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "setsockopt(TCP_NODELAY) failed:", strerror(errno
));
251 goto error_free_socket
;
255 if (0 != bind(srv_socket
->fd
, (struct sockaddr
*) &(srv_socket
->addr
), addr_len
)) {
256 switch(srv_socket
->addr
.plain
.sa_family
) {
258 log_error_write(srv
, __FILE__
, __LINE__
, "sds",
259 "can't bind to socket:",
260 host
, strerror(errno
));
263 log_error_write(srv
, __FILE__
, __LINE__
, "ssds",
264 "can't bind to port:",
265 host
, port
, strerror(errno
));
268 goto error_free_socket
;
271 if (srv_socket
->addr
.plain
.sa_family
== AF_UNIX
&& !buffer_string_is_empty(s
->socket_perms
)) {
273 for (char *str
= s
->socket_perms
->ptr
; *str
; ++str
) {
277 if (0 != m
&& -1 == chmod(host
, m
)) {
278 log_error_write(srv
, __FILE__
, __LINE__
, "sssbss", "chmod(\"", host
, "\", ", s
->socket_perms
, "):", strerror(errno
));
282 if (-1 == listen(srv_socket
->fd
, s
->listen_backlog
)) {
283 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "listen failed: ", strerror(errno
));
284 goto error_free_socket
;
287 if (s
->ssl_enabled
) {
288 #ifdef TCP_DEFER_ACCEPT
289 } else if (s
->defer_accept
) {
290 int v
= s
->defer_accept
;
291 if (-1 == setsockopt(srv_socket
->fd
, IPPROTO_TCP
, TCP_DEFER_ACCEPT
, &v
, sizeof(v
))) {
292 log_error_write(srv
, __FILE__
, __LINE__
, "ss", "can't set TCP_DEFER_ACCEPT: ", strerror(errno
));
295 #if defined(__FreeBSD__) || defined(__NetBSD__) \
296 || defined(__OpenBSD__) || defined(__DragonFly__)
297 } else if (!buffer_is_empty(s
->bsd_accept_filter
)
298 && (buffer_is_equal_string(s
->bsd_accept_filter
, CONST_STR_LEN("httpready"))
299 || buffer_is_equal_string(s
->bsd_accept_filter
, CONST_STR_LEN("dataready")))) {
300 #ifdef SO_ACCEPTFILTER
301 /* FreeBSD accf_http filter */
302 struct accept_filter_arg afa
;
303 memset(&afa
, 0, sizeof(afa
));
304 strncpy(afa
.af_name
, s
->bsd_accept_filter
->ptr
, sizeof(afa
.af_name
));
305 if (setsockopt(srv_socket
->fd
, SOL_SOCKET
, SO_ACCEPTFILTER
, &afa
, sizeof(afa
)) < 0) {
306 if (errno
!= ENOENT
) {
307 log_error_write(srv
, __FILE__
, __LINE__
, "SBss", "can't set accept-filter '", s
->bsd_accept_filter
, "':", strerror(errno
));
315 srv_socket
->is_ssl
= s
->ssl_enabled
;
317 if (srv
->srv_sockets
.size
== 0) {
318 srv
->srv_sockets
.size
= 4;
319 srv
->srv_sockets
.used
= 0;
320 srv
->srv_sockets
.ptr
= malloc(srv
->srv_sockets
.size
* sizeof(server_socket
*));
321 force_assert(NULL
!= srv
->srv_sockets
.ptr
);
322 } else if (srv
->srv_sockets
.used
== srv
->srv_sockets
.size
) {
323 srv
->srv_sockets
.size
+= 4;
324 srv
->srv_sockets
.ptr
= realloc(srv
->srv_sockets
.ptr
, srv
->srv_sockets
.size
* sizeof(server_socket
*));
325 force_assert(NULL
!= srv
->srv_sockets
.ptr
);
328 srv
->srv_sockets
.ptr
[srv
->srv_sockets
.used
++] = srv_socket
;
335 if (srv_socket
->fd
!= -1) {
336 network_unregister_sock(srv
, srv_socket
);
337 close(srv_socket
->fd
);
339 buffer_free(srv_socket
->srv_token
);
344 return err
; /* -1 if error; 0 if srv->srvconf.preflight_check successful */
347 int network_close(server
*srv
) {
349 for (i
= 0; i
< srv
->srv_sockets
.used
; i
++) {
350 server_socket
*srv_socket
= srv
->srv_sockets
.ptr
[i
];
351 if (srv_socket
->fd
!= -1) {
352 network_unregister_sock(srv
, srv_socket
);
353 close(srv_socket
->fd
);
356 buffer_free(srv_socket
->srv_token
);
361 free(srv
->srv_sockets
.ptr
);
362 srv
->srv_sockets
.ptr
= NULL
;
363 srv
->srv_sockets
.used
= 0;
364 srv
->srv_sockets
.size
= 0;
370 NETWORK_BACKEND_UNSET
,
371 NETWORK_BACKEND_WRITE
,
372 NETWORK_BACKEND_WRITEV
,
373 NETWORK_BACKEND_SENDFILE
,
376 int network_init(server
*srv
) {
379 network_backend_t backend
;
382 network_backend_t nb
;
384 } network_backends
[] = {
386 #if defined USE_SENDFILE
387 { NETWORK_BACKEND_SENDFILE
, "sendfile" },
389 #if defined USE_LINUX_SENDFILE
390 { NETWORK_BACKEND_SENDFILE
, "linux-sendfile" },
392 #if defined USE_FREEBSD_SENDFILE
393 { NETWORK_BACKEND_SENDFILE
, "freebsd-sendfile" },
395 #if defined USE_SOLARIS_SENDFILEV
396 { NETWORK_BACKEND_SENDFILE
, "solaris-sendfilev" },
398 #if defined USE_WRITEV
399 { NETWORK_BACKEND_WRITEV
, "writev" },
401 { NETWORK_BACKEND_WRITE
, "write" },
402 { NETWORK_BACKEND_UNSET
, NULL
}
407 buffer_copy_buffer(b
, srv
->srvconf
.bindhost
);
408 if (b
->ptr
[0] != '/') { /*(skip adding port if unix socket path)*/
409 buffer_append_string_len(b
, CONST_STR_LEN(":"));
410 buffer_append_int(b
, srv
->srvconf
.port
);
413 /* check if we already know this socket, and if yes, don't init it */
414 for (j
= 0; j
< srv
->srv_sockets
.used
; j
++) {
415 if (buffer_is_equal(srv
->srv_sockets
.ptr
[j
]->srv_token
, b
)) {
419 if (j
== srv
->srv_sockets
.used
) {
420 if (0 != network_server_init(srv
, b
, 0)) {
427 /* get a usefull default */
428 backend
= network_backends
[0].nb
;
430 /* match name against known types */
431 if (!buffer_string_is_empty(srv
->srvconf
.network_backend
)) {
432 for (i
= 0; network_backends
[i
].name
; i
++) {
434 if (buffer_is_equal_string(srv
->srvconf
.network_backend
, network_backends
[i
].name
, strlen(network_backends
[i
].name
))) {
435 backend
= network_backends
[i
].nb
;
439 if (NULL
== network_backends
[i
].name
) {
440 /* we don't know it */
442 log_error_write(srv
, __FILE__
, __LINE__
, "sb",
443 "server.network-backend has a unknown value:",
444 srv
->srvconf
.network_backend
);
451 case NETWORK_BACKEND_WRITE
:
452 srv
->network_backend_write
= network_write_chunkqueue_write
;
454 #if defined(USE_WRITEV)
455 case NETWORK_BACKEND_WRITEV
:
456 srv
->network_backend_write
= network_write_chunkqueue_writev
;
459 #if defined(USE_SENDFILE)
460 case NETWORK_BACKEND_SENDFILE
:
461 srv
->network_backend_write
= network_write_chunkqueue_sendfile
;
468 /* check for $SERVER["socket"] */
469 for (i
= 1; i
< srv
->config_context
->used
; i
++) {
470 data_config
*dc
= (data_config
*)srv
->config_context
->data
[i
];
473 if (COMP_SERVER_SOCKET
!= dc
->comp
) continue;
475 if (dc
->cond
!= CONFIG_COND_EQ
) continue;
477 /* check if we already know this socket,
478 * if yes, don't init it */
479 for (j
= 0; j
< srv
->srv_sockets
.used
; j
++) {
480 if (buffer_is_equal(srv
->srv_sockets
.ptr
[j
]->srv_token
, dc
->string
)) {
485 if (j
== srv
->srv_sockets
.used
) {
486 if (0 != network_server_init(srv
, dc
->string
, i
)) return -1;
493 void network_unregister_sock(server
*srv
, server_socket
*srv_socket
) {
494 if (-1 == srv_socket
->fd
|| -1 == srv_socket
->fde_ndx
) return;
495 fdevent_event_del(srv
->ev
, &srv_socket
->fde_ndx
, srv_socket
->fd
);
496 fdevent_unregister(srv
->ev
, srv_socket
->fd
);
499 int network_register_fdevents(server
*srv
) {
502 if (-1 == fdevent_reset(srv
->ev
)) {
506 if (srv
->sockets_disabled
) return 0; /* lighttpd -1 (one-shot mode) */
508 /* register fdevents after reset */
509 for (i
= 0; i
< srv
->srv_sockets
.used
; i
++) {
510 server_socket
*srv_socket
= srv
->srv_sockets
.ptr
[i
];
512 fdevent_register(srv
->ev
, srv_socket
->fd
, network_server_handle_fdevent
, srv_socket
);
513 fdevent_event_set(srv
->ev
, &(srv_socket
->fde_ndx
), srv_socket
->fd
, FDEVENT_IN
);