Implement reconnect when LDAP connection goes down

main
Jiri Hruska 11 years ago
parent 9b192fee53
commit 007ef91db1
  1. 55
      ngx_http_auth_ldap_module.c

@ -134,6 +134,7 @@ typedef struct ngx_http_auth_ldap_connection {
ngx_log_t *log;
ngx_http_auth_ldap_server_t *server;
ngx_peer_connection_t conn;
ngx_event_t reconnect_event;
ngx_queue_t queue;
ngx_http_auth_ldap_ctx_t *rctx;
@ -916,23 +917,38 @@ static Sockbuf_IO ngx_http_auth_ldap_sbio =
static void
ngx_http_auth_ldap_close_connection(ngx_http_auth_ldap_connection_t *c)
{
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Closing connection");
ngx_queue_t *q;
if (c->ld) {
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Unbinding from the server");
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Unbinding from the server \"%V\")",
&c->server->url);
ldap_unbind_ext(c->ld, NULL, NULL);
/* Unbind is always synchronous, even though the function name does not end with an '_s'. */
c->ld = NULL;
}
if (c->conn.connection) {
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Closing connection fd=%d",
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Closing connection (fd=%d)",
c->conn.connection->fd);
ngx_close_connection(c->conn.connection);
c->conn.connection = NULL;
}
q = ngx_queue_head(&c->server->free_connections);
while (q != ngx_queue_sentinel(&c->server->free_connections)) {
if (q == &c->queue) {
ngx_queue_remove(q);
break;
}
q = ngx_queue_next(q);
}
c->rctx = NULL;
c->state = STATE_DISCONNECTED;
if (c->state != STATE_DISCONNECTED) {
c->state = STATE_DISCONNECTED;
ngx_add_timer(&c->reconnect_event, 10000); /* TODO: Reconnect timeout */
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Connection scheduled for reconnection in 10000 ms");
}
}
static void
@ -1114,6 +1130,12 @@ ngx_http_auth_ldap_read_handler(ngx_event_t *rev)
conn = ((ngx_connection_t *)rev->data)->data;
c = conn->data;
if (c->ld == NULL) {
ngx_log_error(NGX_LOG_INFO, c->log, 0, "http_auth_ldap: Could not connect");
ngx_http_auth_ldap_close_connection(c);
return;
}
if (rev->timedout) {
ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT, "http_auth_ldap: Request timed out (state=%d)", c->state);
conn->connection->timedout = 1;
@ -1237,6 +1259,9 @@ ngx_http_auth_ldap_connect(ngx_http_auth_ldap_connection_t *c)
addr = &c->server->parsed_url.addrs[ngx_random() % c->server->parsed_url.naddrs];
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "http_auth_ldap: Connecting to LDAP server \"%V\".",
&addr->name);
conn = &c->conn;
conn->data = c;
conn->sockaddr = addr->sockaddr;
@ -1251,6 +1276,7 @@ ngx_http_auth_ldap_connect(ngx_http_auth_ldap_connection_t *c)
if (rc == NGX_ERROR || rc == NGX_BUSY || rc == NGX_DECLINED) {
ngx_log_error(NGX_LOG_ERR, c->log, 0, "http_auth_ldap: Unable to connect to LDAP server \"%V\".",
&addr->name);
ngx_add_timer(&c->reconnect_event, 10000); /* TODO: Reconnect timeout */
return;
}
@ -1269,6 +1295,14 @@ ngx_http_auth_ldap_connection_cleanup(void *data)
ngx_http_auth_ldap_close_connection((ngx_http_auth_ldap_connection_t *) data);
}
static void
ngx_http_auth_ldap_reconnect_handler(ngx_event_t *ev)
{
ngx_connection_t *conn = ev->data;
ngx_http_auth_ldap_connection_t *c = conn->data;
ngx_http_auth_ldap_connect(c);
}
static ngx_int_t
ngx_http_auth_ldap_init_connections(ngx_cycle_t *cycle)
{
@ -1276,6 +1310,7 @@ ngx_http_auth_ldap_init_connections(ngx_cycle_t *cycle)
ngx_http_auth_ldap_main_conf_t *halmcf;
ngx_http_auth_ldap_server_t *server;
ngx_pool_cleanup_t *cleanup;
ngx_connection_t *dummy_conn;
ngx_uint_t i, j;
ngx_int_t rc;
int option;
@ -1302,13 +1337,23 @@ ngx_http_auth_ldap_init_connections(ngx_cycle_t *cycle)
for (j = 0; j < server->connections; j++) {
c = ngx_pcalloc(cycle->pool, sizeof(ngx_http_auth_ldap_connection_t));
cleanup = ngx_pool_cleanup_add(cycle->pool, 0);
if (c == NULL || cleanup == NULL) {
dummy_conn = ngx_pcalloc(cycle->pool, sizeof(ngx_connection_t));
if (c == NULL || cleanup == NULL || dummy_conn == NULL) {
return NGX_ERROR;
}
c->log = cycle->log;
c->server = server;
c->state = STATE_DISCONNECTED;
/* Various debug logging around timer management assume that the field
'data' in ngx_event_t is a pointer to ngx_connection_t, therefore we
have a dummy such structure around so that it does not crash etc. */
dummy_conn->data = c;
c->reconnect_event.log = c->log;
c->reconnect_event.data = dummy_conn;
c->reconnect_event.handler = ngx_http_auth_ldap_reconnect_handler;
ngx_http_auth_ldap_connect(c);
cleanup->handler = &ngx_http_auth_ldap_connection_cleanup;

Loading…
Cancel
Save