]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
auth: Don't disconnect auth-worker during long-running user iterations.
authorTimo Sirainen <tss@iki.fi>
Wed, 12 Mar 2014 12:09:14 +0000 (14:09 +0200)
committerTimo Sirainen <tss@iki.fi>
Wed, 12 Mar 2014 12:09:14 +0000 (14:09 +0200)
src/auth/auth-worker-server.c

index 55adc2786f93f0950f765f7d2f2301dda06f962d..c7900e4ecc3f73e854bc114891c401d03c7de228 100644 (file)
@@ -84,6 +84,8 @@ static bool auth_worker_request_send(struct auth_worker_connection *conn,
        struct const_iovec iov[3];
        unsigned int age_secs = ioloop_time - request->created;
 
+       i_assert(conn->to != NULL);
+
        if (age_secs >= AUTH_WORKER_ABORT_SECS) {
                i_error("Aborting auth request that was queued for %d secs, "
                        "%d left in queue",
@@ -236,7 +238,8 @@ static void auth_worker_destroy(struct auth_worker_connection **_conn,
                io_remove(&conn->io);
        i_stream_destroy(&conn->input);
        o_stream_destroy(&conn->output);
-       timeout_remove(&conn->to);
+       if (conn->to != NULL)
+               timeout_remove(&conn->to);
 
        if (close(conn->fd) < 0)
                i_error("close(auth worker) failed: %m");
@@ -266,7 +269,7 @@ static struct auth_worker_connection *auth_worker_find_free(void)
        return NULL;
 }
 
-static void auth_worker_request_handle(struct auth_worker_connection *conn,
+static bool auth_worker_request_handle(struct auth_worker_connection *conn,
                                       struct auth_worker_request *request,
                                       const char *line)
 {
@@ -281,8 +284,12 @@ static void auth_worker_request_handle(struct auth_worker_connection *conn,
                idle_count++;
        }
 
-       if (!request->callback(line, request->context) && conn->io != NULL)
+       if (!request->callback(line, request->context) && conn->io != NULL) {
+               timeout_remove(&conn->to);
                io_remove(&conn->io);
+               return FALSE;
+       }
+       return TRUE;
 }
 
 static bool auth_worker_error(struct auth_worker_connection *conn)
@@ -376,8 +383,9 @@ static void worker_input(struct auth_worker_connection *conn)
                        continue;
 
                if (conn->request != NULL && id == conn->request->id) {
-                       auth_worker_request_handle(conn, conn->request,
-                                                  line + 1);
+                       if (!auth_worker_request_handle(conn, conn->request,
+                                                       line + 1))
+                               break;
                } else {
                        if (conn->request != NULL) {
                                i_error("BUG: Worker sent reply with id %u, "
@@ -401,6 +409,14 @@ static void worker_input(struct auth_worker_connection *conn)
                auth_worker_request_send_next(conn);
 }
 
+static void worker_input_resume(struct auth_worker_connection *conn)
+{
+       timeout_remove(&conn->to);
+       conn->to = timeout_add(AUTH_WORKER_LOOKUP_TIMEOUT_SECS * 1000,
+                              auth_worker_call_timeout, conn);
+       worker_input(conn);
+}
+
 struct auth_worker_connection *
 auth_worker_call(pool_t pool, const char *username, const char *data,
                 auth_worker_callback_t *callback, void *context)
@@ -440,6 +456,9 @@ void auth_worker_server_resume_input(struct auth_worker_connection *conn)
 {
        if (conn->io == NULL)
                conn->io = io_add(conn->fd, IO_READ, worker_input, conn);
+       if (conn->to != NULL)
+               timeout_remove(&conn->to);
+       conn->to = timeout_add_short(0, worker_input_resume, conn);
 }
 
 void auth_worker_server_init(void)