Blame SOURCES/openldap-chase-referral.patch

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