]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Don't loop through active requests every 5 seconds, looking for timeouts.
authorTimo Sirainen <tss@iki.fi>
Fri, 19 Feb 2010 02:20:25 +0000 (04:20 +0200)
committerTimo Sirainen <tss@iki.fi>
Fri, 19 Feb 2010 02:20:25 +0000 (04:20 +0200)
--HG--
branch : HEAD

src/auth/auth-client-connection.c
src/auth/auth-request-handler.c
src/auth/auth-request-handler.h
src/auth/auth-request.c
src/auth/auth-request.h

index b42728212ffb75999b12ca4604e437350d732fc1..77a94b7ded7ef704ad95133cf89274a61386d01c 100644 (file)
@@ -24,7 +24,6 @@
 #define OUTBUF_THROTTLE_SIZE (1024*50)
 
 static ARRAY_DEFINE(auth_client_connections, struct auth_client_connection *);
-static struct timeout *to_clients;
 
 static void auth_client_connection_unref(struct auth_client_connection **_conn);
 static void auth_client_input(struct auth_client_connection *conn);
@@ -363,24 +362,9 @@ auth_client_connection_lookup(unsigned int pid)
        return NULL;
 }
 
-static void request_timeout(void *context ATTR_UNUSED)
-{
-       struct auth_client_connection *const *clients;
-
-       array_foreach(&auth_client_connections, clients) {
-               struct auth_client_connection *client = *clients;
-
-               if (client->request_handler != NULL) {
-                       auth_request_handler_check_timeouts(
-                               client->request_handler);
-               }
-       }
-}
-
 void auth_client_connections_init(void)
 {
        i_array_init(&auth_client_connections, 16);
-       to_clients = timeout_add(5000, request_timeout, NULL);
 }
 
 void auth_client_connections_deinit(void)
@@ -388,9 +372,6 @@ void auth_client_connections_deinit(void)
        struct auth_client_connection **clients;
        unsigned int i, count;
 
-       if (to_clients != NULL)
-               timeout_remove(&to_clients);
-
        clients = array_get_modifiable(&auth_client_connections, &count);
        for (i = count; i > 0; i--)
                auth_client_connection_destroy(&clients[i-1]);
