LDAP delay when connected DC goes down

Jeremy Allison jra at samba.org
Tue Jan 11 02:12:00 GMT 2005


On Mon, Jan 10, 2005 at 12:05:52PM -0800, Joe Meadows wrote:
> 
> A couple of us have been looking into a problem that shows up when a 
> Samba server is joined to an ADS domain and the DC that it is connected 
> to becomes unreachable.  We were seeing a long delay (sixteen minutes) 
> before the server would time out and failover to another DC.  We tracked 
> the delay down to the function ads_do_paged_search() which is calling 
> ldap_search_ext_s() without setting a timeout.  I've noticed that the 
> function ads_do_search() also calls ldap_search_ext_s(), but in this 
> case it is given a timeout of ADS_SEARCH_TIMEOUT (10 seconds).
> 
> We modified the code so that ads_do_paged_search() also sets a timeout 
> when calling ldap_search_ext_s().  In this case the timeout is set to 
> lp_ldap_timeout(), which is set by the 'ldap timeout' parameter in 
> smb.conf or defaults to 15 seconds.  With this change in place our 
> testing shows that the problem is effectively fixed.  Samba times out 
> after the specified time and reattaches to the domain using a different 
> DC.  I am curious if not setting the timeout in ads_do_paged_search() 
> was done intentionally and if there is any reason why a timeout here 
> would be a bad thing.  Our testing is focused on this one problem that 
> we're running into and the timeout does seem to fix it, but will this 
> change create problems elsewhere?
> 
> BTW, the 'ldap timeout' in smb.conf currently only controls the 
> *connect* timeout and has no effect on the search timeout.  I also tried 
> to set the search timeout using ldap_set_option but this did not work.  
> The reason turns out to be that for ldap_search_ext_s() the timeout only 
> controls the amount of time that the server will spend searching, but 
> does not affect the local timeout (the time that the client will wait 
> for the results of the search).

Looks correct to me. Can you try this patch, which should cause all
ldap timeouts to be consistent. Thanks,

Jeremy.
-------------- next part --------------
Index: include/ads.h
===================================================================
--- include/ads.h	(revision 4655)
+++ include/ads.h	(working copy)
@@ -76,9 +76,6 @@
 /* time between reconnect attempts */
 #define ADS_RECONNECT_TIME 5
 
-/* timeout on searches */
-#define ADS_SEARCH_TIMEOUT 10
-
 /* ldap control oids */
 #define ADS_PAGE_CTL_OID "1.2.840.113556.1.4.319"
 #define ADS_NO_REFERRALS_OID "1.2.840.113556.1.4.1339"
Index: libads/ldap.c
===================================================================
--- libads/ldap.c	(revision 4655)
+++ libads/ldap.c	(working copy)
@@ -75,20 +75,24 @@
 				    int attrsonly,
 				    LDAPControl **sctrls,
 				    LDAPControl **cctrls,
-				    struct timeval *timeout,
 				    int sizelimit,
 				    LDAPMessage **res )
 {
+	struct timeval timeout;
 	int result;
 
-	/* Setup timeout */
+	/* Setup timeout for the ldap_search_ext_s call - local and remote. */
+	timeout.tv_sec = lp_ldap_timeout();
+	timeout.tv_usec = 0;
+
+	/* Setup alarm timeout.... Do we need both of these ? JRA. */
 	gotalarm = 0;
 	CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
 	alarm(lp_ldap_timeout());
 	/* End setup timeout. */
 
 	result = ldap_search_ext_s(ld, base, scope, filter, attrs,
-				   attrsonly, sctrls, cctrls, timeout,
+				   attrsonly, sctrls, cctrls, &timeout,
 				   sizelimit, res);
 
 	/* Teardown timeout. */
@@ -504,14 +508,14 @@
 
 	rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr, 
 				      search_attrs, 0, controls,
-				      NULL, NULL, LDAP_NO_LIMIT,
+				      NULL, LDAP_NO_LIMIT,
 				      (LDAPMessage **)res);
 
 	ber_free(cookie_be, 1);
 	ber_bvfree(cookie_bv);
 
 	if (rc) {
-		DEBUG(3,("ldap_search_with_timeout(%s) -> %s\n", expr,
+		DEBUG(3,("ads_do_paged_search: ldap_search_with_timeout(%s) -> %s\n", expr,
 			 ldap_err2string(rc)));
 		goto done;
 	}
@@ -655,7 +659,6 @@
 			 const char *expr,
 			 const char **attrs, void **res)
 {
-	struct timeval timeout;
 	int rc;
 	char *utf8_expr, *utf8_path, **search_attrs = NULL;
 	TALLOC_CTX *ctx;
@@ -689,15 +692,12 @@
 		}
 	}
 
-	timeout.tv_sec = ADS_SEARCH_TIMEOUT;
-	timeout.tv_usec = 0;
-
 	/* see the note in ads_do_paged_search - we *must* disable referrals */
 	ldap_set_option(ads->ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
 
 	rc = ldap_search_with_timeout(ads->ld, utf8_path, scope, utf8_expr,
 				      search_attrs, 0, NULL, NULL, 
-				      &timeout, LDAP_NO_LIMIT,
+				      LDAP_NO_LIMIT,
 				      (LDAPMessage **)res);
 
 	if (rc == LDAP_SIZELIMIT_EXCEEDED) {


More information about the samba-technical mailing list