diff options
Diffstat (limited to 'mail/dbmail/files/patch-0009-Rework-temporary-connection-failures')
-rw-r--r-- | mail/dbmail/files/patch-0009-Rework-temporary-connection-failures | 162 |
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) + |