index 1c4fa2ef8b485b2a5e58928a3ed30563ef64a7de..7fc54235b76a4d2a103a815909b54c95e0d0ae00 100644 (file)
@@ -96,25 +96,12 @@ void auth_request_handler_set(struct auth_request_handler *handler,
 static void auth_request_handler_remove(struct auth_request_handler *handler,
                                        struct auth_request *request)
 {
+       i_assert(request->handler == handler);
+
        hash_table_remove(handler->requests, POINTER_CAST(request->id));
        auth_request_unref(&request);
 }
 
-void auth_request_handler_check_timeouts(struct auth_request_handler *handler)
-{
-       struct hash_iterate_context *iter;
-       void *key, *value;
-
-       iter = hash_table_iterate_init(handler->requests);
-       while (hash_table_iterate(iter, &key, &value)) {
-               struct auth_request *request = value;
-
-               if (request->last_access + AUTH_REQUEST_TIMEOUT < ioloop_time)
-                       auth_request_handler_remove(handler, request);
-       }
-       hash_table_iterate_deinit(&iter);
-}
-
 static void get_client_extra_fields(struct auth_request *request,
                                    struct auth_stream_reply *reply)
 {
@@ -192,7 +179,7 @@ auth_request_handle_failure(struct auth_request *request,
        auth_penalty_update(request->auth->penalty, request,
                            request->last_penalty + 1);
 
-       request->last_access = ioloop_time;
+       auth_request_refresh_last_access(request);
        aqueue_append(auth_failures, &request);
        if (to_auth_failures == NULL) {
                to_auth_failures =
@@ -290,6 +277,11 @@ static void auth_request_handler_auth_fail(struct auth_request_handler *handler,
        auth_request_handler_remove(handler, request);
 }
 
+static void auth_request_timeout(struct auth_request *request)
+{
+       auth_request_handler_remove(request->handler, request);
+}
+
 static void auth_request_penalty_finish(struct auth_request *request)
 {
        timeout_remove(&request->to_penalty);
@@ -343,6 +335,7 @@ bool auth_request_handler_auth_begin(struct auth_request_handler *handler,
        }
 
        request = auth_request_new(handler->auth, mech, auth_callback, handler);
+       request->handler = handler;
        request->connect_uid = handler->connect_uid;
        request->client_pid = handler->client_pid;
        request->id = id;
@@ -383,6 +376,8 @@ bool auth_request_handler_auth_begin(struct auth_request_handler *handler,
                return FALSE;
        }
 
+       request->to_abort = timeout_add(AUTH_REQUEST_TIMEOUT * 1000,
+                                       auth_request_timeout, request);
        hash_table_insert(handler->requests, POINTER_CAST(id), request);
 
        if (request->auth->set->ssl_require_client_cert &&
index d81abfb8f3c75dc72197fa1c750072cb8202b807..b580677b476671e5d7a1c37c73f2bee7c4a65189 100644 (file)
@@ -30,8 +30,6 @@ void auth_request_handler_set(struct auth_request_handler *handler,
                              unsigned int connect_uid,
                              unsigned int client_pid);
 
-void auth_request_handler_check_timeouts(struct auth_request_handler *handler);
-
 bool auth_request_handler_auth_begin(struct auth_request_handler *handler,
                                     const char *args);
 bool auth_request_handler_auth_continue(struct auth_request_handler *handler,
index 7e3432d3e910533850e09e038d0f85f401be804e..d2fef0ce4eea3db5867e7686d7913bfb536dbf22 100644 (file)
@@ -62,6 +62,7 @@ struct auth_request *auth_request_new_dummy(struct auth *auth)
 
        auth_request->refcount = 1;
        auth_request->last_access = ioloop_time;
+
        auth_request->auth = auth;
        auth_request->passdb = auth->passdbs;
        auth_request->userdb = auth->userdbs;
@@ -82,7 +83,7 @@ void auth_request_success(struct auth_request *request,
 
        request->state = AUTH_REQUEST_STATE_FINISHED;
        request->successful = TRUE;
-       request->last_access = ioloop_time;
+       auth_request_refresh_last_access(request);
        request->callback(request, AUTH_CLIENT_RESULT_SUCCESS,
                          data, data_size);
 }
@@ -92,7 +93,7 @@ void auth_request_fail(struct auth_request *request)
        i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
 
        request->state = AUTH_REQUEST_STATE_FINISHED;
-       request->last_access = ioloop_time;
+       auth_request_refresh_last_access(request);
        request->callback(request, AUTH_CLIENT_RESULT_FAILURE, NULL, 0);
 }
 
@@ -116,6 +117,8 @@ void auth_request_unref(struct auth_request **_request)
        if (--request->refcount > 0)
                return;
 
+       if (request->to_abort != NULL)
+               timeout_remove(&request->to_abort);
        if (request->to_penalty != NULL)
                timeout_remove(&request->to_penalty);
 
@@ -221,7 +224,7 @@ void auth_request_continue(struct auth_request *request,
 {
        i_assert(request->state == AUTH_REQUEST_STATE_MECH_CONTINUE);
 
-       request->last_access = ioloop_time;
+       auth_request_refresh_last_access(request);
        request->mech->auth_continue(request, data, data_size);
 }
 
@@ -1561,3 +1564,10 @@ void auth_request_log_error(struct auth_request *auth_request,
        } T_END;
        va_end(va);
 }
+
+void auth_request_refresh_last_access(struct auth_request *request)
+{
+       request->last_access = ioloop_time;
+       if (request->to_abort != NULL)
+               timeout_reset(request->to_abort);
+}
index c9e011009180e079a8f34a4e7dc2b1ef766091f3..580939e3acbe4737555fa91bb12e5c4fec9fd8c8 100644 (file)
@@ -55,6 +55,7 @@ struct auth_request {
        struct auth_stream_reply *userdb_reply;
 
        const struct mech_module *mech;
+       struct auth_request_handler *handler;
        struct auth *auth;
         struct auth_passdb *passdb;
         struct auth_userdb *userdb;
@@ -68,7 +69,7 @@ struct auth_request {
        struct ip_addr local_ip, remote_ip;
        unsigned int local_port, remote_port;
 
-       struct timeout *to_penalty;
+       struct timeout *to_abort, *to_penalty;
        unsigned int last_penalty;
        unsigned int initial_response_len;
        const unsigned char *initial_response;
@@ -195,4 +196,6 @@ void auth_request_set_credentials(struct auth_request *request,
 void auth_request_userdb_callback(enum userdb_result result,
                                  struct auth_request *request);
 
+void auth_request_refresh_last_access(struct auth_request *request);
+
 #endif