dovecot-2.0-sslstream: lib-master: Fixes to handling master-logi...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 13 02:55:44 EET 2010


details:   http://hg.dovecot.org/dovecot-2.0-sslstream/rev/9d13e9f78d52
changeset: 10200:9d13e9f78d52
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Oct 26 23:41:54 2009 -0400
description:
lib-master: Fixes to handling master-login services.

diffstat:

5 files changed, 32 insertions(+), 10 deletions(-)
src/lib-master/master-login-auth.c      |    5 +++++
src/lib-master/master-login-auth.h      |    1 +
src/lib-master/master-login.c           |   24 +++++++++++++++++++-----
src/lib-master/master-service-private.h |    2 ++
src/lib-master/master-service.c         |   10 +++++-----

diffs (177 lines):

diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-login-auth.c
--- a/src/lib-master/master-login-auth.c	Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-login-auth.c	Mon Oct 26 23:41:54 2009 -0400
@@ -288,3 +288,8 @@ void master_login_auth_request(struct ma
 	login_req->context = context;
 	hash_table_insert(auth->requests, POINTER_CAST(id), login_req);
 }
+
+unsigned int master_login_auth_request_count(struct master_login_auth *auth)
+{
+	return hash_table_count(auth->requests);
+}
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-login-auth.h
--- a/src/lib-master/master-login-auth.h	Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-login-auth.h	Mon Oct 26 23:41:54 2009 -0400
@@ -14,5 +14,6 @@ void master_login_auth_request(struct ma
 			       const struct master_auth_request *req,
 			       master_login_auth_request_callback_t *callback,
 			       void *context);
+unsigned int master_login_auth_request_count(struct master_login_auth *auth);
 
 #endif
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-login.c
--- a/src/lib-master/master-login.c	Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-login.c	Mon Oct 26 23:41:54 2009 -0400
@@ -131,7 +131,8 @@ master_login_auth_callback(const char *c
 {
 	struct master_login_client *client = context;
 	struct master_auth_reply reply;
-	struct master_service *service = client->conn->login->service;
+	struct master_login_connection *conn = client->conn;
+	struct master_service *service = conn->login->service;
 	bool close_config;
 
 	memset(&reply, 0, sizeof(reply));
@@ -139,7 +140,7 @@ master_login_auth_callback(const char *c
 	reply.status = auth_args != NULL ? MASTER_AUTH_STATUS_OK :
 		MASTER_AUTH_STATUS_INTERNAL_ERROR;
 	reply.mail_pid = getpid();
-	o_stream_send(client->conn->output, &reply, sizeof(reply));
+	o_stream_send(conn->output, &reply, sizeof(reply));
 
 	if (auth_args == NULL) {
 		if (close(client->fd) < 0)
@@ -148,17 +149,19 @@ master_login_auth_callback(const char *c
 		return;
 	}
 
+	i_assert(service->master_status.available_count > 0);
 	service->master_status.available_count--;
 	master_status_update(service);
 	close_config = service->master_status.available_count == 0 &&
 		service->service_count_left == 1;
 
-	client->conn->login->callback(client, auth_args[0], auth_args+1);
+	conn->login->callback(client, auth_args[0], auth_args+1);
 	i_free(client);
 
 	if (close_config) {
 		/* we're dying as soon as this connection closes. */
 		master_service_close_config_fd(service);
+		master_login_conn_deinit(&conn);
 	}
 }
 
@@ -166,7 +169,9 @@ static void master_login_conn_input(stru
 {
 	struct master_auth_request req;
 	struct master_login_client *client;
+	struct master_login *login = conn->login;
 	unsigned char data[MASTER_AUTH_MAX_DATA_SIZE];
+	unsigned int request_count;
 	int ret, client_fd;
 
 	ret = master_login_conn_read_request(conn, &req, data, &client_fd);
@@ -188,8 +193,11 @@ static void master_login_conn_input(stru
 	client->auth_req = req;
 	memcpy(client->data, data, req.data_size);
 
-	master_login_auth_request(conn->login->auth, &req,
+	master_login_auth_request(login->auth, &req,
 				  master_login_auth_callback, client);
+	request_count = master_login_auth_request_count(login->auth);
+	if (login->service->master_status.available_count <= request_count)
+		io_remove(&conn->io);
 }
 
 void master_login_add(struct master_login *login, int fd)
@@ -203,6 +211,10 @@ void master_login_add(struct master_logi
 	conn->output = o_stream_create_fd(fd, (size_t)-1, FALSE);
 
 	DLLIST_PREPEND(&login->conns, conn);
+
+	/* don't accept more connections. this is mainly a temporary
+	   workaround.. */
+	master_service_io_listeners_remove(login->service);
 }
 
 static void master_login_conn_deinit(struct master_login_connection **_conn)
@@ -213,9 +225,11 @@ static void master_login_conn_deinit(str
 
 	DLLIST_REMOVE(&conn->login->conns, conn);
 
-	io_remove(&conn->io);
+	if (conn->io != NULL)
+		io_remove(&conn->io);
 	o_stream_unref(&conn->output);
 	if (close(conn->fd) < 0)
 		i_error("close(master login) failed: %m");
+	master_service_io_listeners_add(conn->login->service);
 	i_free(conn);
 }
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-service-private.h
--- a/src/lib-master/master-service-private.h	Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-service-private.h	Mon Oct 26 23:41:54 2009 -0400
@@ -62,4 +62,6 @@ void master_status_update(struct master_
 void master_status_update(struct master_service *service);
 void master_service_close_config_fd(struct master_service *service);
 
+void master_service_io_listeners_remove(struct master_service *service);
+
 #endif
diff -r 3e7e08af2991 -r 9d13e9f78d52 src/lib-master/master-service.c
--- a/src/lib-master/master-service.c	Mon Oct 26 22:10:42 2009 -0400
+++ b/src/lib-master/master-service.c	Mon Oct 26 23:41:54 2009 -0400
@@ -39,7 +39,6 @@ struct master_service *master_service;
 struct master_service *master_service;
 
 static void master_service_refresh_login_state(struct master_service *service);
-static void io_listeners_remove(struct master_service *service);
 
 const char *master_service_getopt_string(void)
 {
@@ -265,7 +264,7 @@ bool master_service_parse_option(struct 
 
 static void master_service_error(struct master_service *service)
 {
-	io_listeners_remove(service);
+	master_service_io_listeners_remove(service);
 	if (service->master_status.available_count ==
 	    service->total_available_count || service->die_with_master) {
 		if (service->die_callback == NULL)
@@ -585,7 +584,7 @@ void master_service_deinit(struct master
 
 	*_service = NULL;
 
-	io_listeners_remove(service);
+	master_service_io_listeners_remove(service);
 
 	master_service_close_config_fd(service);
 	if (service->to_die != NULL)
@@ -631,7 +630,7 @@ static void master_service_listen(struct
 		}
 
 		if (service->master_status.available_count == 0) {
-			io_listeners_remove(service);
+			master_service_io_listeners_remove(service);
 			return;
 		}
 	}
@@ -663,6 +662,7 @@ static void master_service_listen(struct
 	if (service->login_connections)
 		close_config = FALSE;
 	else {
+		i_assert(service->master_status.available_count > 0);
 		service->master_status.available_count--;
 		master_status_update(service);
 		close_config = service->master_status.available_count == 0 &&
@@ -715,7 +715,7 @@ void master_service_io_listeners_add(str
 	}
 }
 
-static void io_listeners_remove(struct master_service *service)
+void master_service_io_listeners_remove(struct master_service *service)
 {
 	unsigned int i;
 


More information about the dovecot-cvs mailing list