From: Pavel Filipenský Date: Mon, 19 Jan 2026 18:50:37 +0000 (+0100) Subject: s3:libads: Do not reduce the page size in case of immediate timeouts X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52c67b07210dc6ba21ffa538406eb0092ee52717;p=thirdparty%2Fsamba.git s3:libads: Do not reduce the page size in case of immediate timeouts Signed-off-by: Pavel Filipenský Reviewed-by: Andreas Schneider Autobuild-User(master): Andreas Schneider Autobuild-Date(master): Wed Jan 21 11:38:40 UTC 2026 on atb-devel-224 --- diff --git a/source3/libads/ldap_utils.c b/source3/libads/ldap_utils.c index dee6ea42356..fd154c6b6e5 100644 --- a/source3/libads/ldap_utils.c +++ b/source3/libads/ldap_utils.c @@ -52,6 +52,28 @@ static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads, int *num_retries, bool *more_values); +/* + * Do not reduce the page size in case of immediate timeouts. E.g. kernel + * detected broken connection but samba hasn't tried to use the socket yet. + * time() uses resolution in seconds, so it is avoided for timeouts < 1s and + * might be avoided for timeouts < 2s. + */ +static inline void adjust_ldap_page_size(ADS_STRUCT *ads, + time_t start, + time_t end) +{ + if (ads->config.ldap_page_size >= (lp_ldap_page_size() / 4) && + lp_ldap_page_size() > 4 && end - start > 1) + { + int new_page_size = (ads->config.ldap_page_size / 2); + DBG_WARNING("Reducing LDAP page size from %d to %d due to " + "IO_TIMEOUT\n", + ads->config.ldap_page_size, + new_page_size); + ads->config.ldap_page_size = new_page_size; + } +} + /* a wrapper around ldap_search_s that retries depending on the error code this is supposed to catch dropped connections and auto-reconnect @@ -64,6 +86,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind ADS_STATUS status; int count = 3; char *bp; + time_t search_start, search_end; *res = NULL; @@ -83,6 +106,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind /* when binding anonymously, we cannot use the paged search LDAP * control - Guenther */ + search_start = time(NULL); if (ads->auth.flags & ADS_AUTH_ANON_BIND) { status = ads_do_search(ads, bp, scope, expr, attrs, res); } else { @@ -100,13 +124,10 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind char *cred_name = NULL; NTSTATUS ntstatus; - if (NT_STATUS_EQUAL(ads_ntstatus(status), NT_STATUS_IO_TIMEOUT) && - ads->config.ldap_page_size >= (lp_ldap_page_size() / 4) && - lp_ldap_page_size() > 4) { - int new_page_size = (ads->config.ldap_page_size / 2); - DEBUG(1, ("Reducing LDAP page size from %d to %d due to IO_TIMEOUT\n", - ads->config.ldap_page_size, new_page_size)); - ads->config.ldap_page_size = new_page_size; + search_end = time(NULL); + if (NT_STATUS_EQUAL(ads_ntstatus(status), NT_STATUS_IO_TIMEOUT)) + { + adjust_ldap_page_size(ads, search_start, search_end); } if (*res) @@ -162,6 +183,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind /* when binding anonymously, we cannot use the paged search LDAP * control - Guenther */ + search_start = time(NULL); if (ads->auth.flags & ADS_AUTH_ANON_BIND) { status = ads_do_search(ads, bp, scope, expr, attrs, res); } else {