From: Timo Sirainen Date: Fri, 18 Nov 2011 14:15:24 +0000 (+0200) Subject: auth: Log a warning if auth client disconnects while it still has pending requests. X-Git-Tag: 2.1.rc1~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a7e2c98560cf54dc656711a237cb07da8a5a9ee4;p=thirdparty%2Fdovecot%2Fcore.git auth: Log a warning if auth client disconnects while it still has pending requests. --- diff --git a/src/auth/auth-client-connection.c b/src/auth/auth-client-connection.c index 89242e44e8..43ec1e6513 100644 --- a/src/auth/auth-client-connection.c +++ b/src/auth/auth-client-connection.c @@ -26,6 +26,7 @@ static ARRAY_DEFINE(auth_client_connections, struct auth_client_connection *); +static void auth_client_disconnected(struct auth_client_connection **_conn); static void auth_client_connection_unref(struct auth_client_connection **_conn); static void auth_client_input(struct auth_client_connection *conn); @@ -100,7 +101,7 @@ auth_client_input_cpid(struct auth_client_connection *conn, const char *args) see if the old connection is still there. */ i_assert(old != conn); if (i_stream_read(old->input) == -1) { - auth_client_connection_destroy(&old); + auth_client_disconnected(&old); old = NULL; } } @@ -128,7 +129,7 @@ auth_client_input_cpid(struct auth_client_connection *conn, const char *args) static int auth_client_output(struct auth_client_connection *conn) { if (o_stream_flush(conn->output) < 0) { - auth_client_connection_destroy(&conn); + auth_client_disconnected(&conn); return 1; } @@ -221,7 +222,7 @@ static void auth_client_input(struct auth_client_connection *conn) return; case -1: /* disconnected */ - auth_client_connection_destroy(&conn); + auth_client_disconnected(&conn); return; case -2: /* buffer full */ @@ -314,7 +315,7 @@ auth_client_connection_create(struct auth *auth, int fd, bool login_requests) str_append(str, "\nDONE\n"); if (o_stream_send(conn->output, str_data(str), str_len(str)) < 0) - auth_client_connection_destroy(&conn); + auth_client_disconnected(&conn); return conn; } @@ -356,6 +357,31 @@ void auth_client_connection_destroy(struct auth_client_connection **_conn) auth_client_connection_unref(&conn); } +static void auth_client_disconnected(struct auth_client_connection **_conn) +{ + struct auth_client_connection *conn = *_conn; + unsigned int request_count; + int err; + + *_conn = NULL; + + if (conn->input->stream_errno != 0) + err = conn->input->stream_errno; + else if (conn->output->stream_errno != 0) + err = conn->output->stream_errno; + else + err = 0; + + request_count = conn->request_handler == NULL ? 0 : + auth_request_handler_get_request_count(conn->request_handler); + if (request_count > 0) { + i_warning("auth client %u disconnected with %u " + "pending requests: %s", conn->pid, request_count, + err == 0 ? "EOF" : strerror(err)); + } + auth_client_connection_destroy(&conn); +} + static void auth_client_connection_unref(struct auth_client_connection **_conn) { struct auth_client_connection *conn = *_conn; diff --git a/src/auth/auth-request-handler.c b/src/auth/auth-request-handler.c index 52fef54de7..f13bd1dbb6 100644 --- a/src/auth/auth-request-handler.c +++ b/src/auth/auth-request-handler.c @@ -59,6 +59,12 @@ auth_request_handler_create(auth_request_callback_t *callback, void *context, return handler; } +unsigned int +auth_request_handler_get_request_count(struct auth_request_handler *handler) +{ + return hash_table_count(handler->requests); +} + void auth_request_handler_abort_requests(struct auth_request_handler *handler) { struct hash_iterate_context *iter; diff --git a/src/auth/auth-request-handler.h b/src/auth/auth-request-handler.h index 2d751efb1f..b5cabdff43 100644 --- a/src/auth/auth-request-handler.h +++ b/src/auth/auth-request-handler.h @@ -46,6 +46,8 @@ void auth_request_handler_reply(struct auth_request *request, const void *reply, size_t reply_size); void auth_request_handler_reply_continue(struct auth_request *request, const void *reply, size_t reply_size); +unsigned int +auth_request_handler_get_request_count(struct auth_request_handler *handler); bool auth_request_handler_master_request(struct auth_request_handler *handler, struct auth_master_connection *master, unsigned int id,