mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-02-03 20:40:05 -05:00
ITS#9112 cleaner error handling during connection setup
And additional debug code for tracking errant close()s
This commit is contained in:
parent
230b469669
commit
4d7be1c161
3 changed files with 86 additions and 0 deletions
|
|
@ -522,6 +522,23 @@ Connection * connection_init(
|
|||
Debug( LDAP_DEBUG_ANY,
|
||||
"connection_init(%d, %s): set nonblocking failed\n",
|
||||
s, c->c_peer_name.bv_val );
|
||||
|
||||
c->c_listener = NULL;
|
||||
if(c->c_peer_domain.bv_val != NULL) {
|
||||
free(c->c_peer_domain.bv_val);
|
||||
}
|
||||
BER_BVZERO( &c->c_peer_domain );
|
||||
if(c->c_peer_name.bv_val != NULL) {
|
||||
free(c->c_peer_name.bv_val);
|
||||
}
|
||||
BER_BVZERO( &c->c_peer_name );
|
||||
|
||||
ber_sockbuf_free( c->c_sb );
|
||||
c->c_sb = NULL;
|
||||
c->c_sd = AC_SOCKET_INVALID;
|
||||
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &conn_nextid_mutex );
|
||||
|
|
|
|||
|
|
@ -1085,6 +1085,50 @@ slapd_sock2fd( ber_socket_t s )
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_CLOSE
|
||||
/* Was used to find a bug causing slapd's descriptors to be closed
|
||||
* out from under it. Tracked it down to a long-standing (from 2009)
|
||||
* bug in Heimdal https://github.com/heimdal/heimdal/issues/431 .
|
||||
* Leaving this here for future use, if necessary.
|
||||
*/
|
||||
#include <dlfcn.h>
|
||||
#ifndef RTLD_NEXT
|
||||
#define RTLD_NEXT (void *)-1L
|
||||
#endif
|
||||
static char *newconns;
|
||||
typedef int (closefunc)(int fd);
|
||||
static closefunc *close_ptr;
|
||||
int close( int s )
|
||||
{
|
||||
if (newconns) {
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"daemon: close(%ld)\n", s, 0, 0 );
|
||||
if (s >= 0 && s < dtblsize && newconns[s])
|
||||
assert(newconns[s] == 2);
|
||||
}
|
||||
return close_ptr ? close_ptr(s) : -1;
|
||||
}
|
||||
|
||||
void slapd_debug_close()
|
||||
{
|
||||
if (dtblsize)
|
||||
newconns = ch_calloc(1, dtblsize);
|
||||
close_ptr = dlsym(RTLD_NEXT, "close");
|
||||
}
|
||||
|
||||
void slapd_set_close(int fd)
|
||||
{
|
||||
newconns[fd] = 3;
|
||||
}
|
||||
#define SETUP_CLOSE() slapd_debug_close()
|
||||
#define SET_CLOSE(fd) slapd_set_close(fd)
|
||||
#define CLR_CLOSE(fd) if (newconns[fd]) newconns[fd]--
|
||||
#else
|
||||
#define SETUP_CLOSE(fd)
|
||||
#define SET_CLOSE(fd)
|
||||
#define CLR_CLOSE(fd)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Add a descriptor to daemon control
|
||||
*
|
||||
|
|
@ -1148,6 +1192,7 @@ slapd_remove(
|
|||
if ( waswriter ) slap_daemon[id].sd_nwriters--;
|
||||
|
||||
SLAP_SOCK_DEL(id, s);
|
||||
CLR_CLOSE(s);
|
||||
|
||||
if ( sb )
|
||||
ber_sockbuf_free(sb);
|
||||
|
|
@ -1253,6 +1298,7 @@ slapd_close( ber_socket_t s )
|
|||
{
|
||||
Debug( LDAP_DEBUG_CONNS, "daemon: closing %ld\n",
|
||||
(long) s );
|
||||
CLR_CLOSE( SLAP_FD2SOCK(s) );
|
||||
tcp_close( SLAP_FD2SOCK(s) );
|
||||
#ifdef HAVE_WINSOCK
|
||||
slapd_sockdel( s );
|
||||
|
|
@ -1862,6 +1908,8 @@ slapd_daemon_init( const char *urls )
|
|||
dtblsize = FD_SETSIZE;
|
||||
#endif /* ! HAVE_SYSCONF && ! HAVE_GETDTABLESIZE */
|
||||
|
||||
SETUP_CLOSE();
|
||||
|
||||
/* open a pipe (or something equivalent connected to itself).
|
||||
* we write a byte on this fd whenever we catch a signal. The main
|
||||
* loop will be select'ing on this socket, and will wake up when
|
||||
|
|
@ -2070,6 +2118,11 @@ slap_listener(
|
|||
# endif /* LDAP_PF_LOCAL */
|
||||
|
||||
s = accept( SLAP_FD2SOCK( sl->sl_sd ), (struct sockaddr *) &from, &len );
|
||||
if ( s != AC_SOCKET_INVALID ) {
|
||||
SET_CLOSE(s);
|
||||
}
|
||||
Debug( LDAP_DEBUG_CONNS,
|
||||
"daemon: accept() = %ld\n", s, 0, 0 );
|
||||
|
||||
/* Resume the listener FD to allow concurrent-processing of
|
||||
* additional incoming connections.
|
||||
|
|
@ -2141,6 +2194,8 @@ slap_listener(
|
|||
Debug( LDAP_DEBUG_ANY,
|
||||
"slapd(%ld): setsockopt(SO_KEEPALIVE) failed "
|
||||
"errno=%d (%s)\n", (long) sfd, err, sock_errstr(err) );
|
||||
slapd_close(sfd);
|
||||
return 0;
|
||||
}
|
||||
#endif /* SO_KEEPALIVE */
|
||||
#ifdef TCP_NODELAY
|
||||
|
|
@ -2153,6 +2208,8 @@ slap_listener(
|
|||
Debug( LDAP_DEBUG_ANY,
|
||||
"slapd(%ld): setsockopt(TCP_NODELAY) failed "
|
||||
"errno=%d (%s)\n", (long) sfd, err, sock_errstr(err) );
|
||||
slapd_close(sfd);
|
||||
return 0;
|
||||
}
|
||||
#endif /* TCP_NODELAY */
|
||||
}
|
||||
|
|
@ -3322,6 +3379,9 @@ slap_unpause_server( void )
|
|||
void
|
||||
slapd_add_internal( ber_socket_t s, int isactive )
|
||||
{
|
||||
if (!isactive) {
|
||||
SET_CLOSE(s);
|
||||
}
|
||||
slapd_add( s, isactive, NULL, -1 );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -401,11 +401,16 @@ int main( int argc, char **argv )
|
|||
|
||||
slap_sl_mem_init();
|
||||
|
||||
|
||||
(void) ldap_pvt_thread_initialize();
|
||||
|
||||
serverName = lutil_progname( "slapd", argc, argv );
|
||||
|
||||
if ( strcmp( serverName, "slapd" ) ) {
|
||||
#ifdef DEBUG_CLOSE
|
||||
extern void slapd_debug_close();
|
||||
slapd_debug_close();
|
||||
#endif
|
||||
for (i=0; tools[i].name; i++) {
|
||||
if ( !strcmp( serverName, tools[i].name ) ) {
|
||||
rc = tools[i].func(argc, argv);
|
||||
|
|
@ -649,6 +654,10 @@ int main( int argc, char **argv )
|
|||
optarg );
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CLOSE
|
||||
extern void slapd_debug_close();
|
||||
slapd_debug_close();
|
||||
#endif
|
||||
/* try full option string first */
|
||||
for ( i = 0; tools[i].name; i++ ) {
|
||||
if ( strcmp( optarg, &tools[i].name[4] ) == 0 ) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue