diff --git a/include/ldap.h b/include/ldap.h
index 70ab7318fec62587cd7cd8b5f25de8e55f50a40b..460237727020d4ba96c8314a10dc519c334301b1 100644
--- a/include/ldap.h
+++ b/include/ldap.h
@@ -112,6 +112,7 @@ LDAP_BEGIN_DECL
 #define LDAP_OPT_TIMEOUT			0x5002	/* default timeout */
 #define LDAP_OPT_REFHOPLIMIT		0x5003	/* ref hop limit */
 #define LDAP_OPT_MATCHED_DN			0x5004	/* should have been in draft */
+#define LDAP_OPT_NETWORK_TIMEOUT        0x5005  /* socket level timeout */
 
 /* TLS options */
 #define LDAP_OPT_X_TLS_CACERTFILE	0x6001
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 5906bf78ae2f0a4018da9badaad54404f40e71f0..c49b372ae93c2818f48315a9c0f8cdaf051c07de 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -315,12 +315,15 @@ void ldap_int_initialize( void )
 	if ( ldap_int_tblsize == 0 )
 		ldap_int_ip_init();
 
+	gopts.ldo_debug = 0;
+
 	gopts.ldo_version =	LDAP_VERSION2;
 	gopts.ldo_deref =	LDAP_DEREF_NEVER;
 	gopts.ldo_timelimit = LDAP_NO_LIMIT;
 	gopts.ldo_sizelimit = LDAP_NO_LIMIT;
 
-	gopts.ldo_debug = 0;
+	gopts.ldo_tm_api = (struct timeval *)NULL;
+	gopts.ldo_tm_net = (struct timeval *)NULL;
 
 	gopts.ldo_defhost = LDAP_STRDUP("localhost");
 	gopts.ldo_defport = LDAP_PORT;
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index 6b1ca1a027eca2663cc97c0e3fb4b78251d82019..e9146db127075b985e0816da0e673d53345672a7 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -90,6 +90,9 @@ struct ldapoptions {
 #define LDAP_VALID_SESSION	0x2
 
 	int		ldo_debug;
+	/* per API call timeout */
+	struct timeval		*ldo_tm_api;
+	struct timeval		*ldo_tm_net;
 
 	ber_int_t		ldo_version;	/* version to connect at */
 	ber_int_t		ldo_deref;
@@ -119,6 +122,7 @@ struct ldapoptions {
 	LDAP_BOOLEANS ldo_booleans;	/* boolean options */
 };
 
+
 /*
  * structure for tracking LDAP server host, ports, DNs, etc.
  */
@@ -353,9 +357,10 @@ int open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport,
  * in os-ip.c
  */
 extern int ldap_int_tblsize;
+int ldap_int_timeval_dup( struct timeval **dest, const struct timeval *tm );
+int ldap_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host,
+	unsigned long address, int port, int async );
 
-int ldap_connect_to_host( Sockbuf *sb, const char *host, unsigned long address, int port,
-	int async );
 void ldap_close_connection( Sockbuf *sb );
 
 #ifdef HAVE_KERBEROS
diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c
index 419b4277e0cca5b215c193fe9fd04a0d034cfdee..93019b0915c52b2e55bfb5d9d73f9035cbf2fc81 100644
--- a/libraries/libldap/open.c
+++ b/libraries/libldap/open.c
@@ -236,13 +236,13 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport,
 			    port = defport;   
 			}
 
