Skip to content

Commit

Permalink
Rework temporary connection failures
Browse files Browse the repository at this point in the history
  • Loading branch information
alan-hicks authored and pjstevns committed Nov 1, 2016
1 parent 024ba19 commit 9d093f7
Showing 1 changed file with 67 additions and 35 deletions.
102 changes: 67 additions & 35 deletions src/modules/authldap.c
Expand Up @@ -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;
}

/*
Expand All @@ -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;
Expand All @@ -153,7 +190,6 @@ static int auth_ldap_bind(void)
}

return 0;

}

/*
Expand Down Expand Up @@ -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");
Expand Down

0 comments on commit 9d093f7

Please sign in to comment.