Mercurial > dovecot > core-2.2
changeset 11325:2a5336ad86cd HEAD
director: Tell login proxy to notify director of open connections every director_user_expire/2 secs.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 19 May 2010 12:23:32 +0200 |
parents | c872378a8de6 |
children | fc94106ca7e9 |
files | doc/example-config/conf.d/10-director.conf src/director/Makefile.am src/director/director-settings.c src/director/login-connection.c src/director/main.c src/director/notify-connection.c src/director/notify-connection.h |
diffstat | 7 files changed, 111 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/doc/example-config/conf.d/10-director.conf Wed May 19 12:20:36 2010 +0200 +++ b/doc/example-config/conf.d/10-director.conf Wed May 19 12:23:32 2010 +0200 @@ -11,21 +11,24 @@ # List of IPs or hostnames to all director servers, including ourself. # Ports can be specified as ip:port. The default port is the same as # what director service's inet_listener is using. -director_servers = +#director_servers = # List of IPs or hostnames to all backend mail servers. Ranges are allowed # too, like 10.0.0.10-10.0.0.30. -director_mail_servers = +#director_mail_servers = # How long to redirect users to a specific server after it no longer has # any connections. -director_user_expire = 15 min +#director_user_expire = 15 min -# To enable director service, uncomment the mode and assign a port. +# To enable director service, uncomment the modes and assign a port. service director { unix_listener login/director { #mode = 0666 } + fifo_listener login/proxy-notify { + #mode = 0666 + } inet_listener { #port = }
--- a/src/director/Makefile.am Wed May 19 12:20:36 2010 +0200 +++ b/src/director/Makefile.am Wed May 19 12:23:32 2010 +0200 @@ -23,6 +23,7 @@ doveadm-connection.c \ login-connection.c \ mail-host.c \ + notify-connection.c \ user-directory.c noinst_HEADERS = \ @@ -35,4 +36,5 @@ doveadm-connection.h \ login-connection.h \ mail-host.h \ + notify-connection.h \ user-directory.h
--- a/src/director/director-settings.c Wed May 19 12:20:36 2010 +0200 +++ b/src/director/director-settings.c Wed May 19 12:23:32 2010 +0200 @@ -19,6 +19,16 @@ director_unix_listeners, sizeof(director_unix_listeners), { 0, } }; +static struct file_listener_settings director_fifo_listeners_array[] = { + { "login/proxy-notify", 0, "", "" } +}; +static struct file_listener_settings *director_fifo_listeners[] = { + &director_fifo_listeners_array[0] +}; +static buffer_t director_fifo_listeners_buf = { + director_fifo_listeners, + sizeof(director_fifo_listeners), { 0, } +}; /* </settings checks> */ struct service_settings director_service_settings = { @@ -42,7 +52,8 @@ .unix_listeners = { { &director_unix_listeners_buf, sizeof(director_unix_listeners[0]) } }, - .fifo_listeners = ARRAY_INIT, + .fifo_listeners = { { &director_fifo_listeners_buf, + sizeof(director_fifo_listeners[0]) } }, .inet_listeners = ARRAY_INIT }; #undef DEF
--- a/src/director/login-connection.c Wed May 19 12:20:36 2010 +0200 +++ b/src/director/login-connection.c Wed May 19 12:23:32 2010 +0200 @@ -71,12 +71,16 @@ static void login_host_callback(const struct ip_addr *ip, void *context) { struct login_host_request *request = context; + struct director *dir = request->conn->dir; const char *line; + unsigned int secs; T_BEGIN { if (ip != NULL) { - line = t_strconcat(request->line, "\thost=", - net_ip2addr(ip), NULL); + secs = dir->set->director_user_expire / 2; + line = t_strdup_printf("%s\thost=%s\tproxy_refresh=%u", + request->line, net_ip2addr(ip), + secs); } else { i_assert(strncmp(request->line, "OK\t", 3) == 0); line = t_strconcat("FAIL\t",
--- a/src/director/main.c Wed May 19 12:20:36 2010 +0200 +++ b/src/director/main.c Wed May 19 12:23:32 2010 +0200 @@ -10,6 +10,7 @@ #include "auth-connection.h" #include "doveadm-connection.h" #include "login-connection.h" +#include "notify-connection.h" #include "director.h" #include "director-host.h" #include "director-connection.h" @@ -21,6 +22,7 @@ #define AUTH_SOCKET_PATH "login/login" static struct director *director; +static struct notify_connection *notify_conn; static char *auth_socket_path; static int director_client_connected(int fd, const struct ip_addr *ip) @@ -42,6 +44,16 @@ struct ip_addr ip; unsigned int port, len; + if (conn->fifo) { + if (notify_conn != NULL) { + i_error("Received another proxy-notify connection"); + (void)close(conn->fd); + return; + } + notify_conn = notify_connection_init(director, conn->fd); + return; + } + if (net_getpeername(conn->fd, &ip, &port) == 0 && (IPADDR_IS_V4(&ip) || IPADDR_IS_V6(&ip))) { /* TCP/IP connection - this is another director */ @@ -140,6 +152,7 @@ static void main_deinit(void) { + notify_connection_deinit(¬ify_conn); director_deinit(&director); doveadm_connections_deinit(); login_connections_deinit();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/director/notify-connection.c Wed May 19 12:23:32 2010 +0200 @@ -0,0 +1,62 @@ +/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "ioloop.h" +#include "istream.h" +#include "director.h" +#include "user-directory.h" +#include "notify-connection.h" + +#include <unistd.h> + +struct notify_connection { + int fd; + struct io *io; + struct istream *input; + struct director *dir; +}; + +static void notify_connection_input(struct notify_connection *conn) +{ + struct user *user; + const char *line; + unsigned int hash; + + while ((line = i_stream_read_next_line(conn->input)) != NULL) { + hash = user_directory_get_username_hash(line); + user = user_directory_lookup(conn->dir->users, hash); + if (user != NULL) { + user_directory_refresh(conn->dir->users, user); + director_update_user(conn->dir, conn->dir->self_host, + user); + } + } + if (conn->input->eof || conn->input->stream_errno != 0) + notify_connection_deinit(&conn); +} + +struct notify_connection * +notify_connection_init(struct director *dir, int fd) +{ + struct notify_connection *conn; + + conn = i_new(struct notify_connection, 1); + conn->fd = fd; + conn->dir = dir; + conn->input = i_stream_create_fd(conn->fd, 1024, FALSE); + conn->io = io_add(conn->fd, IO_READ, notify_connection_input, conn); + return conn; +} + +void notify_connection_deinit(struct notify_connection **_conn) +{ + struct notify_connection *conn = *_conn; + + *_conn = NULL; + + io_remove(&conn->io); + i_stream_unref(&conn->input); + if (close(conn->fd) < 0) + i_error("close(notify connection) failed: %m"); + i_free(conn); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/director/notify-connection.h Wed May 19 12:23:32 2010 +0200 @@ -0,0 +1,9 @@ +#ifndef NOTIFY_CONNECTION_H +#define NOTIFY_CONNECTION_H + +struct director; + +struct notify_connection *notify_connection_init(struct director *dir, int fd); +void notify_connection_deinit(struct notify_connection **conn); + +#endif