dovecot-2.0: lib-master: Login client connection wasn't closed o...

dovecot at dovecot.org dovecot at dovecot.org
Wed Apr 7 04:20:57 EEST 2010


details:   http://hg.dovecot.org/dovecot-2.0/rev/b93ae980b66b
changeset: 11099:b93ae980b66b
user:      Timo Sirainen <tss at iki.fi>
date:      Wed Apr 07 04:01:31 2010 +0300
description:
lib-master: Login client connection wasn't closed on some error conditions.

diffstat:

 src/lib-master/master-login.c |  35 +++++++++++++++++++----------------
 1 files changed, 19 insertions(+), 16 deletions(-)

diffs (109 lines):

diff -r 9efddc9abfce -r b93ae980b66b src/lib-master/master-login.c
--- a/src/lib-master/master-login.c	Wed Apr 07 03:45:48 2010 +0300
+++ b/src/lib-master/master-login.c	Wed Apr 07 04:01:31 2010 +0300
@@ -17,6 +17,9 @@
 
 #define MASTER_LOGIN_POSTLOGIN_TIMEOUT_MSECS (60*1000)
 
+#define master_login_conn_is_closed(conn) \
+	((conn)->output == NULL)
+
 struct master_login_connection {
 	struct master_login_connection *prev, *next;
 
@@ -47,7 +50,7 @@
 	unsigned int stopping:1;
 };
 
-static void master_login_conn_deinit(struct master_login_connection **_conn);
+static void master_login_conn_close(struct master_login_connection *conn);
 static void master_login_conn_unref(struct master_login_connection **_conn);
 
 struct master_login *
@@ -83,7 +86,8 @@
 	while (login->conns != NULL) {
 		struct master_login_connection *conn = login->conns;
 
-		master_login_conn_deinit(&conn);
+		master_login_conn_close(conn);
+		master_login_conn_unref(&conn);
 	}
 	i_free(login->postlogin_socket_path);
 	i_free(login);
@@ -165,6 +169,10 @@
 			i_error("close(fd_read client) failed: %m");
 	}
 
+	/* FIXME: currently we create a separate connection for each request,
+	   so close the connection after we're done with this client */
+	if (!master_login_conn_is_closed(client->conn))
+		master_login_conn_unref(&client->conn);
 	master_login_conn_unref(&client->conn);
 	i_free(client);
 }
@@ -172,8 +180,7 @@
 static void master_login_auth_finish(struct master_login_client *client,
 				     const char *const *auth_args)
 {
-	struct master_login_connection *conn = client->conn;
-	struct master_login *login = conn->login;
+	struct master_login *login = client->conn->login;
 	struct master_service *service = login->service;
 	bool close_sockets;
 
@@ -192,8 +199,6 @@
 		/* try stopping again */
 		master_login_stop(login);
 	}
-	/* FIXME: currently we create a separate connection for each request */
-	master_login_conn_deinit(&conn);
 
 	client->fd = -1;
 	master_login_client_free(&client);
@@ -368,8 +373,10 @@
 
 	ret = master_login_conn_read_request(conn, &req, data, &client_fd);
 	if (ret <= 0) {
-		if (ret < 0)
-			master_login_conn_deinit(&conn);
+		if (ret < 0) {
+			master_login_conn_close(conn);
+			master_login_conn_unref(&conn);
+		}
 		if (client_fd != -1) {
 			if (close(client_fd) < 0)
 				i_error("close(fd_read client) failed: %m");
@@ -411,14 +418,10 @@
 	master_service_io_listeners_remove(login->service);
 }
 
-static void master_login_conn_deinit(struct master_login_connection **_conn)
+static void master_login_conn_close(struct master_login_connection *conn)
 {
-	struct master_login_connection *conn = *_conn;
-
-	*_conn = NULL;
-
-	if (conn->output == NULL) {
-		/* already deinitialized */
+	if (master_login_conn_is_closed(conn)) {
+		/* already closed */
 		return;
 	}
 
@@ -433,7 +436,6 @@
 
 	conn->login->service->login_authenticating = FALSE;
 	master_service_io_listeners_add(conn->login->service);
-	master_login_conn_unref(&conn);
 }
 
 static void master_login_conn_unref(struct master_login_connection **_conn)
@@ -446,6 +448,7 @@
 		return;
 
 	*_conn = NULL;
+	master_login_conn_close(conn);
 	o_stream_unref(&conn->output);
 	i_free(conn);
 }


More information about the dovecot-cvs mailing list