2016-03-19 15:14:35 +00:00
# include "first.h"
2005-02-20 14:27:00 +00:00
# include "network.h"
# include "fdevent.h"
# include "log.h"
# include "connections.h"
# include "plugin.h"
# include "joblist.h"
2009-10-14 14:32:24 +00:00
# include "configfile.h"
2017-06-24 15:26:27 +00:00
# include "inet_ntop_cache.h"
2005-02-20 14:27:00 +00:00
# include "network_backends.h"
# include "sys-mmap.h"
# include "sys-socket.h"
2009-10-11 14:31:42 +00:00
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <errno.h>
# include <fcntl.h>
# include <unistd.h>
# include <string.h>
# include <stdlib.h>
2016-06-30 01:02:44 +00:00
void
network_accept_tcp_nagle_disable ( const int fd )
{
static int noinherit_tcpnodelay = - 1 ;
int opt ;
if ( ! noinherit_tcpnodelay ) /* TCP_NODELAY inherited from listen socket */
return ;
if ( noinherit_tcpnodelay < 0 ) {
socklen_t optlen = sizeof ( opt ) ;
if ( 0 = = getsockopt ( fd , IPPROTO_TCP , TCP_NODELAY , & opt , & optlen ) ) {
noinherit_tcpnodelay = ! opt ;
if ( opt ) /* TCP_NODELAY inherited from listen socket */
return ;
}
}
opt = 1 ;
( void ) setsockopt ( fd , IPPROTO_TCP , TCP_NODELAY , & opt , sizeof ( opt ) ) ;
}
2010-08-06 21:57:15 +00:00
static handler_t network_server_handle_fdevent ( server * srv , void * context , int revents ) {
2005-02-20 14:27:00 +00:00
server_socket * srv_socket = ( server_socket * ) context ;
connection * con ;
2005-09-23 16:31:49 +00:00
int loops = 0 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
UNUSED ( context ) ;
2006-10-04 13:26:23 +00:00
2010-08-06 21:57:19 +00:00
if ( 0 = = ( revents & FDEVENT_IN ) ) {
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sdd " ,
2005-02-20 14:27:00 +00:00
" strange event for server socket " ,
srv_socket - > fd ,
revents ) ;
2005-03-01 23:01:12 +00:00
return HANDLER_ERROR ;
2005-02-20 14:27:00 +00:00
}
2005-09-23 16:31:49 +00:00
/* accept()s at most 100 connections directly
*
2006-10-04 13:26:23 +00:00
* we jump out after 100 to give the waiting connections a chance */
2005-09-23 16:31:49 +00:00
for ( loops = 0 ; loops < 100 & & NULL ! = ( con = connection_accept ( srv , srv_socket ) ) ; loops + + ) {
2005-02-20 14:27:00 +00:00
connection_state_machine ( srv , con ) ;
}
return HANDLER_GO_ON ;
}
2016-12-22 01:23:43 +00:00
static int network_server_init ( server * srv , buffer * host_token , size_t sidx ) {
2005-02-20 14:27:00 +00:00
socklen_t addr_len ;
server_socket * srv_socket ;
unsigned int port = 0 ;
const char * host ;
2016-12-22 01:23:43 +00:00
specific_config * s = srv - > config_storage [ sidx ] ;
2005-02-20 14:27:00 +00:00
buffer * b ;
2016-03-26 13:39:54 +00:00
int err ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
# ifdef __WIN32
WORD wVersionRequested ;
WSADATA wsaData ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
wVersionRequested = MAKEWORD ( 2 , 2 ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
err = WSAStartup ( wVersionRequested , & wsaData ) ;
if ( err ! = 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return - 1 ;
}
# endif
2016-03-26 13:39:54 +00:00
err = - 1 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
srv_socket = calloc ( 1 , sizeof ( * srv_socket ) ) ;
2016-01-30 13:59:07 +00:00
force_assert ( NULL ! = srv_socket ) ;
2016-04-29 00:53:33 +00:00
srv_socket - > addr . plain . sa_family = AF_INET ; /* default */
2005-02-20 14:27:00 +00:00
srv_socket - > fd = - 1 ;
2009-09-01 14:03:59 +00:00
srv_socket - > fde_ndx = - 1 ;
2016-12-22 01:23:43 +00:00
srv_socket - > sidx = sidx ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
srv_socket - > srv_token = buffer_init ( ) ;
2015-02-08 12:37:10 +00:00
buffer_copy_buffer ( srv_socket - > srv_token , host_token ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
b = buffer_init ( ) ;
2017-06-24 15:26:27 +00:00
buffer_copy_buffer ( b , host_token ) ; /*(allocates b->ptr even if host_token is NULL)*/
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
host = b - > ptr ;
2006-10-04 13:26:23 +00:00
2005-11-23 10:46:21 +00:00
if ( host [ 0 ] = = ' / ' ) {
/* host is a unix-domain-socket */
2016-04-29 00:53:33 +00:00
# ifdef HAVE_SYS_UN_H
srv_socket - > addr . plain . sa_family = AF_UNIX ;
# else
log_error_write ( srv , __FILE__ , __LINE__ , " s " ,
" ERROR: Unix Domain sockets are not supported. " ) ;
goto error_free_socket ;
# endif
2016-03-19 13:06:54 +00:00
} else {
/* ipv4:port
* [ ipv6 ] : port
*/
size_t len = buffer_string_length ( b ) ;
char * sp = NULL ;
2016-03-19 13:06:56 +00:00
if ( 0 = = len ) {
log_error_write ( srv , __FILE__ , __LINE__ , " s " , " value of $SERVER[ \" socket \" ] must not be empty " ) ;
2016-03-19 13:06:54 +00:00
goto error_free_socket ;
2016-03-19 13:06:56 +00:00
}
if ( ( b - > ptr [ 0 ] = = ' [ ' & & b - > ptr [ len - 1 ] = = ' ] ' ) | | NULL = = ( sp = strrchr ( b - > ptr , ' : ' ) ) ) {
/* use server.port if set in config, or else default from config_set_defaults() */
port = srv - > srvconf . port ;
sp = b - > ptr + len ; /* point to '\0' at end of string so end of IPv6 address can be found below */
2016-03-19 13:06:54 +00:00
} else {
/* found ip:port separator at *sp; port doesn't end in ']', so *sp hopefully doesn't split an IPv6 address */
2016-05-08 03:08:53 +00:00
* sp = ' \0 ' ;
port = strtol ( sp + 1 , NULL , 10 ) ;
2016-03-19 13:06:54 +00:00
}
2006-10-04 13:26:23 +00:00
2016-03-19 13:06:54 +00:00
/* check for [ and ] */
if ( b - > ptr [ 0 ] = = ' [ ' & & * ( sp - 1 ) = = ' ] ' ) {
* ( sp - 1 ) = ' \0 ' ;
host + + ;
s - > use_ipv6 = 1 ;
}
if ( port = = 0 | | port > 65535 ) {
2016-03-19 13:06:56 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sd " , " port not set or out of range: " , port ) ;
2016-03-19 13:06:54 +00:00
goto error_free_socket ;
}
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
# ifdef HAVE_IPV6
if ( s - > use_ipv6 ) {
srv_socket - > addr . plain . sa_family = AF_INET6 ;
}
# endif
2006-10-04 13:26:23 +00:00
2017-06-24 15:26:27 +00:00
if ( * host = = ' \0 ' ) {
if ( srv_socket - > addr . plain . sa_family = = AF_INET6 ) {
2010-08-07 13:16:16 +00:00
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 " ) ;
2017-06-24 15:26:27 +00:00
host = " :: " ;
} else if ( srv_socket - > addr . plain . sa_family = = AF_INET ) {
host = " 0.0.0.0 " ;
2015-02-07 11:33:30 +00:00
}
2017-06-24 15:26:27 +00:00
}
2005-11-23 10:46:21 +00:00
2017-06-24 15:26:27 +00:00
if ( 1 ! = sock_addr_from_str_hints ( srv , & srv_socket - > addr , & addr_len , host , srv_socket - > addr . plain . sa_family , port ) ) {
2016-04-29 00:53:33 +00:00
goto error_free_socket ;
}
2016-03-26 13:39:54 +00:00
2016-04-29 00:53:33 +00:00
if ( srv - > srvconf . preflight_check ) {
err = 0 ;
goto error_free_socket ;
}
2006-01-14 17:02:44 +00:00
2016-04-29 04:11:45 +00:00
if ( srv - > sockets_disabled ) { /* lighttpd -1 (one-shot mode) */
goto srv_sockets_append ;
}
2016-04-29 00:53:33 +00:00
# ifdef HAVE_SYS_UN_H
if ( AF_UNIX = = srv_socket - > addr . plain . sa_family ) {
/* check if the socket exists and try to connect to it. */
2016-06-21 07:39:17 +00:00
force_assert ( host ) ; /*(static analysis hint)*/
2013-12-24 04:28:44 +00:00
if ( - 1 = = ( srv_socket - > fd = fdevent_socket_cloexec ( srv_socket - > addr . plain . sa_family , SOCK_STREAM , 0 ) ) ) {
2016-04-29 00:53:33 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socket failed: " , strerror ( errno ) ) ;
goto error_free_socket ;
}
if ( 0 = = connect ( srv_socket - > fd , ( struct sockaddr * ) & ( srv_socket - > addr ) , addr_len ) ) {
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " ,
" server socket is still in use: " ,
2006-01-14 17:02:44 +00:00
host ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2006-01-14 17:02:44 +00:00
}
/* connect failed */
switch ( errno ) {
case ECONNREFUSED :
unlink ( host ) ;
break ;
case ENOENT :
break ;
default :
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sds " ,
" testing socket failed: " ,
2006-01-14 17:02:44 +00:00
host , strerror ( errno ) ) ;
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2006-01-14 17:02:44 +00:00
}
2013-12-24 04:28:44 +00:00
fdevent_fcntl_set_nb ( srv - > ev , srv_socket - > fd ) ;
2016-04-29 00:53:33 +00:00
} else
# endif
{
2013-12-24 04:28:44 +00:00
if ( - 1 = = ( srv_socket - > fd = fdevent_socket_nb_cloexec ( srv_socket - > addr . plain . sa_family , SOCK_STREAM , IPPROTO_TCP ) ) ) {
2016-04-29 00:53:33 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " socket failed: " , strerror ( errno ) ) ;
goto error_free_socket ;
}
2006-01-14 17:02:44 +00:00
2016-04-29 00:53:33 +00:00
# ifdef HAVE_IPV6
if ( AF_INET6 = = srv_socket - > addr . plain . sa_family
& & host ! = NULL ) {
if ( s - > set_v6only ) {
2017-09-23 14:30:08 +00:00
int val = 1 ;
2016-04-29 00:53:33 +00:00
if ( - 1 = = setsockopt ( srv_socket - > fd , IPPROTO_IPV6 , IPV6_V6ONLY , & val , sizeof ( val ) ) ) {
2017-09-23 14:30:08 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " setsockopt(IPV6_V6ONLY) failed: " , strerror ( errno ) ) ;
2016-04-29 00:53:33 +00:00
goto error_free_socket ;
}
} else {
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 " ) ;
}
}
# endif
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2016-04-29 00:53:33 +00:00
/* */
srv - > cur_fds = srv_socket - > fd ;
2017-09-23 14:30:08 +00:00
if ( fdevent_set_so_reuseaddr ( srv_socket - > fd , 1 ) < 0 ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " setsockopt(SO_REUSEADDR) failed: " , strerror ( errno ) ) ;
2016-03-26 13:39:54 +00:00
goto error_free_socket ;
}
2016-06-30 01:02:44 +00:00
if ( srv_socket - > addr . plain . sa_family ! = AF_UNIX ) {
2017-09-23 14:30:08 +00:00
if ( fdevent_set_tcp_nodelay ( srv_socket - > fd , 1 ) < 0 ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " setsockopt(TCP_NODELAY) failed: " , strerror ( errno ) ) ;
2016-06-30 01:02:44 +00:00
goto error_free_socket ;
}
}
2005-02-20 14:27:00 +00:00
if ( 0 ! = bind ( srv_socket - > fd , ( struct sockaddr * ) & ( srv_socket - > addr ) , addr_len ) ) {
2006-01-14 17:02:44 +00:00
switch ( srv_socket - > addr . plain . sa_family ) {
case AF_UNIX :
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sds " ,
" can't bind to socket: " ,
2006-01-14 17:02:44 +00:00
host , strerror ( errno ) ) ;
break ;
default :
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " ssds " ,
" can't bind to port: " ,
2006-01-14 17:02:44 +00:00
host , port , strerror ( errno ) ) ;
break ;
}
2009-09-01 14:03:59 +00:00
goto error_free_socket ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2017-06-13 03:40:31 +00:00
if ( srv_socket - > addr . plain . sa_family = = AF_UNIX & & ! buffer_string_is_empty ( s - > socket_perms ) ) {
mode_t m = 0 ;
for ( char * str = s - > socket_perms - > ptr ; * str ; + + str ) {
m < < = 3 ;
m | = ( * str - ' 0 ' ) ;
}
if ( 0 ! = m & & - 1 = = chmod ( host , m ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " sssbss " , " chmod( \" " , host , " \" , " , s - > socket_perms , " ): " , strerror ( errno ) ) ;
}
}
2017-08-03 04:37:43 +00:00
if ( - 1 = = listen ( srv_socket - > fd , s - > listen_backlog ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " listen failed: " , strerror ( errno ) ) ;
goto error_free_socket ;
}
2013-07-31 20:23:21 +00:00
if ( s - > ssl_enabled ) {
2009-04-26 17:59:55 +00:00
# ifdef TCP_DEFER_ACCEPT
} else if ( s - > defer_accept ) {
int v = s - > defer_accept ;
if ( - 1 = = setsockopt ( srv_socket - > fd , IPPROTO_TCP , TCP_DEFER_ACCEPT , & v , sizeof ( v ) ) ) {
log_error_write ( srv , __FILE__ , __LINE__ , " ss " , " can't set TCP_DEFER_ACCEPT: " , strerror ( errno ) ) ;
}
2005-04-30 10:03:29 +00:00
# endif
2016-06-04 17:47:27 +00:00
# if defined(__FreeBSD__) || defined(__NetBSD__) \
2016-08-20 18:15:14 +00:00
| | defined ( __OpenBSD__ ) | | defined ( __DragonFly__ )
2016-06-04 17:47:27 +00:00
} else if ( ! buffer_is_empty ( s - > bsd_accept_filter )
& & ( buffer_is_equal_string ( s - > bsd_accept_filter , CONST_STR_LEN ( " httpready " ) )
| | buffer_is_equal_string ( s - > bsd_accept_filter , CONST_STR_LEN ( " dataready " ) ) ) ) {
2005-04-30 10:03:29 +00:00
# ifdef SO_ACCEPTFILTER
2009-04-26 17:59:55 +00:00
/* FreeBSD accf_http filter */
struct accept_filter_arg afa ;
2005-04-30 10:03:29 +00:00
memset ( & afa , 0 , sizeof ( afa ) ) ;
2016-06-04 17:47:27 +00:00
strncpy ( afa . af_name , s - > bsd_accept_filter - > ptr , sizeof ( afa . af_name ) ) ;
2005-04-30 10:03:29 +00:00
if ( setsockopt ( srv_socket - > fd , SOL_SOCKET , SO_ACCEPTFILTER , & afa , sizeof ( afa ) ) < 0 ) {
if ( errno ! = ENOENT ) {
2016-06-04 17:47:27 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " SBss " , " can't set accept-filter ' " , s - > bsd_accept_filter , " ': " , strerror ( errno ) ) ;
2005-04-30 10:03:29 +00:00
}
}
2016-06-04 17:47:27 +00:00
# endif
2005-02-20 14:27:00 +00:00
# endif
}
2006-10-04 13:26:23 +00:00
2016-04-29 04:11:45 +00:00
srv_sockets_append :
2013-07-31 20:23:21 +00:00
srv_socket - > is_ssl = s - > ssl_enabled ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
if ( srv - > srv_sockets . size = = 0 ) {
srv - > srv_sockets . size = 4 ;
srv - > srv_sockets . used = 0 ;
2013-11-13 11:43:26 +00:00
srv - > srv_sockets . ptr = malloc ( srv - > srv_sockets . size * sizeof ( server_socket * ) ) ;
2016-01-30 13:59:07 +00:00
force_assert ( NULL ! = srv - > srv_sockets . ptr ) ;
2005-02-20 14:27:00 +00:00
} else if ( srv - > srv_sockets . used = = srv - > srv_sockets . size ) {
srv - > srv_sockets . size + = 4 ;
2013-11-13 11:43:26 +00:00
srv - > srv_sockets . ptr = realloc ( srv - > srv_sockets . ptr , srv - > srv_sockets . size * sizeof ( server_socket * ) ) ;
2016-01-30 13:59:07 +00:00
force_assert ( NULL ! = srv - > srv_sockets . ptr ) ;
2005-02-20 14:27:00 +00:00
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
srv - > srv_sockets . ptr [ srv - > srv_sockets . used + + ] = srv_socket ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
buffer_free ( b ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
return 0 ;
2009-09-01 14:03:59 +00:00
error_free_socket :
if ( srv_socket - > fd ! = - 1 ) {
2017-01-24 16:29:10 +00:00
network_unregister_sock ( srv , srv_socket ) ;
2009-09-01 14:03:59 +00:00
close ( srv_socket - > fd ) ;
}
buffer_free ( srv_socket - > srv_token ) ;
free ( srv_socket ) ;
2012-11-09 14:23:22 +00:00
buffer_free ( b ) ;
2016-03-26 13:39:54 +00:00
return err ; /* -1 if error; 0 if srv->srvconf.preflight_check successful */
2005-02-20 14:27:00 +00:00
}
int network_close ( server * srv ) {
size_t i ;
for ( i = 0 ; i < srv - > srv_sockets . used ; i + + ) {
server_socket * srv_socket = srv - > srv_sockets . ptr [ i ] ;
2005-08-31 09:16:18 +00:00
if ( srv_socket - > fd ! = - 1 ) {
2017-01-24 16:29:10 +00:00
network_unregister_sock ( srv , srv_socket ) ;
2005-02-20 14:27:00 +00:00
close ( srv_socket - > fd ) ;
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
buffer_free ( srv_socket - > srv_token ) ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
free ( srv_socket ) ;
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
free ( srv - > srv_sockets . ptr ) ;
2017-01-24 16:29:10 +00:00
srv - > srv_sockets . ptr = NULL ;
srv - > srv_sockets . used = 0 ;
srv - > srv_sockets . size = 0 ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
return 0 ;
}
2005-10-31 15:34:00 +00:00
typedef enum {
NETWORK_BACKEND_UNSET ,
NETWORK_BACKEND_WRITE ,
NETWORK_BACKEND_WRITEV ,
2015-08-22 16:00:59 +00:00
NETWORK_BACKEND_SENDFILE ,
2005-10-31 15:34:00 +00:00
} network_backend_t ;
2005-02-20 14:27:00 +00:00
int network_init ( server * srv ) {
buffer * b ;
2013-11-05 15:29:07 +00:00
size_t i , j ;
2005-10-31 15:34:00 +00:00
network_backend_t backend ;
2006-10-04 13:26:23 +00:00
struct nb_map {
network_backend_t nb ;
const char * name ;
} network_backends [ ] = {
2005-10-31 15:34:00 +00:00
/* lowest id wins */
2015-08-22 16:00:59 +00:00
# if defined USE_SENDFILE
{ NETWORK_BACKEND_SENDFILE , " sendfile " } ,
# endif
2005-10-31 15:34:00 +00:00
# if defined USE_LINUX_SENDFILE
2015-08-22 16:00:59 +00:00
{ NETWORK_BACKEND_SENDFILE , " linux-sendfile " } ,
2005-10-31 15:34:00 +00:00
# endif
# if defined USE_FREEBSD_SENDFILE
2015-08-22 16:00:59 +00:00
{ NETWORK_BACKEND_SENDFILE , " freebsd-sendfile " } ,
2005-10-31 15:34:00 +00:00
# endif
# if defined USE_SOLARIS_SENDFILEV
2015-08-22 16:00:59 +00:00
{ NETWORK_BACKEND_SENDFILE , " solaris-sendfilev " } ,
2005-10-31 15:34:00 +00:00
# endif
# if defined USE_WRITEV
2015-08-22 16:00:59 +00:00
{ NETWORK_BACKEND_WRITEV , " writev " } ,
2005-10-31 15:34:00 +00:00
# endif
2015-08-22 16:00:59 +00:00
{ NETWORK_BACKEND_WRITE , " write " } ,
{ NETWORK_BACKEND_UNSET , NULL }
2005-10-31 15:34:00 +00:00
} ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
b = buffer_init ( ) ;
2006-10-04 13:26:23 +00:00
2015-02-08 12:37:10 +00:00
buffer_copy_buffer ( b , srv - > srvconf . bindhost ) ;
2017-10-04 01:13:09 +00:00
if ( b - > ptr [ 0 ] ! = ' / ' ) { /*(skip adding port if unix socket path)*/
buffer_append_string_len ( b , CONST_STR_LEN ( " : " ) ) ;
buffer_append_int ( b , srv - > srvconf . port ) ;
}
2006-10-04 13:26:23 +00:00
2017-01-24 16:29:10 +00:00
/* check if we already know this socket, and if yes, don't init it */
for ( j = 0 ; j < srv - > srv_sockets . used ; j + + ) {
if ( buffer_is_equal ( srv - > srv_sockets . ptr [ j ] - > srv_token , b ) ) {
break ;
}
}
if ( j = = srv - > srv_sockets . used ) {
if ( 0 ! = network_server_init ( srv , b , 0 ) ) {
buffer_free ( b ) ;
return - 1 ;
}
2005-02-20 14:27:00 +00:00
}
buffer_free ( b ) ;
2006-10-04 13:26:23 +00:00
2005-10-31 15:34:00 +00:00
/* get a usefull default */
backend = network_backends [ 0 ] . nb ;
/* match name against known types */
2015-02-08 12:37:10 +00:00
if ( ! buffer_string_is_empty ( srv - > srvconf . network_backend ) ) {
2005-10-31 15:34:00 +00:00
for ( i = 0 ; network_backends [ i ] . name ; i + + ) {
/**/
if ( buffer_is_equal_string ( srv - > srvconf . network_backend , network_backends [ i ] . name , strlen ( network_backends [ i ] . name ) ) ) {
backend = network_backends [ i ] . nb ;
break ;
}
}
if ( NULL = = network_backends [ i ] . name ) {
/* we don't know it */
2006-10-04 13:26:23 +00:00
log_error_write ( srv , __FILE__ , __LINE__ , " sb " ,
" server.network-backend has a unknown value: " ,
2005-10-31 15:34:00 +00:00
srv - > srvconf . network_backend ) ;
return - 1 ;
}
}
switch ( backend ) {
case NETWORK_BACKEND_WRITE :
srv - > network_backend_write = network_write_chunkqueue_write ;
break ;
2015-08-22 16:00:59 +00:00
# if defined(USE_WRITEV)
2005-10-31 15:34:00 +00:00
case NETWORK_BACKEND_WRITEV :
srv - > network_backend_write = network_write_chunkqueue_writev ;
break ;
# endif
2015-08-22 16:00:59 +00:00
# if defined(USE_SENDFILE)
case NETWORK_BACKEND_SENDFILE :
srv - > network_backend_write = network_write_chunkqueue_sendfile ;
2005-10-31 15:34:00 +00:00
break ;
# endif
default :
return - 1 ;
}
2005-02-20 14:27:00 +00:00
/* check for $SERVER["socket"] */
for ( i = 1 ; i < srv - > config_context - > used ; i + + ) {
data_config * dc = ( data_config * ) srv - > config_context - > data [ i ] ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
/* not our stage */
2005-08-08 17:25:55 +00:00
if ( COMP_SERVER_SOCKET ! = dc - > comp ) continue ;
2006-10-04 13:26:23 +00:00
2009-07-16 23:23:08 +00:00
if ( dc - > cond ! = CONFIG_COND_EQ ) continue ;
2006-03-04 14:53:57 +00:00
/* check if we already know this socket,
* if yes , don ' t init it */
for ( j = 0 ; j < srv - > srv_sockets . used ; j + + ) {
if ( buffer_is_equal ( srv - > srv_sockets . ptr [ j ] - > srv_token , dc - > string ) ) {
break ;
}
}
2006-10-04 13:26:23 +00:00
2006-03-04 14:53:57 +00:00
if ( j = = srv - > srv_sockets . used ) {
2016-12-22 01:23:43 +00:00
if ( 0 ! = network_server_init ( srv , dc - > string , i ) ) return - 1 ;
2005-02-20 14:27:00 +00:00
}
}
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
return 0 ;
}
2017-01-24 16:29:10 +00:00
void network_unregister_sock ( server * srv , server_socket * srv_socket ) {
if ( - 1 = = srv_socket - > fd | | - 1 = = srv_socket - > fde_ndx ) return ;
fdevent_event_del ( srv - > ev , & srv_socket - > fde_ndx , srv_socket - > fd ) ;
fdevent_unregister ( srv - > ev , srv_socket - > fd ) ;
}
2005-02-20 14:27:00 +00:00
int network_register_fdevents ( server * srv ) {
size_t i ;
2006-10-04 13:26:23 +00:00
2005-08-30 10:42:06 +00:00
if ( - 1 = = fdevent_reset ( srv - > ev ) ) {
return - 1 ;
}
2006-10-04 13:26:23 +00:00
2016-04-29 04:11:45 +00:00
if ( srv - > sockets_disabled ) return 0 ; /* lighttpd -1 (one-shot mode) */
2005-02-20 14:27:00 +00:00
/* register fdevents after reset */
for ( i = 0 ; i < srv - > srv_sockets . used ; i + + ) {
server_socket * srv_socket = srv - > srv_sockets . ptr [ i ] ;
2006-10-04 13:26:23 +00:00
2005-02-20 14:27:00 +00:00
fdevent_register ( srv - > ev , srv_socket - > fd , network_server_handle_fdevent , srv_socket ) ;
2010-08-17 09:54:42 +00:00
fdevent_event_set ( srv - > ev , & ( srv_socket - > fde_ndx ) , srv_socket - > fd , FDEVENT_IN ) ;
2005-02-20 14:27:00 +00:00
}
return 0 ;
}