Blame SOURCES/openldap-chase-referral.patch

5b6c6a
diff -up openldap-2.3.43/libraries/libldap/os-ip.c.orig openldap-2.3.43/libraries/libldap/os-ip.c
5b6c6a
--- openldap-2.3.43/libraries/libldap/os-ip.c.orig	2008-05-19 19:28:54.000000000 -0400
5b6c6a
+++ openldap-2.3.43/libraries/libldap/os-ip.c	2009-07-29 17:01:32.000000000 -0400
5b6c6a
@@ -738,6 +738,9 @@ ldap_mark_select_read( LDAP *ld, Sockbuf
5b6c6a
 
5b6c6a
 	sip = (struct selectinfo *)ld->ld_selectinfo;
5b6c6a
 
5b6c6a
+	if (ber_sockbuf_ctrl( sb, LBER_SB_OPT_DATA_READY, NULL ))
5b6c6a
+		return;
5b6c6a
+
5b6c6a
 	ber_sockbuf_ctrl( sb, LBER_SB_OPT_GET_FD, &sd );
5b6c6a
 
5b6c6a
 #ifdef HAVE_POLL
5b6c6a
diff -up openldap-2.3.43/libraries/libldap/result.c.orig openldap-2.3.43/libraries/libldap/result.c
5b6c6a
--- openldap-2.3.43/libraries/libldap/result.c.orig	2009-07-29 17:00:42.000000000 -0400
5b6c6a
+++ openldap-2.3.43/libraries/libldap/result.c	2009-07-29 18:10:35.000000000 -0400
5b6c6a
@@ -73,7 +73,7 @@ static int ldap_mark_abandoned LDAP_P(( 
5b6c6a
 static int wait4msg LDAP_P(( LDAP *ld, ber_int_t msgid, int all, struct timeval *timeout,
5b6c6a
 	LDAPMessage **result ));
5b6c6a
 static ber_tag_t try_read1msg LDAP_P(( LDAP *ld, ber_int_t msgid,
5b6c6a
-	int all, LDAPConn **lc, LDAPMessage **result ));
5b6c6a
+	int all, LDAPConn *lc, LDAPMessage **result ));
5b6c6a
 static ber_tag_t build_result_ber LDAP_P(( LDAP *ld, BerElement **bp, LDAPRequest *lr ));
5b6c6a
 static void merge_error_info LDAP_P(( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr ));
5b6c6a
 static LDAPMessage * chkResponseList LDAP_P(( LDAP *ld, int msgid, int all));
5b6c6a
@@ -118,15 +118,9 @@ ldap_result(
5b6c6a
 #ifdef LDAP_R_COMPILE
5b6c6a
 	ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex );
5b6c6a
 #endif
5b6c6a
-	lm = chkResponseList(ld, msgid, all);
5b6c6a
 
5b6c6a
-	if ( lm == NULL ) {
5b6c6a
-		rc = wait4msg( ld, msgid, all, timeout, result );
5b6c6a
-	} else {
5b6c6a
-		*result = lm;
5b6c6a
-		ld->ld_errno = LDAP_SUCCESS;
5b6c6a
-		rc = lm->lm_msgtype;
5b6c6a
-	}
5b6c6a
+	rc = wait4msg( ld, msgid, all, timeout, result );
5b6c6a
+
5b6c6a
 #ifdef LDAP_R_COMPILE
5b6c6a
 	ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex );
5b6c6a
 #endif
