summaryrefslogtreecommitdiff
path: root/mail/dbmail/files/patch-0009-Rework-temporary-connection-failures
diff options
context:
space:
mode:
Diffstat (limited to 'mail/dbmail/files/patch-0009-Rework-temporary-connection-failures')
-rw-r--r--mail/dbmail/files/patch-0009-Rework-temporary-connection-failures162
1 files changed, 162 insertions, 0 deletions
diff --git a/mail/dbmail/files/patch-0009-Rework-temporary-connection-failures b/mail/dbmail/files/patch-0009-Rework-temporary-connection-failures
new file mode 100644
index 000000000000..8d5486fdfd8b
--- /dev/null
+++ b/mail/dbmail/files/patch-0009-Rework-temporary-connection-failures
@@ -0,0 +1,162 @@
+From 9d093f76a82c88647df1cd0ef08b3e8f82e26abb Mon Sep 17 00:00:00 2001
+From: Alan Hicks <ahicks@p-o.co.uk>
+Date: Fri, 30 Sep 2016 17:17:05 +0100
+Subject: [PATCH 09/33] Rework temporary connection failures
+
+---
+ src/modules/authldap.c | 102 ++++++++++++++++++++++++++++++++-----------------
+ 1 file changed, 67 insertions(+), 35 deletions(-)
+
+diff --git src/modules/authldap.c src/modules/authldap.c
+index 19802c8..2073768 100644
+--- src/modules/authldap.c
++++ src/modules/authldap.c
+@@ -110,18 +110,48 @@ static gpointer authldap_once(gpointer UNUSED data)
+ return (gpointer)NULL;
+ }
+
+-/*
+- lookup thread-local ldap connection
+-*/
++/*
++ * ldap_con_get()
++ *
++ * Lookup thread-local ldap connection and bind using config credentials
++ * retrying a few times if the server is temporarily unavailable
++ *
++ * returns connection on success, NULL on failure
++ */
+ static LDAP * ldap_con_get(void)
+ {
+- LDAP * c = (LDAP *)g_static_private_get(&ldap_conn_key);
+- if (! c) {
+- authldap_connect();
+- c = (LDAP *)g_static_private_get(&ldap_conn_key);
++ LDAP * ld = (LDAP *)g_static_private_get(&ldap_conn_key);
++ if (ld) {
++ TRACE(TRACE_DEBUG, "connection [%p]", ld);
++ return ld;
+ }
+- TRACE(TRACE_DEBUG, "connection [%p]", c);
+- return c;
++ int c = 0;
++ int err = -1; // Start wanting success
++ while (err != 0 && c++ < 5) {
++ // Loop until success or too many retries
++ TRACE(TRACE_DEBUG, "No connection trying [%d]", c);
++
++ err = authldap_connect();
++
++ switch (err) {
++ case LDAP_SUCCESS:
++ ld = (LDAP *)g_static_private_get(&ldap_conn_key);
++ TRACE(TRACE_DEBUG, "connection [%p]", ld);
++ break;
++ case LDAP_SERVER_DOWN:
++ TRACE(TRACE_WARNING, "LDAP gone away: %s. Trying to reconnect(%d/5).", ldap_err2string(err),c);
++ sleep(2); // reconnect failed. wait before trying again
++ break;
++ default:
++ TRACE(TRACE_ERR, "LDAP error(%d): %s", err, ldap_err2string(err));
++ break;
++ }
++ }
++ if (! ld) {
++ TRACE(TRACE_ERR, "Unable to connect to LDAP giving up");
++ }
++ TRACE(TRACE_DEBUG, "connection [%p]", ld);
++ return ld;
+ }
+
+ /*
+@@ -140,6 +170,13 @@ static void authldap_free(gpointer data)
+ sigaction(SIGPIPE, &oldact, 0);
+ }
+
++/*
++ * auth_ldap_bind()
++ *
++ * Bind to server using config credentials
++ *
++ * returns 0 on success, -1 on failure
++ */
+ static int auth_ldap_bind(void)
+ {
+ int err;
+@@ -153,7 +190,6 @@ static int auth_ldap_bind(void)
+ }
+
+ return 0;
+-
+ }
+
+ /*
+@@ -213,44 +249,40 @@ static int authldap_connect(void)
+ return auth_ldap_bind();
+ }
+
+-static int authldap_reconnect(void)
+-{
+- LDAP *c;
+- if ((c = ldap_con_get())) authldap_free((gpointer)c);
+- return authldap_connect();
+-}
+-
++/*
++ * authldap_search()
++ *
++ * Perform an LDAP search
++ *
++ * returns search results on success, NULL on failure
++ */
+ static LDAPMessage * authldap_search(const gchar *query)
+ {
+ LDAPMessage *ldap_res;
+ int _ldap_attrsonly = 0;
+ char **_ldap_attrs = NULL;
+- int c=0, err;
++ int err;
+ LDAP *_ldap_conn;
+
+ g_return_val_if_fail(query!=NULL, NULL);
+
+ _ldap_conn = ldap_con_get();
+
+- while (c++ < 5) {
+- TRACE(TRACE_DEBUG, " [%s]", query);
+- err = ldap_search_s(_ldap_conn, _ldap_cfg.base_dn, _ldap_cfg.scope_int,
+- query, _ldap_attrs, _ldap_attrsonly, &ldap_res);
++ TRACE(TRACE_DEBUG, " [%s]", query);
++ err = ldap_search_s(_ldap_conn, _ldap_cfg.base_dn, _ldap_cfg.scope_int,
++ query, _ldap_attrs, _ldap_attrsonly, &ldap_res);
+
+- if (! err)
+- return ldap_res;
++ if (! err)
++ return ldap_res;
+
+- switch (err) {
+- case LDAP_SERVER_DOWN:
+- TRACE(TRACE_WARNING, "LDAP gone away: %s. Try to reconnect(%d/5).", ldap_err2string(err),c);
+- if (authldap_reconnect())
+- sleep(2); // reconnect failed. wait before trying again
+- break;
+- default:
+- TRACE(TRACE_ERR, "LDAP error(%d): %s", err, ldap_err2string(err));
+- return NULL;
+- break;
+- }
++ switch (err) {
++ case LDAP_SERVER_DOWN:
++ TRACE(TRACE_WARNING, "LDAP gone away: %s).", ldap_err2string(err));
++ break;
++ default:
++ TRACE(TRACE_ERR, "LDAP error(%d): %s", err, ldap_err2string(err));
++ return NULL;
++ break;
+ }
+
+ TRACE(TRACE_EMERG,"unrecoverable error while talking to ldap server");
+--
+2.10.1 (Apple Git-78)
+