mirror of
https://github.com/mainnika/nginx-auth-ldap.git
synced 2026-05-22 15:53:39 +00:00
Implement reconnect when LDAP connection goes down
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user