changeset 7045:ae0556fb268d HEAD

If LDAP server disconnects the connection and we haven't sent requests for a minute, disconnect silently and don't reconnect until the next auth request comes.
author Timo Sirainen <tss@iki.fi>
date Fri, 28 Dec 2007 19:14:36 +0200
parents b7f037c8ff57
children e74a1d1dca07
files src/auth/db-ldap.c src/auth/db-ldap.h src/auth/passdb-ldap.c
diffstat 3 files changed, 22 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/db-ldap.c	Fri Dec 28 00:50:48 2007 +0200
+++ b/src/auth/db-ldap.c	Fri Dec 28 19:14:36 2007 +0200
@@ -42,6 +42,10 @@
 #  define LDAP_OPT_SUCCESS LDAP_SUCCESS
 #endif
 
+/* If server disconnects us, don't reconnect if no requests have been sent
+   for this many seconds. */
+#define LDAP_IDLE_RECONNECT_SECS 60
+
 struct db_ldap_result_iterate_context {
 	struct ldap_connection *conn;
 	LDAPMessage *entry;
@@ -277,6 +281,7 @@
 		hash_insert(conn->requests, POINTER_CAST(msgid), request);
 	else
 		db_ldap_add_delayed_request(conn, request);
+	conn->last_request_stamp = ioloop_time;
 }
 
 static void ldap_conn_retry_requests(struct ldap_connection *conn)
@@ -395,12 +400,21 @@
 		ldap_msgfree(res);
 	}
 
-	if (ret < 0) {
+	if (ret == 0) {
+		if (!conn->binding)
+			db_ldap_handle_next_delayed_request(conn);
+	} else if (ldap_get_errno(conn) != LDAP_SERVER_DOWN) {
 		i_error("LDAP: ldap_result() failed: %s", ldap_get_error(conn));
 		ldap_conn_reconnect(conn);
+	} else if (hash_count(conn->requests) > 0 ||
+		   ioloop_time - conn->last_request_stamp <
+		   				LDAP_IDLE_RECONNECT_SECS) {
+		i_error("LDAP: Connection lost to LDAP server, reconnecting");
+		ldap_conn_reconnect(conn);
 	} else {
-		if (!conn->binding)
-			db_ldap_handle_next_delayed_request(conn);
+		/* server probably disconnected an idle connection. don't
+		   reconnect until the next request comes. */
+		ldap_conn_close(conn, TRUE);
 	}
 }
 
@@ -516,6 +530,7 @@
 	/* we're binding back to the original DN, not doing an
 	   authentication bind */
 	conn->last_auth_bind = FALSE;
+	conn->last_request_stamp = ioloop_time;
 	return 0;
 }
 
@@ -547,6 +562,7 @@
 		return 0;
 	i_assert(!conn->binding);
 
+	conn->last_request_stamp = ioloop_time;
 	if (conn->ld == NULL) {
 		if (conn->set.uris != NULL) {
 #ifdef LDAP_HAVE_INITIALIZE
--- a/src/auth/db-ldap.h	Fri Dec 28 00:50:48 2007 +0200
+++ b/src/auth/db-ldap.h	Fri Dec 28 19:14:36 2007 +0200
@@ -62,6 +62,7 @@
 
 	struct hash_table *requests;
 	struct ldap_request *delayed_requests_head, *delayed_requests_tail;
+	time_t last_request_stamp;
 
 	char **pass_attr_names, **user_attr_names;
 	struct hash_table *pass_attr_map, *user_attr_map;
--- a/src/auth/passdb-ldap.c	Fri Dec 28 00:50:48 2007 +0200
+++ b/src/auth/passdb-ldap.c	Fri Dec 28 19:14:36 2007 +0200
@@ -4,6 +4,7 @@
 
 #ifdef PASSDB_LDAP
 
+#include "ioloop.h"
 #include "hash.h"
 #include "str.h"
 #include "var-expand.h"
@@ -203,6 +204,7 @@
 		}
 
 		conn->binding = TRUE;
+		conn->last_request_stamp = ioloop_time;
 		hash_insert(conn->requests, POINTER_CAST(msgid), ldap_request);
 
 		auth_request_log_debug(auth_request, "ldap", "bind: dn=%s",