5b6c6a
@@ -233,7 +227,7 @@ wait4msg(
5b6c6a
 			*tvp;
5b6c6a
 	time_t		start_time = 0;
5b6c6a
 	time_t		tmp_time;
5b6c6a
-	LDAPConn	*lc;
5b6c6a
+	LDAPConn	*lc, *nextlc;
5b6c6a
 
5b6c6a
 	assert( ld != NULL );
5b6c6a
 	assert( result != NULL );
5b6c6a
@@ -280,13 +274,6 @@ wait4msg(
5b6c6a
 			for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) {
5b6c6a
 				if ( ber_sockbuf_ctrl( lc->lconn_sb,
5b6c6a
 						LBER_SB_OPT_DATA_READY, NULL ) ) {
5b6c6a
-#ifdef LDAP_R_COMPILE
5b6c6a
-					ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
5b6c6a
-#endif
5b6c6a
-					rc = try_read1msg( ld, msgid, all, &lc, result );
5b6c6a
-#ifdef LDAP_R_COMPILE
5b6c6a
-					ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
5b6c6a
-#endif
5b6c6a
 					lc_ready = 1;
5b6c6a
 					break;
5b6c6a
 				}
5b6c6a
@@ -319,7 +306,11 @@ wait4msg(
5b6c6a
 				if ( rc == -1 ) {
5b6c6a
 					rc = LDAP_MSG_X_KEEP_LOOKING;	/* select interrupted: loop */
5b6c6a
 				} else {
5b6c6a
-					rc = LDAP_MSG_X_KEEP_LOOKING;
5b6c6a
+					lc_ready = 1;
5b6c6a
+				}
5b6c6a
+			}
5b6c6a
+			if ( lc_ready ) {
5b6c6a
+				rc = LDAP_MSG_X_KEEP_LOOKING;
5b6c6a
 #ifdef LDAP_R_COMPILE
5b6c6a
 					ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
5b6c6a
 #endif
5b6c6a
@@ -335,38 +326,43 @@ wait4msg(
5b6c6a
 					ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
5b6c6a
 #endif
5b6c6a
 					for ( lc = ld->ld_conns;
5b6c6a
-						rc == LDAP_MSG_X_KEEP_LOOKING && lc != NULL; )
5b6c6a
+						rc == LDAP_MSG_X_KEEP_LOOKING && lc != NULL;
5b6c6a
+						lc = nextlc )
5b6c6a
 					{
5b6c6a
 						if ( lc->lconn_status == LDAP_CONNST_CONNECTED &&
5b6c6a
 							ldap_is_read_ready( ld, lc->lconn_sb ))
5b6c6a
 						{
5b6c6a
+							/* Don't let it get freed out from under us */
5b6c6a
+							++lc->lconn_refcnt;
5b6c6a
 #ifdef LDAP_R_COMPILE
5b6c6a
 							ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
5b6c6a
 #endif
5b6c6a
-							rc = try_read1msg( ld, msgid, all, &lc, result );
5b6c6a
+							rc = try_read1msg( ld, msgid, all, lc, result );
5b6c6a
+							nextlc = lc->lconn_next;
5b6c6a
+
5b6c6a
+							/* Only take locks if we're really freeing */
5b6c6a
+							if ( lc->lconn_refcnt <= 1 ) {
5b6c6a
 #ifdef LDAP_R_COMPILE
5b6c6a
-							ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
5b6c6a
+								ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
5b6c6a
 #endif
5b6c6a
-							if ( lc == NULL ) {
5b6c6a
-								/* if lc gets free()'d,
5b6c6a
-								 * there's no guarantee
5b6c6a
-								 * lc->lconn_next is still
5b6c6a
-								 * sane; better restart
5b6c6a
-								 * (ITS#4405) */
5b6c6a
-								lc = ld->ld_conns;
5b6c6a
-
5b6c6a
-								/* don't get to next conn! */
5b6c6a
-								break;
5b6c6a
+								ldap_free_connection( ld, lc, 0, 1 );
5b6c6a
+#ifdef LDAP_R_COMPILE
5b6c6a
+								ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
5b6c6a
+#endif
5b6c6a
+							} else {
5b6c6a
+								--lc->lconn_refcnt;
5b6c6a
 							}
5b6c6a
+#ifdef LDAP_R_COMPILE
5b6c6a
+							ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex );
5b6c6a
+#endif
5b6c6a
+						} else {
5b6c6a
+							/* next conn */
5b6c6a
+							nextlc = lc->lconn_next;
5b6c6a
 						}
5b6c6a
-
5b6c6a
-						/* next conn */
5b6c6a
-						lc = lc->lconn_next;
5b6c6a
 					}
5b6c6a
 #ifdef LDAP_R_COMPILE
5b6c6a
 					ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex );
5b6c6a
 #endif
5b6c6a
-				}
5b6c6a
 			}
5b6c6a
 		}
5b6c6a
 
5b6c6a
@@ -380,7 +376,6 @@ wait4msg(
5b6c6a
 			if ( tv0.tv_sec <= delta_time ) {
5b6c6a
 				rc = 0;	/* timed out */
5b6c6a
 				ld->ld_errno = LDAP_TIMEOUT;
5b6c6a
-				break;
5b6c6a
 			}
5b6c6a
 			tv0.tv_sec -= delta_time;
5b6c6a
 			tv.tv_sec = tv0.tv_sec;
5b6c6a
@@ -400,7 +395,7 @@ try_read1msg(
5b6c6a
 	LDAP *ld,
5b6c6a
 	ber_int_t msgid,
5b6c6a
 	int all,
5b6c6a
-	LDAPConn **lcp,
5b6c6a
+	LDAPConn *lc,
5b6c6a
 	LDAPMessage **result )
5b6c6a
 {
5b6c6a
 	BerElement	*ber;
5b6c6a
@@ -410,7 +405,6 @@ try_read1msg(
5b6c6a
 	ber_len_t	len;
5b6c6a
 	int		foundit = 0;
5b6c6a
 	LDAPRequest	*lr, *tmplr;
5b6c6a
-	LDAPConn	*lc;
5b6c6a
 	BerElement	tmpber;
5b6c6a
 	int		rc, refer_cnt, hadref, simple_request, err;
5b6c6a
 	ber_int_t	lderr;
5b6c6a
@@ -431,14 +425,11 @@ try_read1msg(
5b6c6a
 	}	v3ref;
5b6c6a
 
5b6c6a
 	assert( ld != NULL );
5b6c6a
-	assert( lcp != NULL );
5b6c6a
-	assert( *lcp != NULL );
5b6c6a
+	assert( lc != NULL );
5b6c6a
 	
5b6c6a
 	Debug( LDAP_DEBUG_TRACE, "read1msg: ld %p msgid %d all %d\n",
5b6c6a
 		(void *)ld, msgid, all );
5b6c6a
 
5b6c6a
-	lc = *lcp;
5b6c6a
-
5b6c6a
 retry:
5b6c6a
 	if ( lc->lconn_ber == NULL ) {
5b6c6a
 		lc->lconn_ber = ldap_alloc_ber_with_options(ld);
5b6c6a
@@ -839,14 +830,8 @@ lr->lr_res_matched ? lr->lr_res_matched 
5b6c6a
 			}
5b6c6a
 
5b6c6a
 			if ( lc != NULL ) {
5b6c6a
-#ifdef LDAP_R_COMPILE
5b6c6a
-				ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
5b6c6a
-#endif
5b6c6a
-				ldap_free_connection( ld, lc, 0, 1 );
5b6c6a
-#ifdef LDAP_R_COMPILE
5b6c6a
-				ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
5b6c6a
-#endif
5b6c6a
-				lc = *lcp = NULL;
5b6c6a
+				--lc->lconn_refcnt;
5b6c6a
+				lc = NULL;
5b6c6a
 			}
5b6c6a
 		}
5b6c6a
 	}