Mercurial > dovecot > core-2.2
changeset 11388:b8d3c96e61a7 HEAD
lib-master API changed to avoid accidentally leaking client connections.
This change also fixes many such leaks.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 27 May 2010 12:16:36 +0100 |
parents | 7b8bd33c96f9 |
children | a0fccb6367f4 |
files | src/anvil/main.c src/auth/main.c src/config/main.c src/dict/main.c src/director/main.c src/dns/dns-client.c src/dsync/dsync.c src/imap/main.c src/lib-master/master-service.c src/lib-master/master-service.h src/lmtp/main.c src/log/main.c src/login-common/main.c src/pop3/main.c src/ssl-params/main.c src/util/script.c src/util/tcpwrap.c |
diffstat | 17 files changed, 54 insertions(+), 29 deletions(-) [+] |
line wrap: on
line diff
--- a/src/anvil/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/anvil/main.c Thu May 27 12:16:36 2010 +0100 @@ -18,10 +18,11 @@ struct penalty *penalty; static struct io *log_fdpass_io; -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { bool master = conn->listen_fd == MASTER_LISTEN_FD_FIRST; + master_service_client_connection_accept(conn); anvil_connection_create(conn->fd, master, conn->fifo); }
--- a/src/auth/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/auth/main.c Thu May 27 12:16:36 2010 +0100 @@ -182,18 +182,18 @@ pool_unref(&auth_set_pool); } -static void worker_connected(const struct master_service_connection *conn) +static void worker_connected(struct master_service_connection *conn) { if (auth_worker_client != NULL) { i_error("Auth workers can handle only a single client"); - (void)close(conn->fd); return; } + master_service_client_connection_accept(conn); (void)auth_worker_client_create(auth_find_service(NULL), conn->fd); } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { enum auth_socket_type *type; const char *path, *name, *suffix; @@ -245,6 +245,7 @@ default: i_unreached(); } + master_service_client_connection_accept(conn); }
--- a/src/config/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/config/main.c Thu May 27 12:16:36 2010 +0100 @@ -8,8 +8,9 @@ #include "config-parser.h" #include "config-request.h" -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { + master_service_client_connection_accept(conn); config_connection_create(conn->fd); }
--- a/src/dict/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/dict/main.c Thu May 27 12:16:36 2010 +0100 @@ -20,8 +20,9 @@ /* hope that other processes relying on us will die first. */ } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { + master_service_client_connection_accept(conn); dict_connection_create(conn->fd); }
--- a/src/director/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/director/main.c Thu May 27 12:16:36 2010 +0100 @@ -37,7 +37,7 @@ return 0; } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { struct auth_connection *auth; const char *path, *name; @@ -47,9 +47,9 @@ if (conn->fifo) { if (notify_conn != NULL) { i_error("Received another proxy-notify connection"); - (void)close(conn->fd); return; } + master_service_client_connection_accept(conn); notify_conn = notify_connection_init(director, conn->fd); return; } @@ -57,8 +57,8 @@ if (net_getpeername(conn->fd, &ip, &port) == 0 && (IPADDR_IS_V4(&ip) || IPADDR_IS_V6(&ip))) { /* TCP/IP connection - this is another director */ - if (director_client_connected(conn->fd, &ip) < 0) - (void)close(conn->fd); + if (director_client_connected(conn->fd, &ip) == 0) + master_service_client_connection_accept(conn); return; } @@ -74,14 +74,15 @@ len = strlen(name); if (len > 6 && strcmp(name + len - 6, "-admin") == 0) { /* doveadm connection */ + master_service_client_connection_accept(conn); (void)doveadm_connection_init(director, conn->fd); } else { /* login connection */ auth = auth_connection_init(auth_socket_path); - if (auth_connection_connect(auth) == 0) + if (auth_connection_connect(auth) == 0) { + master_service_client_connection_accept(conn); login_connection_init(director, conn->fd, auth); - else { - (void)close(conn->fd); + } else { auth_connection_deinit(&auth); } }
--- a/src/dns/dns-client.c Thu May 27 11:36:07 2010 +0100 +++ b/src/dns/dns-client.c Thu May 27 12:16:36 2010 +0100 @@ -115,13 +115,14 @@ master_service_client_connection_destroyed(master_service); } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { if (dns_client != NULL) { i_error("dns-client must be configured with client_limit=1"); - (void)close(conn->fd); return; } + + master_service_client_connection_accept(conn); dns_client = dns_client_create(conn->fd); }
--- a/src/dsync/dsync.c Thu May 27 11:36:07 2010 +0100 +++ b/src/dsync/dsync.c Thu May 27 12:16:36 2010 +0100 @@ -67,7 +67,7 @@ } static void -dsync_connected(const struct master_service_connection *conn ATTR_UNUSED) +dsync_connected(struct master_service_connection *conn ATTR_UNUSED) { i_fatal("Running as service not supported currently"); }
--- a/src/imap/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/imap/main.c Thu May 27 12:16:36 2010 +0100 @@ -276,12 +276,12 @@ } } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { if (master_login == NULL) { /* running standalone, we shouldn't even get here */ - (void)close(conn->fd); } else { + master_service_client_connection_accept(conn); master_login_add(master_login, conn->fd); } }
--- a/src/lib-master/master-service.c Thu May 27 11:36:07 2010 +0100 +++ b/src/lib-master/master-service.c Thu May 27 12:16:36 2010 +0100 @@ -537,6 +537,11 @@ } } +void master_service_client_connection_accept(struct master_service_connection *conn) +{ + conn->accepted = TRUE; +} + void master_service_client_connection_destroyed(struct master_service *service) { /* we can listen again */ @@ -711,6 +716,12 @@ master_status_update(service); service->callback(&conn); + + if (!conn.accepted) { + if (close(conn.fd) < 0) + i_error("close(service connection) failed: %m"); + master_service_client_connection_destroyed(service); + } } static void io_listeners_init(struct master_service *service)
--- a/src/lib-master/master-service.h Thu May 27 11:36:07 2010 +0100 +++ b/src/lib-master/master-service.h Thu May 27 12:16:36 2010 +0100 @@ -29,10 +29,12 @@ unsigned int fifo:1; unsigned int ssl:1; + + unsigned int accepted:1; }; typedef void -master_service_connection_callback_t(const struct master_service_connection *conn); +master_service_connection_callback_t(struct master_service_connection *conn); extern struct master_service *master_service; @@ -109,6 +111,8 @@ /* Send command to anvil process, if we have fd to it. */ void master_service_anvil_send(struct master_service *service, const char *cmd); +/* Call to accept the client connection. Otherwise the connection is closed. */ +void master_service_client_connection_accept(struct master_service_connection *conn); /* Call whenever a client connection is destroyed. */ void master_service_client_connection_destroyed(struct master_service *service);
--- a/src/lmtp/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/lmtp/main.c Thu May 27 12:16:36 2010 +0100 @@ -28,8 +28,9 @@ const char *dns_client_socket_path; struct mail_storage_service_ctx *storage_service; -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { + master_service_client_connection_accept(conn); (void)client_create(conn->fd, conn->fd, conn); }
--- a/src/log/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/log/main.c Thu May 27 12:16:36 2010 +0100 @@ -28,8 +28,9 @@ log_connections_deinit(); } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { + master_service_client_connection_accept(conn); log_connection_create(conn->fd, conn->listen_fd); }
--- a/src/login-common/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/login-common/main.c Thu May 27 12:16:36 2010 +0100 @@ -206,12 +206,14 @@ } } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { const char *access_sockets = global_login_settings->login_access_sockets; struct login_access_lookup *lookup; + master_service_client_connection_accept(conn); + /* make sure we're connected (or attempting to connect) to auth */ auth_client_connect(auth_client);
--- a/src/pop3/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/pop3/main.c Thu May 27 12:16:36 2010 +0100 @@ -172,12 +172,12 @@ } } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { if (master_login == NULL) { /* running standalone, we shouldn't even get here */ - (void)close(conn->fd); } else { + master_service_client_connection_accept(conn); master_login_add(master_login, conn->fd); } }
--- a/src/ssl-params/main.c Thu May 27 11:36:07 2010 +0100 +++ b/src/ssl-params/main.c Thu May 27 12:16:36 2010 +0100 @@ -54,8 +54,9 @@ } } -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { + master_service_client_connection_accept(conn); if (ssl_params->used == 0) { /* waiting for parameter building to finish */ if (!array_is_created(&delayed_fds))
--- a/src/util/script.c Thu May 27 11:36:07 2010 +0100 +++ b/src/util/script.c Thu May 27 12:16:36 2010 +0100 @@ -22,7 +22,7 @@ static const char **exec_args; static bool drop_privileges = FALSE; -static void client_connected(const struct master_service_connection *conn) +static void client_connected(struct master_service_connection *conn) { enum mail_storage_service_flags flags = MAIL_STORAGE_SERVICE_FLAG_NO_PLUGINS; @@ -53,8 +53,6 @@ i_fatal("read() failed: %m"); else i_fatal("read() failed: disconnected"); - (void)close(conn->fd); - return; } if (fd == -1) i_fatal("client fd not received");
--- a/src/util/tcpwrap.c Thu May 27 11:36:07 2010 +0100 +++ b/src/util/tcpwrap.c Thu May 27 12:16:36 2010 +0100 @@ -103,9 +103,10 @@ { if (tcpwrap_client != NULL) { i_error("tcpwrap must be configured with client_limit=1"); - (void)close(conn->fd); return; } + + master_service_client_connection_accept(conn); tcpwrap_client = tcpwrap_client_create(conn->fd); }