Mercurial > dovecot > original-hg > dovecot-1.2
diff src/auth/db-ldap.c @ 3731:0a7beabfe332 HEAD
If LDAP lookup fails because connection gets closed, try retrying it again
after reconnect.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 06 Dec 2005 18:48:20 +0200 |
parents | 0c10475d9968 |
children | 4b6d962485b9 |
line wrap: on
line diff
--- a/src/auth/db-ldap.c Tue Dec 06 17:08:32 2005 +0200 +++ b/src/auth/db-ldap.c Tue Dec 06 18:48:20 2005 +0200 @@ -66,7 +66,7 @@ static struct ldap_connection *ldap_connections = NULL; -static void ldap_conn_close(struct ldap_connection *conn); +static void ldap_conn_close(struct ldap_connection *conn, int flush_requests); static int deref2str(const char *str) { @@ -108,9 +108,7 @@ return ldap_err2string(err); } -void db_ldap_search(struct ldap_connection *conn, const char *base, int scope, - const char *filter, char **attributes, - struct ldap_request *request) +void db_ldap_search(struct ldap_connection *conn, struct ldap_request *request) { int msgid; @@ -121,10 +119,11 @@ } } - msgid = ldap_search(conn->ld, base, scope, filter, attributes, 0); + msgid = ldap_search(conn->ld, request->base, conn->set.ldap_scope, + request->filter, request->attributes, 0); if (msgid == -1) { i_error("LDAP: ldap_search() failed (filter %s): %s", - filter, ldap_get_error(conn)); + request->filter, ldap_get_error(conn)); request->callback(conn, request, NULL); return; } @@ -132,6 +131,41 @@ hash_insert(conn->requests, POINTER_CAST(msgid), request); } +static void ldap_conn_retry_requests(struct ldap_connection *conn) +{ + struct hash_table *old_requests; + struct hash_iterate_context *iter; + void *key, *value; + + i_assert(conn->connected); + + if (hash_size(conn->requests) == 0) + return; + + old_requests = conn->requests; + conn->requests = hash_create(default_pool, conn->pool, 0, NULL, NULL); + + iter = hash_iterate_init(old_requests); + while (hash_iterate(iter, &key, &value)) { + struct ldap_request *request = value; + + i_assert(conn->connected); + db_ldap_search(conn, request); + } + hash_iterate_deinit(iter); + hash_destroy(old_requests); +} + +static void ldap_conn_reconnect(struct ldap_connection *conn) +{ + ldap_conn_close(conn, FALSE); + + if (!db_ldap_connect(conn)) { + /* failed to reconnect. fail all requests. */ + ldap_conn_close(conn, TRUE); + } +} + static void ldap_input(void *context) { struct ldap_connection *conn = context; @@ -154,8 +188,7 @@ if (ret < 0) { i_error("LDAP: ldap_result() failed: %s", ldap_get_error(conn)); - /* reconnect */ - ldap_conn_close(conn); + ldap_conn_reconnect(conn); } return; } @@ -237,22 +270,27 @@ net_set_nonblock(fd, TRUE); conn->io = io_add(fd, IO_READ, ldap_input, conn); + + /* in case there are requests waiting, retry them */ + ldap_conn_retry_requests(conn); return TRUE; } -static void ldap_conn_close(struct ldap_connection *conn) +static void ldap_conn_close(struct ldap_connection *conn, int flush_requests) { struct hash_iterate_context *iter; void *key, *value; - iter = hash_iterate_init(conn->requests); - while (hash_iterate(iter, &key, &value)) { - struct ldap_request *request = value; + if (flush_requests) { + iter = hash_iterate_init(conn->requests); + while (hash_iterate(iter, &key, &value)) { + struct ldap_request *request = value; - request->callback(conn, request, NULL); + request->callback(conn, request, NULL); + } + hash_iterate_deinit(iter); + hash_clear(conn->requests, FALSE); } - hash_iterate_deinit(iter); - hash_clear(conn->requests, FALSE); conn->connected = FALSE; @@ -426,7 +464,7 @@ } } - ldap_conn_close(conn); + ldap_conn_close(conn, TRUE); hash_destroy(conn->requests); if (conn->pass_attr_map != NULL)