-			if (( rc = ldap_connect_to_host( sb, curhost, 0L,
+			if (( rc = ldap_connect_to_host( ld, sb, curhost, 0L,
 			    port, async )) != -1 ) {
 				break;
 			}
 		}
 	} else {
-		rc = ldap_connect_to_host( sb, NULL, htonl( INADDR_LOOPBACK ),
+		rc = ldap_connect_to_host( ld, sb, 0, htonl( INADDR_LOOPBACK ),
 		    defport, async );
 	}
 
diff --git a/libraries/libldap/options.c b/libraries/libldap/options.c
index b3dd1b4d58f3a9b073949b0c3405d4348be815aa..c66ac0ab1fe74bbeee600d03b6d9025c66ea195d 100644
--- a/libraries/libldap/options.c
+++ b/libraries/libldap/options.c
@@ -11,6 +11,7 @@
 
 #include <ac/socket.h>
 #include <ac/string.h>
+#include <ac/time.h>
 
 #include "ldap-int.h"
 
@@ -155,6 +156,22 @@ ldap_get_option(
 		* (ber_socket_t *) outvalue = ber_pvt_sb_get_desc( &(ld->ld_sb) );
 		return LDAP_OPT_SUCCESS;
 
+	case LDAP_OPT_TIMEOUT:
+		/* the caller has to free outvalue ! */
+		if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_api) != 0 )
+		{
+			return LDAP_OPT_ERROR;
+		}
+		return LDAP_OPT_SUCCESS;
+		
+	case LDAP_OPT_NETWORK_TIMEOUT:
+		/* the caller has to free outvalue ! */
+		if ( ldap_int_timeval_dup( outvalue, lo->ldo_tm_net ) != 0 )
+		{
+			return LDAP_OPT_ERROR;
+		}
+		return LDAP_OPT_SUCCESS;
+
 	case LDAP_OPT_DEREF:
 		* (int *) outvalue = lo->ldo_deref;
 		return LDAP_OPT_SUCCESS;
@@ -322,38 +339,8 @@ ldap_set_option(
 		return LDAP_OPT_SUCCESS;
 	}
 
-	if(invalue == NULL) {
-		/* no place to set from */
-		return LDAP_OPT_ERROR;
-	}
-
-	switch(option) {
-	case LDAP_OPT_API_INFO:
-	case LDAP_OPT_DESC:
-		/* READ ONLY */
-		break;
-
-	case LDAP_OPT_DEREF:
-		lo->ldo_deref = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_SIZELIMIT:
-		lo->ldo_sizelimit = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_TIMELIMIT:
-		lo->ldo_timelimit = * (const int *) invalue;
-		return LDAP_OPT_SUCCESS;
-
-	case LDAP_OPT_PROTOCOL_VERSION: {
-			int vers = * (const int *) invalue;
-			if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
-				/* not supported */
-				break;
-			}
-			ld->ld_version = vers;
-		} return LDAP_OPT_SUCCESS;
-
+	/* options which can withstand invalue == NULL */
+	switch ( option ) {
 	case LDAP_OPT_SERVER_CONTROLS: {
 			LDAPControl *const *controls =
 				(LDAPControl *const *) invalue;
@@ -392,6 +379,70 @@ ldap_set_option(
 			}
 		} return LDAP_OPT_SUCCESS;
 
+	case LDAP_OPT_TIMEOUT: {
+			const struct timeval *tv = 
+				(struct timeval *) invalue;
+
+			if ( lo->ldo_tm_api != NULL ) {
+				LDAP_FREE( lo->ldo_tm_api );
+				lo->ldo_tm_api = NULL;
+			}
+
+			if ( ldap_int_timeval_dup( &lo->ldo_tm_api, tv ) != 0 ) {
+				return LDAP_OPT_ERROR;
+			}
+		} return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_NETWORK_TIMEOUT: {
+			const struct timeval *tv = 
+				(struct timeval *) invalue;
+
+			if ( lo->ldo_tm_net != NULL ) {
+				LDAP_FREE( lo->ldo_tm_net );
+				lo->ldo_tm_net = NULL;
+			}
+
+			if ( ldap_int_timeval_dup( &lo->ldo_tm_net, tv ) != 0 ) {
+				return LDAP_OPT_ERROR;
+			}
+		} return LDAP_OPT_SUCCESS;
+	}
+
+	if(invalue == NULL) {
+		/* no place to set from */
+		return LDAP_OPT_ERROR;
+	}
+
+	/* options which cannot withstand invalue == NULL */
+
+	switch(option) {
+	case LDAP_OPT_API_INFO:
+	case LDAP_OPT_DESC:
+		/* READ ONLY */
+		break;
+
+	case LDAP_OPT_DEREF:
+		lo->ldo_deref = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_SIZELIMIT:
+		lo->ldo_sizelimit = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_TIMELIMIT:
+		lo->ldo_timelimit = * (const int *) invalue;
+		return LDAP_OPT_SUCCESS;
+
+	case LDAP_OPT_PROTOCOL_VERSION: {
+			int vers = * (const int *) invalue;
+			if (vers < LDAP_VERSION_MIN || vers > LDAP_VERSION_MAX) {
+				/* not supported */
+				break;
+			}
+			ld->ld_version = vers;
+		} return LDAP_OPT_SUCCESS;
+
+
 	case LDAP_OPT_HOST_NAME: {
 			const char *host = (const char *) invalue;
 
diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c
index 729c5d7902a4502c3e77de0dea9dbaf60d1d5c9a..140f333e749b15442141ad184fbc26bd74ee15f7 100644
--- a/libraries/libldap/os-ip.c
+++ b/libraries/libldap/os-ip.c
@@ -25,6 +25,13 @@
 #include <io.h>
 #endif /* HAVE_IO_H */
 
+#if defined( HAVE_FCNTL_H )
+#include <fcntl.h>
+#ifndef O_NONBLOCK
+#define O_NONBLOCK O_NDELAY
+#endif
+#endif /* HAVE_FCNTL_H */
+
 #if defined( HAVE_SYS_FILIO_H )
 #include <sys/filio.h>
 #elif defined( HAVE_SYS_IOCTL_H )
@@ -35,143 +42,315 @@
 
 int ldap_int_tblsize = 0;
 
-
-int
-ldap_connect_to_host( Sockbuf *sb, const char *host, unsigned long address,
-	int port, int async )
 /*
- * if host == NULL, connect using address
- * "address" and "port" must be in network byte order
- * zero is returned upon success, -1 if fatal error, -2 EINPROGRESS
- * async is only used ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS (non-0 means don't wait for connect)
- * XXX async is not used yet!
+ * nonblock connect code
+ * written by Lars Uffmann, <lars.uffmann@mediaway.net>.
+ *
+ * Copyright 1999, Lars Uffmann, All rights reserved.
+ * This software is not subject to any license of my employer
+ * mediaWays GmbH.
+ *
+ * OpenLDAP COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ *
+ * Read about the rationale in ldap_connect_timeout: 
+ * ftp://koobera.math.uic.edu/www/docs/connect.html.
  */
+
+#define osip_debug(ld,fmt,arg1,arg2,arg3) \
+do { \
+	ldap_log_printf(ld, LDAP_DEBUG_TRACE, fmt, arg1, arg2, arg3); \
+} while(0)
+
+static void
+ldap_pvt_set_errno(int err)
 {
-	int			rc, i;
-	ber_socket_t s = AC_SOCKET_INVALID;
-	int			connected, use_hp;
-	struct sockaddr_in	sin;
-	struct hostent		*hp = NULL;
+	errno = err;
+}
+
+int
+ldap_int_timeval_dup( struct timeval **dest, const struct timeval *src )
+{
+	struct timeval *new;
+
+	assert( dest != NULL );
+
+	if (src == NULL) {
+		*dest = NULL;
+		return 0;
+	}
+
+	new = (struct timeval *) malloc(sizeof(struct timeval));
+
+	if( new == NULL ) {
+		*dest = NULL;
+		return 1;
+	}
+
+	SAFEMEMCPY( (char *) new, (char *) src, sizeof(struct timeval));
+
+	*dest = new;
+	return 0;
+}
+
+static int
+ldap_pvt_ndelay_on(LDAP *ld, int fd)
+{
+	osip_debug(ld, "ldap_ndelay_on: %d\n",fd,0,0);
 #ifdef notyet
-	ioctl_t			status;	/* for ioctl call */
-#endif /* notyet */
-   
-   	/* buffers for ldap_pvt_gethostbyname_a */
-   	struct hostent		he_buf;
-   	int			local_h_errno;
-   	char   			*ha_buf=NULL;
-#define DO_RETURN(x) if (ha_buf) LDAP_FREE(ha_buf); return (x);
+/* #if defined( HAVE_FCNTL_H ) */
+	return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) | O_NONBLOCK);
+#else
+{
+	ioctl_t	status = 1;
+	return ioctl( fd, FIONBIO, (caddr_t)&status );
+}
+#endif
+	return 0;
+}
    
-	Debug( LDAP_DEBUG_TRACE, "ldap_connect_to_host: %s:%d\n",
-	    ( host == NULL ) ? "(by address)" : host, (int) ntohs( (short) port ), 0 );
-
-	connected = use_hp = 0;
-
-	if ( host != NULL ) {
-	    address = inet_addr( host );
-	    /* This was just a test for -1 until OSF1 let inet_addr return
-	       unsigned int, which is narrower than 'unsigned long address' */
-	    if ( address == 0xffffffff || address == (unsigned long) -1 ) {
-		if ( ( ldap_pvt_gethostbyname_a( host, &he_buf, &ha_buf,
-			&hp, &local_h_errno) < 0) || (hp==NULL))
-		{
-#ifdef HAVE_WINSOCK
-			errno = WSAGetLastError();
+static int
+ldap_pvt_ndelay_off(LDAP *ld, int fd)
+{
+	osip_debug(ld, "ldap_ndelay_off: %d\n",fd,0,0);
+#ifdef notyet
+/* #if defined( HAVE_FCNTL_H ) */
+	return fcntl(fd,F_SETFL,fcntl(fd,F_GETFL,0) & ~O_NONBLOCK);
 #else
-			errno = EHOSTUNREACH;	/* not exactly right, but... */
+{
+	ioctl_t	status = 0;
+	return ioctl( fd, FIONBIO, (caddr_t)&status );
+}
 #endif
-			DO_RETURN( -1 );
-		}
-		use_hp = 1;
-	    }
-	}
+}
+
+static ber_socket_t
+ldap_pvt_socket(LDAP *ld)
+{
+	ber_socket_t s = socket(AF_INET, SOCK_STREAM, 0);
+	osip_debug(ld, "ldap_new_socket: %d\n",s,0,0);
+	return ( s );
+}
+
+static int
+ldap_pvt_close_socket(LDAP *ld, int s)
+{
+	osip_debug(ld, "ldap_close_socket: %d\n",s,0,0);
+	return tcp_close(s);
+}
+
+static int
+ldap_pvt_prepare_socket(LDAP *ld, int fd)
+{
+	osip_debug(ld, "ldap_prepare_socket: %d\n",fd,0,0);
 
-	rc = -1;
-	for ( i = 0; !use_hp || ( hp->h_addr_list[ i ] != 0 ); i++ ) {
-		if (( s = socket( AF_INET, SOCK_STREAM, 0 )) < 0 ) {
-			DO_RETURN( -1 );
-		}
 #ifdef TCP_NODELAY
-		{
-			int tmp = 1;
-			if( setsockopt( s, IPPROTO_TCP, TCP_NODELAY,
-				(char *) &tmp, sizeof(tmp) ) == -1 )
-			{
-				Debug( LDAP_DEBUG_ANY,
-					"setsockopt(TCP_NODELAY failed on %d\n",
-					s, 0, 0 );
-			}
-		}
+{
+	int dummy = 1;
+	if ( setsockopt(fd,IPPROTO_TCP,TCP_NODELAY,&dummy,sizeof(dummy)) == -1 )
+		return -1;
+}
 #endif
+	return 0;
+}
+
+/*
+ * check the socket for errors after select returned.
+ */
+static int
+ldap_pvt_is_socket_ready(LDAP *ld, int s)
+{
+	osip_debug(ld, "ldap_is_sock_ready: %d\n",s,0,0);
+
+#define TRACE \
+{ \
+	osip_debug(ld, \
+		"ldap_is_socket_ready: errror on socket %d: errno: %d (%s)\n", \
+		s, \
+		errno, \
+		strerror(errno) ); \
+}
+
 #ifdef notyet
-		status = 1;
-		if ( async && ioctl( s, FIONBIO, (caddr_t)&status ) == -1 ) {
-			Debug( LDAP_DEBUG_ANY, "FIONBIO ioctl failed on %d\n",
-			    s, 0, 0 );
+/* #ifdef SO_ERROR */
+{
+	int so_errno;
+	int dummy = sizeof(so_errno);
+	if ( getsockopt(s,SOL_SOCKET,SO_ERROR,&so_errno,&dummy) == -1 )
+		return -1;
+	if ( so_errno ) {
+		ldap_pvt_set_errno(so_errno);
+		TRACE;
+		return -1;
+	}
+	return 0;
+}
+#else
+{
+	/* error slippery */
+	struct sockaddr_in sin;
+	char ch;
+	int dummy = sizeof(sin);
+	if ( getpeername(s, (struct sockaddr *) &sin, &dummy) == -1 ) {
+		read(s, &ch, 1);
+#ifdef HAVE_WINSOCK
+		ldap_pvt_set_errno( WSAGetLastError() );
+#endif
+		TRACE;
+		return -1;
 		}
-#endif /* notyet */
-		(void)memset( (char *)&sin, 0, sizeof( struct sockaddr_in ));
-		sin.sin_family = AF_INET;
-		sin.sin_port = port;
-		SAFEMEMCPY( (char *) &sin.sin_addr.s_addr,
-		    ( use_hp ? (char *) hp->h_addr_list[ i ] :
-		    (char *) &address ), sizeof( sin.sin_addr.s_addr) );
-
-		if ( connect( s, (struct sockaddr *)&sin,
-		    sizeof( struct sockaddr_in )) >= 0 ) {
-			connected = 1;
-			rc = 0;
-			break;
-		} else {
+	return 0;
+}
+#endif
+	return -1;
+#undef TRACE
+}
+
+static int
+ldap_pvt_connect(LDAP *ld, int s, struct sockaddr_in *sin, int async)
+{
+	struct timeval	tv, *opt_tv=NULL;
+	fd_set		wfds, *z=NULL;
+
+	if ( (opt_tv = ld->ld_options.ldo_tm_net) != NULL ) {
+		tv.tv_usec = opt_tv->tv_usec;
+		tv.tv_sec = opt_tv->tv_sec;
+	}
+
+	osip_debug(ld, "ldap_connect_timeout: fd: %d tm: %d async: %d\n",
+			s, opt_tv ? tv.tv_sec : -1, async);
+
+	if ( ldap_pvt_ndelay_on(ld, s) == -1 )
+		return ( -1 );
+
+	if ( connect(s, (struct sockaddr *) sin, sizeof(struct sockaddr_in)) == 0 )
+	{
+		if ( ldap_pvt_ndelay_off(ld, s) == -1 )
+			return ( -1 );
+		return ( 0 );
+	}
+
 #ifdef HAVE_WINSOCK
-		        errno = WSAGetLastError();
+	ldap_pvt_set_errno( WSAGetLastError() );
 #endif
+
+	if ( (errno != EINPROGRESS) && (errno != EWOULDBLOCK) )
+		return ( -1 );
+	
 #ifdef notyet
-#ifdef EAGAIN
-			if ( errno == EINPROGRESS || errno == EAGAIN ) {
-#else /* EAGAIN */
-			if ( errno == EINPROGRESS ) {
-#endif /* EAGAIN */
-				Debug( LDAP_DEBUG_TRACE,
-					"connect would block...\n", 0, 0, 0 );
-				rc = -2;
-				break;
-			}
-#endif /* notyet */
+	if ( async ) return ( -2 );
+#endif
 
-#ifdef LDAP_DEBUG		
-			if ( ldap_debug & LDAP_DEBUG_TRACE ) {
-				perror( (char *)inet_ntoa( sin.sin_addr ));
-			}
+	FD_ZERO(&wfds); FD_SET(s, &wfds );
+
+	if ( select(s + 1, z, &wfds, z, opt_tv ? &tv : NULL) == -1)
+		return ( -1 );
+
+	if ( FD_ISSET(s, &wfds) ) {
+		if ( ldap_pvt_is_socket_ready(ld, s) == -1 )
+			return ( -1 );
+		if ( ldap_pvt_ndelay_off(ld, s) == -1 )
+			return ( -1 );
+		return ( 0 );
+	}
+	osip_debug(ld, "ldap_connect_timeout: timed out\n",0,0,0);
+	ldap_pvt_set_errno( ETIMEDOUT );
+	return ( -1 );
+}
+
+static int
+ldap_pvt_inet_aton( LDAP *ld, const char *host, struct in_addr *in)
+{
+#ifdef notyet
+/* #ifdef HAVE_INET_ATON */
+	return inet_aton( host, in );
+#else
+{
+	unsigned long u = inet_addr( host );
+	if ( u != 0xffffffff || u != (unsigned long) -1 ) {
+		in->s_addr = u;
+		return 1;
+	}
+}
+#endif
+	return 0;
+}
+
+
+int
+ldap_connect_to_host(LDAP *ld, Sockbuf *sb, const char *host,
+		unsigned long address, int port, int async)
+{
+	struct sockaddr_in	sin;
+	struct in_addr		in;
+	ber_socket_t		s = AC_SOCKET_INVALID;
+	int			rc, i, use_hp = 0;
+	struct hostent		*hp, he_buf;
+   	int			local_h_errno;
+	char   			*ha_buf=NULL, *p, *q;
+
+	osip_debug(ld, "ldap_connect_to_host\n",0,0,0);
+	
+	if (host != NULL) {
+		if (! ldap_pvt_inet_aton( ld, host, &in) ) {
+			rc = ldap_pvt_gethostbyname_a(host, &he_buf, &ha_buf,
+					&hp, &local_h_errno);
+
+			if ( rc < 0 )
+				; /*XXX NO MEMORY? */
+
+			if ( (rc < 0) || (hp == NULL) ) {
+#ifdef HAVE_WINSOCK
+				ldap_pvt_set_errno( WSAGetLastError() );
+#else
+				/* not exactly right, but... */
+				ldap_pvt_set_errno( EHOSTUNREACH );
 #endif
-			tcp_close( s );
-			if ( !use_hp ) {
-				break;
+				if (ha_buf) LDAP_FREE(ha_buf);
+				return -1;
 			}
+			use_hp = 1;
 		}
+		address = in.s_addr;
 	}
 
-	ber_pvt_sb_set_desc( sb, s );		
+	rc = s = -1;
+	for ( i = 0; !use_hp || (hp->h_addr_list[i] != 0); ++i, rc = -1 ) {
 
-	if ( connected ) {
+		if ( (s = ldap_pvt_socket( ld )) == -1 )
+			/* use_hp ? continue : break; */
+			break;
 	   
-#ifdef notyet
-		status = 0;
-		if ( !async && ioctl( s, FIONBIO, (caddr_t)&on ) == -1 ) {
-			Debug( LDAP_DEBUG_ANY, "FIONBIO ioctl failed on %d\n",
-			    s, 0, 0 );
+		if ( ldap_pvt_prepare_socket(ld, s) == -1 ) {
+			ldap_pvt_close_socket(ld, s);
+			/* use_hp ? continue : break; */
+			break;
 		}
-#endif /* notyet */
 
-		Debug( LDAP_DEBUG_TRACE, "sd %d connected to: %s\n",
-		    s, (char *) inet_ntoa( sin.sin_addr ), 0 );
-	}
+		(void)memset((char *)&sin, 0, sizeof(struct sockaddr_in));
+		sin.sin_family = AF_INET;
+		sin.sin_port = port;
+		p = (char *)&sin.sin_addr.s_addr;
+		q = use_hp ? (char *)hp->h_addr_list[i] : (char *)&address;
+		SAFEMEMCPY(p, q, sizeof(p) );
 
-	DO_RETURN( rc );
-}
+		osip_debug(ld, "ldap_connect_to_host: Trying %s:%d\n", 
+				inet_ntoa(sin.sin_addr),ntohs(sin.sin_port),0);
+
+		rc = ldap_pvt_connect(ld, s, &sin, async);
    
-#undef DO_RETURN
+		if ( (rc == 0) || (rc == -2) ) {
+			ber_pvt_sb_set_desc( sb, s );
+			break;
+		}
 
+		ldap_pvt_close_socket(ld, s);
+
+		if (!use_hp)
+			break;
+	}
+	if (ha_buf) LDAP_FREE(ha_buf);
+	return rc;
+}
 
 void
 ldap_close_connection( Sockbuf *sb )
diff --git a/libraries/libldap/unbind.c b/libraries/libldap/unbind.c
index 39b3263e4c6dd2b04505c630b7e300fe7924ca84..93ce360d754fb1039499e750eb5336e8fe5cd88d 100644
--- a/libraries/libldap/unbind.c
+++ b/libraries/libldap/unbind.c
@@ -133,6 +133,16 @@ ldap_ld_free(
 		ld->ld_options.ldo_defhost = NULL;
 	}
 
+	if ( ld->ld_options.ldo_tm_api != NULL ) {
+		LDAP_FREE( ld->ld_options.ldo_tm_api );
+		ld->ld_options.ldo_tm_api = NULL;
+	}
+
+	if ( ld->ld_options.ldo_tm_net != NULL ) {
+		LDAP_FREE( ld->ld_options.ldo_tm_net );
+		ld->ld_options.ldo_tm_net = NULL;
+	}
+
 	ber_pvt_sb_destroy( &(ld->ld_sb) );   
    
 	LDAP_FREE( (char *) ld );