X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fdaemon.c;h=e937ca9158af44cc9dc525b82c5487ac86034133;hb=48b63d4f165269f29c35f89cceddd880c3966ef5;hp=ffbf9ea1c7371abe7a3de507c722aa68d0f981f8;hpb=1971837778694d141dc779ac10675a029506ece0;p=openldap diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index ffbf9ea1c7..e937ca9158 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -21,14 +21,27 @@ int deny_severity = LOG_NOTICE; #endif /* TCP Wrappers */ /* globals */ -int dtblsize; -static int tcps; +time_t starttime; +ber_socket_t dtblsize; + +typedef struct slap_listener { + char* sl_url; + char* sl_name; +#ifdef HAVE_TLS + int sl_is_tls; +#endif + ber_socket_t sl_sd; + struct sockaddr_in sl_addr; +} Listener; + +Listener **slap_listeners = NULL; #ifdef HAVE_WINSOCK2 /* in nt_main.c */ extern ldap_pvt_thread_cond_t started_event; + /* forward reference */ -void hit_socket(); +static void hit_socket(void); /* In wsa_err.c */ char *WSAGetLastErrorString(); static ldap_pvt_thread_t hit_tid; @@ -54,12 +67,10 @@ static #endif volatile sig_atomic_t slapd_shutdown = 0; -static int daemon_initialized = 0; static ldap_pvt_thread_t listener_tid; static volatile sig_atomic_t slapd_listener = 0; -void sockinit(); -struct slap_daemon { +static struct slap_daemon { ldap_pvt_thread_mutex_t sd_mutex; int sd_nactives; @@ -78,7 +89,7 @@ struct slap_daemon { /* * Add a descriptor to daemon control */ -static void slapd_add(int s) { +static void slapd_add(ber_socket_t s) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); assert( !FD_ISSET( s, &slap_daemon.sd_actives )); @@ -91,10 +102,11 @@ static void slapd_add(int s) { } #endif - FD_SET( (unsigned) s, &slap_daemon.sd_actives ); - FD_SET( (unsigned) s, &slap_daemon.sd_readers ); + FD_SET( s, &slap_daemon.sd_actives ); + FD_SET( s, &slap_daemon.sd_readers ); - Debug( LDAP_DEBUG_CONNS, "daemon: added %d%s%s\n", s, + Debug( LDAP_DEBUG_CONNS, "daemon: added %ld%s%s\n", + (long) s, FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "", FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" ); @@ -104,27 +116,28 @@ static void slapd_add(int s) { /* * Remove the descriptor from daemon control */ -void slapd_remove(int s, int wake) { +void slapd_remove(ber_socket_t s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); - Debug( LDAP_DEBUG_CONNS, "daemon: removing %d%s%s\n", s, + Debug( LDAP_DEBUG_CONNS, "daemon: removing %ld%s%s\n", + (long) s, FD_ISSET(s, &slap_daemon.sd_readers) ? "r" : "", FD_ISSET(s, &slap_daemon.sd_writers) ? "w" : "" ); - FD_CLR( (unsigned) s, &slap_daemon.sd_actives ); - FD_CLR( (unsigned) s, &slap_daemon.sd_readers ); - FD_CLR( (unsigned) s, &slap_daemon.sd_writers ); + FD_CLR( s, &slap_daemon.sd_actives ); + FD_CLR( s, &slap_daemon.sd_readers ); + FD_CLR( s, &slap_daemon.sd_writers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); } -void slapd_clr_write(int s, int wake) { +void slapd_clr_write(ber_socket_t s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); - assert( FD_ISSET( (unsigned) s, &slap_daemon.sd_actives) ); - FD_CLR( (unsigned) s, &slap_daemon.sd_writers ); + assert( FD_ISSET( s, &slap_daemon.sd_actives) ); + FD_CLR( s, &slap_daemon.sd_writers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); @@ -133,7 +146,7 @@ void slapd_clr_write(int s, int wake) { } } -void slapd_set_write(int s, int wake) { +void slapd_set_write(ber_socket_t s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); @@ -147,12 +160,12 @@ void slapd_set_write(int s, int wake) { } } -void slapd_clr_read(int s, int wake) { +void slapd_clr_read(ber_socket_t s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); assert( FD_ISSET( s, &slap_daemon.sd_actives) ); - FD_CLR( (unsigned) s, &slap_daemon.sd_readers ); + FD_CLR( s, &slap_daemon.sd_readers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); @@ -161,12 +174,12 @@ void slapd_clr_read(int s, int wake) { } } -void slapd_set_read(int s, int wake) { +void slapd_set_read(ber_socket_t s, int wake) { ldap_pvt_thread_mutex_lock( &slap_daemon.sd_mutex ); WAKE_LISTENER(wake); assert( FD_ISSET( s, &slap_daemon.sd_actives) ); - FD_SET( (unsigned) s, &slap_daemon.sd_readers ); + FD_SET( s, &slap_daemon.sd_readers ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); @@ -175,18 +188,196 @@ void slapd_set_read(int s, int wake) { } } -static void slapd_close(int s) { - Debug( LDAP_DEBUG_CONNS, "daemon: closing %d\n", s, 0, 0 ); +static void slapd_close(ber_socket_t s) { + Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n", + (long) s, 0, 0 ); tcp_close(s); } +Listener * +open_listener( + const char* url, + int port, + int tls_port ) +{ + int tmp, rc; + Listener l; + Listener *li; + LDAPURLDesc *lud; + char *s; + + rc = ldap_url_parse( url, &lud ); + + if( rc != LDAP_URL_SUCCESS ) { + Debug( LDAP_DEBUG_ANY, + "daemon: listen URL \"%s\" parse error=%d\n", + url, rc, 0 ); + return NULL; + } + +#ifndef HAVE_TLS + if( lud->lud_ldaps ) { + Debug( LDAP_DEBUG_ANY, + "daemon: TLS not supported (%s)\n", + url, 0, 0 ); + ldap_free_urldesc( lud ); + return NULL; + } + + if(! lud->lud_port ) { + lud->lud_port = port; + } + +#else + l.sl_is_tls = lud->lud_ldaps; + + if(! lud->lud_port ) { + lud->lud_port = lud->lud_ldaps ? tls_port : port; + } +#endif + + port = lud->lud_port; + + (void) memset( (void*) &l.sl_addr, '\0', sizeof(l.sl_addr) ); + + l.sl_addr.sin_family = AF_INET; + l.sl_addr.sin_port = htons( (unsigned short) lud->lud_port ); + + if( lud->lud_host == NULL || lud->lud_host[0] == '\0' + || strcmp(lud->lud_host, "*") == 0 ) + { + l.sl_addr.sin_addr.s_addr = htonl(INADDR_ANY); + + } else { + /* host or address was specified */ + if( !inet_aton( lud->lud_host, &l.sl_addr.sin_addr ) ) { + struct hostent *he = gethostbyname( lud->lud_host ); + if( he == NULL ) { + Debug( LDAP_DEBUG_ANY, "invalid host (%s) in URL: %s", + lud->lud_host, url, 0); + ldap_free_urldesc( lud ); + return NULL; + } + + memcpy( &l.sl_addr.sin_addr, he->h_addr, + sizeof( l.sl_addr.sin_addr ) ); + } + } + + ldap_free_urldesc( lud ); + + + if ( (l.sl_sd = socket( AF_INET, SOCK_STREAM, 0 )) == AC_SOCKET_INVALID ) { +#ifndef HAVE_WINSOCK + int err = errno; + Debug( LDAP_DEBUG_ANY, + "daemon: socket() failed errno %d (%s)\n", err, + err > -1 && err < sys_nerr ? sys_errlist[err] : + "unknown", 0 ); +#else + Debug( LDAP_DEBUG_ANY, + "daemon: socket() failed errno %d (%s)\n", + WSAGetLastError(), + WSAGetLastErrorString(), 0 ); +#endif + return NULL; + } -int -set_socket( struct sockaddr_in *addr ) +#ifndef HAVE_WINSOCK + if ( l.sl_sd >= dtblsize ) { + Debug( LDAP_DEBUG_ANY, + "daemon: listener descriptor %ld is too great %ld\n", + (long) l.sl_sd, (long) dtblsize, 0 ); + tcp_close( l.sl_sd ); + return NULL; + } +#endif + +#ifdef SO_REUSEADDR + tmp = 1; + if ( setsockopt( l.sl_sd, SOL_SOCKET, SO_REUSEADDR, + (char *) &tmp, sizeof(tmp) ) == -1 ) + { + int err = errno; + Debug( LDAP_DEBUG_ANY, + "slapd(%ld): setsockopt(SO_REUSEADDR) failed errno %d (%s)\n", + (long) l.sl_sd, err, + err > -1 && err < sys_nerr + ? sys_errlist[err] : "unknown" ); + } +#endif +#ifdef SO_KEEPALIVE + tmp = 1; + if ( setsockopt( l.sl_sd, SOL_SOCKET, SO_KEEPALIVE, + (char *) &tmp, sizeof(tmp) ) == -1 ) + { + int err = errno; + Debug( LDAP_DEBUG_ANY, + "slapd(%ld): setsockopt(SO_KEEPALIVE) failed errno %d (%s)\n", + (long) l.sl_sd, err, + err > -1 && err < sys_nerr + ? sys_errlist[err] : "unknown" ); + } +#endif +#ifdef TCP_NODELAY + tmp = 1; + if ( setsockopt( l.sl_sd, IPPROTO_TCP, TCP_NODELAY, + (char *)&tmp, sizeof(tmp) ) ) + { + int err = errno; + Debug( LDAP_DEBUG_ANY, + "slapd(%ld): setsockopt(TCP_NODELAY) failed errno %d (%s)\n", + (long) l.sl_sd, err, + err > -1 && err < sys_nerr + ? sys_errlist[err] : "unknown" ); + } +#endif + + if ( bind( l.sl_sd, (struct sockaddr *) &l.sl_addr, sizeof(l.sl_addr) ) == -1 ) { + int err = errno; + Debug( LDAP_DEBUG_ANY, "daemon: bind(%ld) failed errno %d (%s)\n", + (long) l.sl_sd, err, + err > -1 && err < sys_nerr + ? sys_errlist[err] : "unknown" ); + tcp_close( l.sl_sd ); + return NULL; + } + + l.sl_url = ch_strdup( url ); + + l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65336") ); + s = inet_ntoa( l.sl_addr.sin_addr ); + sprintf( l.sl_name, "IP=%s:%d", + s != NULL ? s : "unknown" , port ); + + li = ch_malloc( sizeof( Listener ) ); + *li = l; + + Debug( LDAP_DEBUG_TRACE, "daemon: initialized %s\n", + l.sl_url, 0, 0 ); + + return li; +} + +static int sockinit(void); +static int sockdestroy(void); + +int slapd_daemon_init(char *urls, int port, int tls_port ) { - int tcps = -1; - if ( !daemon_initialized ) sockinit(); + int i, rc; + char **u; + +#ifndef HAVE_TLS + assert( tls_port == 0 ); +#endif + + Debug( LDAP_DEBUG_ARGS, "daemon_init: %s (%d/%d)\n", + urls ? urls : "", port, tls_port ); + + if( rc = sockinit() ) { + return rc; + } #ifdef HAVE_SYSCONF dtblsize = sysconf( _SC_OPEN_MAX ); @@ -202,130 +393,110 @@ set_socket( struct sockaddr_in *addr ) } #endif /* !FD_SETSIZE */ - if( addr != NULL ) { - int tmp; + FD_ZERO( &slap_daemon.sd_readers ); + FD_ZERO( &slap_daemon.sd_writers ); - if ( (tcps = socket( AF_INET, SOCK_STREAM, 0 )) == -1 ) { -#ifndef HAVE_WINSOCK - int err = errno; - Debug( LDAP_DEBUG_ANY, - "daemon: socket() failed errno %d (%s)\n", err, - err > -1 && err < sys_nerr ? sys_errlist[err] : - "unknown", 0 ); -#else - Debug( LDAP_DEBUG_ANY, - "daemon: socket() failed errno %d (%s)\n", - WSAGetLastError(), - WSAGetLastErrorString(), 0 ); -#endif - return( -1 ); - } + if( urls == NULL ) { + urls = "ldap:///"; + } -#ifndef HAVE_WINSOCK - if ( tcps >= dtblsize ) { - Debug( LDAP_DEBUG_ANY, - "daemon: listener descriptor %d is too great\n", - tcps, dtblsize, 0 ); - return -1; - } -#endif + u = str2charray( urls, " " ); -#ifdef SO_REUSEADDR - tmp = 1; - if ( setsockopt( tcps, SOL_SOCKET, SO_REUSEADDR, - (char *) &tmp, sizeof(tmp) ) == -1 ) - { - int err = errno; - Debug( LDAP_DEBUG_ANY, - "slapd(%d): setsockopt() failed errno %d (%s)\n", - tcps, err, - err > -1 && err < sys_nerr - ? sys_errlist[err] : "unknown" ); - } -#endif -#ifdef SO_KEEPALIVE - tmp = 1; - if ( setsockopt( tcps, SOL_SOCKET, SO_KEEPALIVE, - (char *) &tmp, sizeof(tmp) ) == -1 ) - { - int err = errno; - Debug( LDAP_DEBUG_ANY, - "slapd(%d): setsockopt(KEEPALIVE) failed errno %d (%s)\n", - tcps, err, - err > -1 && err < sys_nerr - ? sys_errlist[err] : "unknown" ); - } -#endif + if( u == NULL || u[0] == NULL ) { + Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n", + urls, 0, 0 ); + return -1; + } - if ( bind( tcps, (struct sockaddr *) addr, sizeof(*addr) ) == -1 ) { - int err = errno; - Debug( LDAP_DEBUG_ANY, "daemon: bind(%d) failed errno %d (%s)\n", - tcps, err, - err > -1 && err < sys_nerr - ? sys_errlist[err] : "unknown" ); + for( i=0; u[i] != NULL; i++ ) { + Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n", + u[i], 0, 0 ); + } + + if( i == 0 ) { + Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n", + urls, 0, 0 ); + return -1; + } + + Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n", + i, 0, 0 ); + + slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) ); + + for(i = 0; u[i] != NULL; i++ ) { + slap_listeners[i] = open_listener( u[i], port, tls_port ); + + if( slap_listeners[i] == NULL ) { return -1; } } + slap_listeners[i] = NULL; + + Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened.\n", + i, 0, 0 ); - return tcps; + charray_free( u ); + ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex ); + return !i; } + +slapd_daemon_destroy(void) +{ + connections_destroy(); + sockdestroy(); + return 0; +} + + static void * slapd_daemon_task( void *ptr ) { - int inetd; - struct slapd_args *args = (struct slapd_args *) ptr; - struct sockaddr_in *slapd_addr = args->addr; + int l; - tcps = args->tcps; - /*free( ptr ); This seems to be wrong unless I hosed something */ + time( &starttime ); - inetd = ( slapd_addr == NULL); - if ( !daemon_initialized ) sockinit(); - - slapd_listener=1; - - ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex ); - FD_ZERO( &slap_daemon.sd_readers ); - FD_ZERO( &slap_daemon.sd_writers ); + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) + continue; - if( !inetd ) { - if ( listen( tcps, 5 ) == -1 ) { + if ( listen( slap_listeners[l]->sl_sd, 5 ) == -1 ) { int err = errno; Debug( LDAP_DEBUG_ANY, - "daemon: listen(%d, 5) failed errno %d (%s)\n", - tcps, err, - err > -1 && err < sys_nerr + "daemon: listen(%s, 5) failed errno %d (%s)\n", + (long) slap_listeners[l]->sl_url, err, + err > -1 && err < sys_nerr ? sys_errlist[err] : "unknown" ); - return( (void*)-1 ); - } - slapd_add( tcps ); - - } else { - if( connection_init( 0, NULL, NULL ) ) { - Debug( LDAP_DEBUG_ANY, - "connection_init(%d) failed.\n", - 0, 0, 0 ); return( (void*)-1 ); } - slapd_add( 0 ); + slapd_add( slap_listeners[l]->sl_sd ); } #ifdef HAVE_WINSOCK - if ( started_event != NULL ) + if ( started_event != NULL ) { ldap_pvt_thread_cond_signal( &started_event ); + } #endif /* initialization complete. Here comes the loop. */ + while ( !slapd_shutdown ) { - unsigned int i; - int ns, nfds; - int ebadf = 0; + ber_socket_t i; + int ns; + int at; + ber_socket_t nfds; #define SLAPD_EBADF_LIMIT 10 + int ebadf = 0; + +#define SLAPD_IDLE_CHECK_LIMIT 4 + time_t last_idle_check = slap_get_time(); + time_t now; + fd_set readfds; fd_set writefds; @@ -337,8 +508,12 @@ slapd_daemon_task( struct timeval zero; struct timeval *tvp; - char *client_name; - char *client_addr; + if( global_idletimeout > 0 && difftime( + last_idle_check+global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, + now ) < 0 ) + { + connections_timeout_idle(now); + } FD_ZERO( &writefds ); FD_ZERO( &readfds ); @@ -362,7 +537,11 @@ slapd_daemon_task( memcpy( &writefds, &slap_daemon.sd_writers, sizeof(fd_set) ); #endif - FD_SET( (unsigned) tcps, &readfds ); + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) + continue; + FD_SET( slap_listeners[l]->sl_sd, &readfds ); + } #ifndef HAVE_WINSOCK nfds = slap_daemon.sd_nfds; @@ -373,21 +552,34 @@ slapd_daemon_task( ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); ldap_pvt_thread_mutex_lock( &active_threads_mutex ); + at = active_threads; + ldap_pvt_thread_mutex_unlock( &active_threads_mutex ); + #if defined( HAVE_YIELDING_SELECT ) || defined( NO_THREADS ) tvp = NULL; #else - tvp = active_threads ? &zero : NULL; + tvp = at ? &zero : NULL; #endif - Debug( LDAP_DEBUG_CONNS, - "daemon: select: tcps=%d active_threads=%d tvp=%s\n", - tcps, active_threads, - tvp == NULL ? "NULL" : "zero" ); - + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) + continue; - ldap_pvt_thread_mutex_unlock( &active_threads_mutex ); + Debug( LDAP_DEBUG_CONNS, + "daemon: select: listen=%d active_threads=%d tvp=%s\n", + slap_listeners[l]->sl_sd, at, + tvp == NULL ? "NULL" : "zero" ); + } - switch(ns = select( nfds, &readfds, &writefds, 0, tvp )) { + switch(ns = select( nfds, &readfds, +#ifdef HAVE_WINSOCK + /* don't pass empty fd_set */ + ( writefds.fd_count > 0 ? &writefds : NULL ), +#else + &writefds, +#endif + NULL, tvp )) + { case -1: { /* failure - try again */ #ifdef HAVE_WINSOCK int err = WSAGetLastError(); @@ -427,18 +619,30 @@ slapd_daemon_task( /* FALL THRU */ } - if ( FD_ISSET( tcps, &readfds ) ) { - int s; - int len = sizeof(from); + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + ber_int_t s; + socklen_t len = sizeof(from); long id; - if ( (s = accept( tcps, - (struct sockaddr *) &from, &len )) == -1 ) + char *dnsname; + char *peeraddr; + + char peername[sizeof("IP=255.255.255.255:65336")]; + + if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID ) + continue; + + if ( !FD_ISSET( slap_listeners[l]->sl_sd, &readfds ) ) + continue; + + if ( (s = accept( slap_listeners[l]->sl_sd, + (struct sockaddr *) &from, &len )) == AC_SOCKET_INVALID ) { int err = errno; Debug( LDAP_DEBUG_ANY, - "daemon: accept(%d) failed errno %d (%s)\n", err, - tcps, err >= 0 && err < sys_nerr ? + "daemon: accept(%ld) failed errno %d (%s)\n", err, + (long) slap_listeners[l]->sl_sd, + err >= 0 && err < sys_nerr ? sys_errlist[err] : "unknown"); continue; } @@ -459,58 +663,61 @@ slapd_daemon_task( /* make sure descriptor number isn't too great */ if ( s >= dtblsize ) { Debug( LDAP_DEBUG_ANY, - "daemon: %d beyond descriptor table size %d\n", - s, dtblsize, 0 ); + "daemon: %ld beyond descriptor table size %ld\n", + (long) s, (long) dtblsize, 0 ); slapd_close(s); continue; } #endif - Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %d\n", - s, 0, 0 ); + Debug( LDAP_DEBUG_CONNS, "daemon: new connection on %ld\n", + (long) s, 0, 0 ); len = sizeof(from); - if ( getpeername( s, (struct sockaddr *) &from, &len ) == 0 ) { - client_addr = inet_ntoa( from.sin_addr ); -#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD) - hp = gethostbyaddr( (char *) - &(from.sin_addr.s_addr), - sizeof(from.sin_addr.s_addr), AF_INET ); + if ( getpeername( s, (struct sockaddr *) &from, &len ) != 0 ) { + int err = errno; + Debug( LDAP_DEBUG_ANY, + "daemon: getpeername( %ld ) failed: errno=%d (%s)\n", + (long) s, err, + err >= 0 && err < sys_nerr ? + sys_errlist[err] : "unknown" ); + slapd_close(s); + continue; + } - if(hp) { - char *p; - client_name = hp->h_name; + peeraddr = inet_ntoa( from.sin_addr ); + sprintf( peername, "IP=%s:%d", + peeraddr != NULL ? peeraddr : "unknown", + (unsigned) ntohs( from.sin_port ) ); - /* normalize the domain */ - for ( p = client_name; *p; p++ ) { - *p = TOLOWER( (unsigned char) *p ); - } +#if defined(SLAPD_RLOOKUPS) || defined(HAVE_TCPD) + hp = gethostbyaddr( (char *) + &(from.sin_addr.s_addr), + sizeof(from.sin_addr.s_addr), AF_INET ); - } else { - client_name = NULL; - } -#else - client_name = NULL; -#endif + if(hp) { + dnsname = str2lower( hp->h_name ); } else { - client_name = NULL;; - client_addr = NULL; + dnsname = NULL; } +#else + dnsname = NULL; +#endif #ifdef HAVE_TCPD - if(!hosts_ctl("slapd", - client_name != NULL ? client_name : STRING_UNKNOWN, - client_addr != NULL ? client_addr : STRING_UNKNOWN, - STRING_UNKNOWN)) + if( !hosts_ctl("slapd", + dnsname != NULL ? dnsname : STRING_UNKNOWN, + peeraddr != NULL ? peeraddr : STRING_UNKNOWN, + STRING_UNKNOWN )) { /* DENY ACCESS */ Statslog( LDAP_DEBUG_ANY, - "fd=%d connection from %s (%s) denied.\n", - s, - client_name == NULL ? "unknown" : client_name, - client_addr == NULL ? "unknown" : client_addr, + "fd=%ld connection from %s (%s) denied.\n", + (long) s, + dnsname != NULL ? dnsname : "unknown", + peeraddr != NULL ? peeraddr : "unknown", 0, 0 ); slapd_close(s); @@ -518,21 +725,32 @@ slapd_daemon_task( } #endif /* HAVE_TCPD */ - if( (id = connection_init(s, client_name, client_addr)) < 0 ) { + if( (id = connection_init(s, + slap_listeners[l]->sl_url, + dnsname != NULL ? dnsname : "unknown", + peername, + slap_listeners[l]->sl_name, +#ifdef HAVE_TLS + slap_listeners[l]->sl_is_tls +#else + 0 +#endif + )) < 0 ) + { Debug( LDAP_DEBUG_ANY, - "daemon: connection_init(%d, %s, %s) failed.\n", - s, - client_name == NULL ? "unknown" : client_name, - client_addr == NULL ? "unknown" : client_addr); + "daemon: connection_init(%ld, %s, %s) failed.\n", + (long) s, + peername, + slap_listeners[l]->sl_name ); slapd_close(s); continue; } Statslog( LDAP_DEBUG_STATS, - "daemon: conn=%d fd=%d connection from %s (%s) accepted.\n", - id, s, - client_name == NULL ? "unknown" : client_name, - client_addr == NULL ? "unknown" : client_addr, + "daemon: conn=%d fd=%ld connection from %s (%s) accepted.\n", + id, (long) s, + peername, + slap_listeners[l]->sl_name, 0 ); slapd_add( s ); @@ -543,18 +761,30 @@ slapd_daemon_task( Debug( LDAP_DEBUG_CONNS, "daemon: activity on:", 0, 0, 0 ); #ifdef HAVE_WINSOCK for ( i = 0; i < readfds.fd_count; i++ ) { - Debug( LDAP_DEBUG_CONNS, " %d%s", readfds.fd_array[i], "r" ); + Debug( LDAP_DEBUG_CONNS, " %d%s", + readfds.fd_array[i], "r", 0 ); } for ( i = 0; i < writefds.fd_count; i++ ) { - Debug( LDAP_DEBUG_CONNS, " %d%s", writefds.fd_array[i], "w" ); + Debug( LDAP_DEBUG_CONNS, " %d%s", + writefds.fd_array[i], "w", 0 ); } #else for ( i = 0; i < nfds; i++ ) { int a, r, w; + int is_listener = 0; + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( i == slap_listeners[l]->sl_sd ) { + is_listener = 1; + break; + } + } + if ( is_listener ) { + continue; + } r = FD_ISSET( i, &readfds ); w = FD_ISSET( i, &writefds ); - if ( i != tcps && (r || w) ) { + if ( r || w ) { Debug( LDAP_DEBUG_CONNS, " %d%s%s", i, r ? "r" : "", w ? "w" : "" ); } @@ -570,8 +800,8 @@ slapd_daemon_task( for ( i = 0; i < nfds; i++ ) #endif { - int wd; - + ber_socket_t wd; + int is_listener = 0; #ifdef HAVE_WINSOCK wd = writefds.fd_array[i]; #else @@ -581,7 +811,13 @@ slapd_daemon_task( wd = i; #endif - if ( wd == tcps ) { + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( i == slap_listeners[l]->sl_sd ) { + is_listener = 1; + break; + } + } + if ( is_listener ) { continue; } Debug( LDAP_DEBUG_CONNS, @@ -607,7 +843,8 @@ slapd_daemon_task( for ( i = 0; i < nfds; i++ ) #endif { - int rd; + ber_socket_t rd; + int is_listener = 0; #ifdef HAVE_WINSOCK rd = readfds.fd_array[i]; @@ -618,7 +855,13 @@ slapd_daemon_task( rd = i; #endif - if ( rd == tcps ) { + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( rd == slap_listeners[l]->sl_sd ) { + is_listener = 1; + break; + } + } + if ( is_listener ) { continue; } @@ -654,8 +897,11 @@ slapd_daemon_task( 0, 0, 0 ); } - if( tcps >= 0 ) { - slapd_close( tcps ); + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( slap_listeners[l]->sl_sd != AC_SOCKET_INVALID ) { + slapd_close( slap_listeners[l]->sl_sd ); + break; + } } ldap_pvt_thread_mutex_lock( &active_threads_mutex ); @@ -671,12 +917,10 @@ slapd_daemon_task( } -int slapd_daemon( struct slapd_args *args ) +int slapd_daemon( void ) { int rc; - if ( !daemon_initialized ) sockinit(); - connections_init(); #define SLAPD_LISTENER_THREAD 1 @@ -684,12 +928,12 @@ int slapd_daemon( struct slapd_args *args ) /* listener as a separate THREAD */ rc = ldap_pvt_thread_create( &listener_tid, - 0, slapd_daemon_task, args ); + 0, slapd_daemon_task, NULL ); if ( rc != 0 ) { Debug( LDAP_DEBUG_ANY, "listener ldap_pvt_thread_create failed (%d)\n", rc, 0, 0 ); - goto destory; + return rc; } /* wait for the listener thread to complete */ @@ -697,23 +941,15 @@ int slapd_daemon( struct slapd_args *args ) #else /* expermimental code */ listener_tid = pthread_self(); - slapd_daemon_task( args ); + slapd_daemon_task( NULL ); #endif - rc = 0; - -destory: - connections_destroy(); - -#ifdef HAVE_WINSOCK - WSACleanup( ); -#endif + return 0; - return rc; } #ifdef HAVE_WINSOCK2 -void sockinit() +int sockinit(void) { WORD wVersionRequested; WSADATA wsaData; @@ -725,7 +961,7 @@ void sockinit() if ( err != 0 ) { /* Tell the user that we couldn't find a usable */ /* WinSock DLL. */ - return; + return -1; } /* Confirm that the WinSock DLL supports 2.0.*/ @@ -739,19 +975,28 @@ void sockinit() { /* Tell the user that we couldn't find a usable */ /* WinSock DLL. */ - WSACleanup( ); - return; + WSACleanup(); + return -1; } - daemon_initialized = 1; -} /* The WinSock DLL is acceptable. Proceed. */ -void hit_socket() + /* The WinSock DLL is acceptable. Proceed. */ + return 0; +} + +int sockdestroy(void) +{ + WSACleanup(); + return 0; +} + +void hit_socket(void) { - int s, on = 1; + ber_socket_t s; + int on = 1; extern struct sockaddr_in bind_addr; /* throw something at the socket to terminate the select() in the daemon thread. */ - if (( s = socket( AF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) + if (( s = socket( AF_INET, SOCK_STREAM, 0 )) == AC_SOCKET_INVALID ) Debug( LDAP_DEBUG_ANY, "slap_set_shutdown: socket failed\n\tWSAGetLastError=%d (%s)\n", WSAGetLastError(), WSAGetLastErrorString(), 0 ); @@ -765,7 +1010,8 @@ void hit_socket() if ( connect( s, (struct sockaddr *)&bind_addr, sizeof( struct sockaddr_in )) == SOCKET_ERROR ) { Debug( LDAP_DEBUG_ANY, - "hit_socket: error on connect: %d\n", WSAGetLastError(), 0 ); + "hit_socket: error on connect: %d\n", + WSAGetLastError(), 0, 0 ); /* we can probably expect some error to occur here, mostly WSAEWOULDBLOCK */ } @@ -773,35 +1019,48 @@ void hit_socket() } #elif HAVE_WINSOCK -void sockinit() +static int sockinit(void) { WSADATA wsaData; if ( WSAStartup( 0x0101, &wsaData ) != 0 ) { - return( NULL ); + return -1; } - daemon_initialized = 1; + return 0; +} +static int sockdestroy(void) +{ + WSACleanup(); + return 0; } + #else -void sockinit() +static int sockinit(void) +{ + return 0; +} +static int sockdestroy(void) { - daemon_initialized = 1; - return; + return 0; } #endif void slap_set_shutdown( int sig ) { + int l; slapd_shutdown = sig; #ifndef HAVE_WINSOCK if(slapd_listener) { ldap_pvt_thread_kill( listener_tid, LDAP_SIGUSR1 ); } #else - Debug( LDAP_DEBUG_TRACE, "Shutdown %d ordered", sig, 0 ); /* trying to "hit" the socket seems to always get a */ /* EWOULDBLOCK error, so just close the listen socket to */ /* break out of the select since we're shutting down anyway */ - tcp_close( tcps ); + for ( l = 0; slap_listeners[l] != NULL; l++ ) { + if ( slap_listeners[l]->sl_sd >= 0 ) { + tcp_close( slap_listeners[l]->sl_sd ); + } + } #endif /* reinstall self */ (void) SIGNAL( sig, slap_set_shutdown );