dovecot: Support listening multiple sockets. SIGHUP also doesn't...
dovecot at dovecot.org
dovecot at dovecot.org
Tue Jul 3 20:04:32 EEST 2007
details: http://hg.dovecot.org/dovecot/rev/3f2eb1b9c555
changeset: 5887:3f2eb1b9c555
user: Timo Sirainen <tss at iki.fi>
date: Tue Jul 03 20:04:28 2007 +0300
description:
Support listening multiple sockets. SIGHUP also doesn't anymore recreate
listener sockets.
diffstat:
12 files changed, 601 insertions(+), 333 deletions(-)
dovecot-example.conf | 8
src/login-common/main.c | 123 +++++++----
src/master/Makefile.am | 4
src/master/dup2-array.c | 80 +++++++
src/master/dup2-array.h | 13 +
src/master/listener.c | 366 +++++++++++++++++++++++++++++++++++
src/master/listener.h | 7
src/master/login-process.c | 59 +++--
src/master/main.c | 256 ------------------------
src/master/master-login-interface.h | 2
src/master/master-settings.c | 2
src/master/master-settings.h | 14 -
diffs (truncated from 1193 to 300 lines):
diff -r 86f22b84e008 -r 3f2eb1b9c555 dovecot-example.conf
--- a/dovecot-example.conf Tue Jul 03 18:34:31 2007 +0300
+++ b/dovecot-example.conf Tue Jul 03 20:04:28 2007 +0300
@@ -22,10 +22,10 @@
# If you only want to use dovecot-auth, you can set this to "none".
#protocols = imap imaps
-# IP or host address where to listen in for connections. It's not currently
-# possible to specify multiple addresses. "*" listens in all IPv4 interfaces.
-# "[::]" listens in all IPv6 interfaces, but may also listen in all IPv4
-# interfaces depending on the operating system.
+# A space separated list of IP or host addresses where to listen in for
+# connections. "*" listens in all IPv4 interfaces. "[::]" listens in all IPv6
+# interfaces, but may also listen in all IPv4 interfaces depending on the
+# operating system.
#
# If you want to specify ports for each service, you will need to configure
# these settings inside the protocol imap/pop3 { ... } section, so you can
diff -r 86f22b84e008 -r 3f2eb1b9c555 src/login-common/main.c
--- a/src/login-common/main.c Tue Jul 03 18:34:31 2007 +0300
+++ b/src/login-common/main.c Tue Jul 03 20:04:28 2007 +0300
@@ -2,6 +2,7 @@
#include "common.h"
#include "ioloop.h"
+#include "array.h"
#include "lib-signals.h"
#include "randgen.h"
#include "restrict-access.h"
@@ -29,9 +30,11 @@ bool closing_down;
static const char *process_name;
static struct ioloop *ioloop;
-static struct io *io_listen, *io_ssl_listen;
static int main_refcount;
static bool is_inetd, listening;
+
+static ARRAY_DEFINE(listen_ios, struct io *);
+static unsigned int listen_count, ssl_listen_count;
void main_ref(void)
{
@@ -71,14 +74,15 @@ static void sig_die(int signo, void *con
io_loop_stop(ioloop);
}
-static void login_accept(void *context __attr_unused__)
-{
+static void login_accept(void *context)
+{
+ int listen_fd = POINTER_CAST_TO(context, int);
struct ip_addr remote_ip, local_ip;
unsigned int remote_port, local_port;
struct client *client;
int fd;
- fd = net_accept(LOGIN_LISTEN_FD, &remote_ip, &remote_port);
+ fd = net_accept(listen_fd, &remote_ip, &remote_port);
if (fd < 0) {
if (fd < -1)
i_error("accept() failed: %m");
@@ -100,15 +104,16 @@ static void login_accept(void *context _
}
}
-static void login_accept_ssl(void *context __attr_unused__)
-{
+static void login_accept_ssl(void *context)
+{
+ int listen_fd = POINTER_CAST_TO(context, int);
struct ip_addr remote_ip, local_ip;
unsigned int remote_port, local_port;
struct client *client;
struct ssl_proxy *proxy;
int fd, fd_ssl;
- fd = net_accept(LOGIN_SSL_LISTEN_FD, &remote_ip, &remote_port);
+ fd = net_accept(listen_fd, &remote_ip, &remote_port);
if (fd < 0) {
if (fd < -1)
i_error("accept() failed: %m");
@@ -138,7 +143,9 @@ static void login_accept_ssl(void *conte
void main_listen_start(void)
{
- unsigned int current_count;
+ struct io *io;
+ unsigned int i, current_count;
+ int cur_fd;
if (listening)
return;
@@ -156,21 +163,17 @@ void main_listen_start(void)
return;
}
- if (net_getsockname(LOGIN_LISTEN_FD, NULL, NULL) == 0) {
- io_listen = io_add(LOGIN_LISTEN_FD, IO_READ,
- login_accept, NULL);
- }
-
- if (net_getsockname(LOGIN_SSL_LISTEN_FD, NULL, NULL) == 0) {
- if (!ssl_initialized) {
- /* this shouldn't happen, master should have
- disabled the ssl socket.. */
- i_fatal("BUG: SSL initialization parameters not given "
- "while they should have been");
- }
-
- io_ssl_listen = io_add(LOGIN_SSL_LISTEN_FD, IO_READ,
- login_accept_ssl, NULL);
+ cur_fd = LOGIN_MASTER_SOCKET_FD + 1;
+ i_array_init(&listen_ios, listen_count + ssl_listen_count);
+ for (i = 0; i < listen_count; i++, cur_fd++) {
+ io = io_add(cur_fd, IO_READ, login_accept,
+ POINTER_CAST(cur_fd));
+ array_append(&listen_ios, &io, 1);
+ }
+ for (i = 0; i < ssl_listen_count; i++, cur_fd++) {
+ io = io_add(cur_fd, IO_READ, login_accept_ssl,
+ POINTER_CAST(cur_fd));
+ array_append(&listen_ios, &io, 1);
}
listening = TRUE;
@@ -181,30 +184,34 @@ void main_listen_start(void)
void main_listen_stop(void)
{
+ struct io **ios;
+ unsigned int i, count;
+ int cur_fd;
+
if (!listening)
return;
+ ios = array_get_modifiable(&listen_ios, &count);
+ for (i = 0; i < count; i++)
+ io_remove(&ios[i]);
+ array_free(&listen_ios);
+
+ if (closing_down) {
+ cur_fd = LOGIN_MASTER_SOCKET_FD + 1;
+ for (i = 0; i < count; i++, cur_fd++) {
+ if (close(cur_fd) < 0) {
+ i_fatal("close(listener %d) failed: %m",
+ cur_fd);
+ }
+ }
+ }
+
listening = FALSE;
- if (io_listen != NULL) {
- io_remove(&io_listen);
- if (closing_down) {
- if (close(LOGIN_LISTEN_FD) < 0)
- i_fatal("close(listen) failed: %m");
- }
- }
-
- if (io_ssl_listen != NULL) {
- io_remove(&io_ssl_listen);
- if (closing_down) {
- if (close(LOGIN_SSL_LISTEN_FD) < 0)
- i_fatal("close(ssl_listen) failed: %m");
- }
- }
-
- listening = FALSE;
- master_notify_state_change(clients_get_count() == 0 ?
- LOGIN_STATE_FULL_LOGINS :
- LOGIN_STATE_FULL_PRELOGINS);
+ if (io_loop_is_running(ioloop)) {
+ master_notify_state_change(clients_get_count() == 0 ?
+ LOGIN_STATE_FULL_LOGINS :
+ LOGIN_STATE_FULL_PRELOGINS);
+ }
}
void connection_queue_add(unsigned int connection_count)
@@ -332,7 +339,18 @@ static void main_init(void)
auth_client_set_connect_notify(auth_client, auth_connect_notify, NULL);
clients_init();
- io_listen = io_ssl_listen = NULL;
+ value = getenv("LISTEN_FDS");
+ listen_count = value == NULL ? 0 : atoi(value);
+
+ value = getenv("SSL_LISTEN_FDS");
+ ssl_listen_count = value == NULL ? 0 : atoi(value);
+
+ if (!ssl_initialized && ssl_listen_count > 0) {
+ /* this shouldn't happen, master should have
+ disabled the ssl socket.. */
+ i_fatal("BUG: SSL initialization parameters not given "
+ "while they should have been");
+ }
if (!is_inetd) {
master_init(LOGIN_MASTER_SOCKET_FD);
@@ -342,8 +360,8 @@ static void main_init(void)
static void main_deinit(void)
{
- if (io_listen != NULL) io_remove(&io_listen);
- if (io_ssl_listen != NULL) io_remove(&io_ssl_listen);
+ closing_down = TRUE;
+ main_listen_stop();
ssl_proxy_deinit();
login_proxy_deinit();
@@ -370,8 +388,17 @@ int main(int argc __attr_unused__, char
is_inetd = getenv("DOVECOT_MASTER") == NULL;
#ifdef DEBUG
- if (!is_inetd && getenv("GDB") == NULL)
- fd_debug_verify_leaks(5, 1024);
+ if (!is_inetd && getenv("GDB") == NULL) {
+ const char *env;
+
+ i = LOGIN_MASTER_SOCKET_FD + 1;
+ env = getenv("LISTEN_FDS");
+ if (env != NULL) i += atoi(env);
+ env = getenv("SSL_LISTEN_FDS");
+ if (env != NULL) i += atoi(env);
+
+ fd_debug_verify_leaks(i + 1, 1024);
+ }
#endif
/* clear all allocated memory before freeing it. this makes the login
processes pretty safe to reuse for new connections since the
diff -r 86f22b84e008 -r 3f2eb1b9c555 src/master/Makefile.am
--- a/src/master/Makefile.am Tue Jul 03 18:34:31 2007 +0300
+++ b/src/master/Makefile.am Tue Jul 03 20:04:28 2007 +0300
@@ -24,6 +24,8 @@ dovecot_SOURCES = \
capabilities-posix.c \
child-process.c \
dict-process.c \
+ dup2-array.c \
+ listener.c \
log.c \
login-process.c \
mail-process.c \
@@ -38,6 +40,8 @@ noinst_HEADERS = \
capabilities.h \
child-process.h \
dict-process.h \
+ dup2-array.h \
+ listener.h \
common.h \
log.h \
login-process.h \
diff -r 86f22b84e008 -r 3f2eb1b9c555 src/master/dup2-array.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/master/dup2-array.c Tue Jul 03 20:04:28 2007 +0300
@@ -0,0 +1,80 @@
+/* Copyright (C) 2007 Timo Sirainen */
+
+#include "lib.h"
+#include "array.h"
+#include "fd-close-on-exec.h"
+#include "dup2-array.h"
+
+#include <unistd.h>
+
+void dup2_append(ARRAY_TYPE(dup2) *dups, int fd_src, int fd_dest)
+{
+ struct dup2 d;
+
+ d.fd_src = fd_src;
+ d.fd_dest = fd_dest;
+ array_append(dups, &d, 1);
+}
+
+int dup2_array(ARRAY_TYPE(dup2) *dups_arr)
+{
+ struct dup2 *dups;
+ bool *moved, moves;
+ unsigned int i, j, count, conflict;
+ int fd;
+
+ dups = array_get_modifiable(dups_arr, &count);
+
+ t_push();
+ moved = t_new(bool, count);
+ for (;;) {
+ conflict = count;
+ moves = FALSE;
+ for (i = 0; i < count; i++) {
+ if (moved[i])
+ continue;
+
+ for (j = 0; j < count; j++) {
+ if (dups[j].fd_src == dups[i].fd_dest &&
+ !moved[j]) {
+ conflict = j;
+ break;
+ }
+ }
+
More information about the dovecot-cvs
mailing list