/* $OpenLDAP$ */
/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
+ * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
#include <ac/unistd.h>
#include "ldap_pvt.h"
+#include "ldap_pvt_thread.h"
#include "lutil.h"
#include "slap.h"
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
-#ifdef LDAP_CONNECTIONLESS
- int sl_is_udp; /* UDP listener is also data port */
-#endif
- ber_socket_t sl_sd;
- Sockaddr sl_sa;
-#define sl_addr sl_sa.sa_in_addr
-} Listener;
-
Listener **slap_listeners = NULL;
#define SLAPD_LISTEN 10
do { if (w) tcp_write( wake_sds[1], "0", 1 ); } while(0)
#endif
-#ifdef HAVE_NT_SERVICE_MANAGER
-/* in nt_main.c */
-extern ldap_pvt_thread_cond_t started_event;
-extern int is_NT_Service;
-#endif
-
#ifndef HAVE_WINSOCK
static
#endif
slapd_srvurls[i] = (char *) realloc( slapd_srvurls[i],
strlen( host ) +
sizeof( LDAP_SRVTYPE_PREFIX ) );
- strcpy( slapd_srvurls[i], LDAP_SRVTYPE_PREFIX );
- strcat( slapd_srvurls[i], host );
+ strcpy( slap_strcopy(slapd_srvurls[i],
+ LDAP_SRVTYPE_PREFIX ), host );
ch_free( host );
}
slapd_srvurls[i] = (char *) realloc( slapd_srvurls[i],
strlen( host ) +
sizeof( LDAPS_SRVTYPE_PREFIX ) );
- strcpy( slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX );
- strcat( slapd_srvurls[i], host );
+ strcpy( slap_strcopy(slapd_srvurls[i],
+ LDAPS_SRVTYPE_PREFIX ), host );
ch_free( host );
}
hints.ai_family = AF_UNSPEC;
snprintf(serv, sizeof serv, "%d", port);
- if (err = getaddrinfo(host, serv, &hints, &res)) {
+ if ( (err = getaddrinfo(host, serv, &hints, &res)) ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
"slap_get_listener_addresses: getaddrinfo failed: %s\n",
for (n=2; (sai = sai->ai_next) != NULL; n++) {
/* EMPTY */ ;
}
- *sal = ch_malloc(n * sizeof(void *));
+ *sal = ch_calloc(n, sizeof(void *));
if (*sal == NULL) {
return -1;
}
sap = *sal;
+ *sap = NULL;
for ( sai=res; sai; sai=sai->ai_next ) {
if( sai->ai_addr == NULL ) {
*sap = NULL;
break;
}
+
if (*sap != NULL) {
(*sap)->sa_family = sai->ai_family;
sap++;
+ *sap = NULL;
}
}
- *sap = NULL;
freeaddrinfo(res);
#else
struct in_addr in;
Listener *li;
LDAPURLDesc *lud;
unsigned short port;
- int err, addrlen;
+ int err, addrlen = 0;
struct sockaddr **sal, **psal;
int socktype = SOCK_STREAM; /* default to COTS */
+#ifdef LDAP_PF_LOCAL
+ mode_t perms = S_IRWXU;
+#endif
rc = ldap_url_parse( url, &lud );
#endif
} else {
#ifdef LDAP_CONNECTIONLESS
- if ( tmp == LDAP_PROTO_UDP )
- l.sl_is_udp = 1;
+ l.sl_is_udp = ( tmp == LDAP_PROTO_UDP );
#endif
if( lud->lud_host == NULL || lud->lud_host[0] == '\0'
|| strcmp(lud->lud_host, "*") == 0 )
#ifdef LDAP_PF_LOCAL
case AF_LOCAL: {
char *addr = ((struct sockaddr_un *)*sal)->sun_path;
- if ( chmod( addr, S_IRWXU ) < 0 ) {
+ if ( chmod( addr, perms ) < 0 ) {
int err = sock_errno();
#ifdef NEW_LOGGING
LDAP_LOG(( "connection", LDAP_LEVEL_INFO,
inet_ntop( AF_INET, &((struct sockaddr_in *)*sal)->sin_addr,
addr, sizeof(addr) );
s = addr;
- port = ((struct sockaddr_in *)*sal) ->sin_port;
#else
- s = inet_ntoa( l.sl_addr.sin_addr );
- port = l.sl_addr.sin_port;
+ s = inet_ntoa( ((struct sockaddr_in *) *sal)->sin_addr );
#endif
+ port = ((struct sockaddr_in *)*sal) ->sin_port;
l.sl_name = ch_malloc( sizeof("IP=255.255.255.255:65535") );
sprintf( l.sl_name, "IP=%s:%d",
s != NULL ? s : "unknown" , port );
)
{
int l;
- time_t last_idle_check = slap_get_time();
+ time_t last_idle_check = 0;
time( &starttime );
+ if ( global_idletimeout > 0 ) {
+ last_idle_check = slap_get_time();
+ }
for ( l = 0; slap_listeners[l] != NULL; l++ ) {
if ( slap_listeners[l]->sl_sd == AC_SOCKET_INVALID )
continue;
ber_socket_t nfds;
#define SLAPD_EBADF_LIMIT 16
int ebadf = 0;
+ int emfile = 0;
#define SLAPD_IDLE_CHECK_LIMIT 4
- time_t now = slap_get_time();
+ time_t now;
fd_set readfds;
Sockaddr from;
#if defined(SLAPD_RLOOKUPS)
- struct hostent *hp;
+ struct hostent *hp;
#endif
struct timeval zero;
struct timeval *tvp;
- if( global_idletimeout > 0 && difftime(
- last_idle_check+global_idletimeout/SLAPD_IDLE_CHECK_LIMIT,
- now ) < 0 )
- {
- connections_timeout_idle(now);
+ if( emfile ) {
+ now = slap_get_time();
+ connections_timeout_idle( now );
+ }
+ else if ( global_idletimeout > 0 ) {
+ now = slap_get_time();
+ if ( difftime( last_idle_check+global_idletimeout/SLAPD_IDLE_CHECK_LIMIT, now ) < 0 ) {
+ connections_timeout_idle( now );
+ }
}
FD_ZERO( &writefds );
slap_ssf_t ssf = 0;
char *authid = NULL;
- char *dnsname;
+ char *dnsname = NULL;
char *peeraddr;
#ifdef LDAP_PF_LOCAL
char peername[MAXPATHLEN + sizeof("PATH=")];
(struct sockaddr *) &from, &len );
if ( s == AC_SOCKET_INVALID ) {
int err = sock_errno();
+
+#ifdef EMFILE
+ if( err == EMFILE ) {
+ emfile++;
+ } else
+#endif
+#ifdef ENFILE
+ if( err == ENFILE ) {
+ emfile++;
+ } else
+#endif
+ {
+ emfile=0;
+ }
+
+ if( emfile < 3 ) {
#ifdef NEW_LOGGING
- LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
- "slapd_daemon_task: accept(%ld) failed errno=%d (%s)\n",
- (long)slap_listeners[l]->sl_sd, err, sock_errstr(err) ));
+ LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
+ "slapd_daemon_task: accept(%ld) failed errno=%d (%s)\n",
+ (long)slap_listeners[l]->sl_sd, err, sock_errstr(err) ));
#else
- Debug( LDAP_DEBUG_ANY,
- "daemon: accept(%ld) failed errno=%d (%s)\n",
- (long) slap_listeners[l]->sl_sd, err,
- sock_errstr(err) );
-#endif
+ Debug( LDAP_DEBUG_ANY,
+ "daemon: accept(%ld) failed errno=%d (%s)\n",
+ (long) slap_listeners[l]->sl_sd, err,
+ sock_errstr(err) );
+#endif
+ } else {
+ /* prevent busy loop */
+# ifdef HAVE_USLEEP
+ if( emfile % 4 == 3 ) usleep( 250 );
+# else
+ if( emfile % 8 == 7 ) sleep( 1 );
+# endif
+ }
+
ldap_pvt_thread_yield();
continue;
}
+ emfile = 0;
#ifndef HAVE_WINSOCK
/* make sure descriptor number isn't too great */
if ( s >= dtblsize ) {
#ifdef NEW_LOGGING
LDAP_LOG(( "connection", LDAP_LEVEL_ERR,
- "slapd_daemon_task: %ld beyond descriptor table size %ld\n",
- (long)s, (long)dtblsize ));
+ "slapd_daemon_task: %ld beyond descriptor table size %ld\n",
+ (long)s, (long)dtblsize ));
#else
Debug( LDAP_DEBUG_ANY,
"daemon: %ld beyond descriptor table size %ld\n",
(long) s, (long) dtblsize, 0 );
#endif
+
slapd_close(s);
ldap_pvt_thread_yield();
continue;
case AF_LOCAL:
sprintf( peername, "PATH=%s", from.sa_un_addr.sun_path );
ssf = LDAP_PVT_SASL_LOCAL_SSF;
+ dnsname = "local";
break;
#endif /* LDAP_PF_LOCAL */
}
#endif /* LDAP_PF_LOCAL */
slapd_close( slap_listeners[l]->sl_sd );
- break;
}
+ if ( slap_listeners[l]->sl_url )
+ free ( slap_listeners[l]->sl_url );
+ if ( slap_listeners[l]->sl_name )
+ free ( slap_listeners[l]->sl_name );
+ free ( slap_listeners[l] );
}
+ free ( slap_listeners );
+ slap_listeners = NULL;
#ifdef NEW_LOGGING
LDAP_LOG(( "connection", LDAP_LEVEL_CRIT,
void slapd_add_internal(ber_socket_t s) {
slapd_add(s);
}
+
+Listener ** slapd_get_listeners(void) {
+ return slap_listeners;
+}