dovecot-2.2: director: Cleanup for director socket type configur...
dovecot at dovecot.org
dovecot at dovecot.org
Wed May 13 12:35:39 UTC 2015
details: http://hg.dovecot.org/dovecot-2.2/rev/fea09ab164dc
changeset: 18672:fea09ab164dc
user: Timo Sirainen <tss at iki.fi>
date: Wed May 13 15:33:27 2015 +0300
description:
director: Cleanup for director socket type configuration.
It's now possible to use any type of a socket for inet listeners by
specifying the name for the listener. The available types are: auth
(default), userdb, ring (= director<->director connection), admin/doveadm.
This change should be backwards compatible with previous configuration.
This setting also deprecates director_doveadm_port setting.
diffstat:
src/director/main.c | 167 ++++++++++++++++++++++++++++++++++++---------------
1 files changed, 116 insertions(+), 51 deletions(-)
diffs (219 lines):
diff -r 5614bc437643 -r fea09ab164dc src/director/main.c
--- a/src/director/main.c Wed May 13 15:32:54 2015 +0300
+++ b/src/director/main.c Wed May 13 15:33:27 2015 +0300
@@ -26,9 +26,18 @@
#define AUTH_SOCKET_PATH "auth-login"
#define AUTH_USERDB_SOCKET_PATH "auth-userdb"
+enum director_socket_type {
+ DIRECTOR_SOCKET_TYPE_UNKNOWN = 0,
+ DIRECTOR_SOCKET_TYPE_AUTH,
+ DIRECTOR_SOCKET_TYPE_USERDB,
+ DIRECTOR_SOCKET_TYPE_RING,
+ DIRECTOR_SOCKET_TYPE_DOVEADM
+};
+
static struct director *director;
static struct notify_connection *notify_conn;
static struct timeout *to_proctitle_refresh;
+static ARRAY(enum director_socket_type) listener_socket_types;
static void director_refresh_proctitle_timeout(void *context ATTR_UNUSED)
{
@@ -51,6 +60,84 @@
process_title_set(str_c(str));
}
+static enum director_socket_type
+director_socket_type_get_from_name(const char *path)
+{
+ const char *name, *suffix;
+
+ name = strrchr(path, '/');
+ if (name == NULL)
+ name = path;
+ else
+ name++;
+
+ suffix = strrchr(name, '-');
+ if (suffix == NULL)
+ suffix = name;
+ else
+ suffix++;
+
+ if (strcmp(suffix, "auth") == 0)
+ return DIRECTOR_SOCKET_TYPE_AUTH;
+ else if (strcmp(suffix, "userdb") == 0)
+ return DIRECTOR_SOCKET_TYPE_USERDB;
+ else if (strcmp(suffix, "ring") == 0)
+ return DIRECTOR_SOCKET_TYPE_RING;
+ else if (strcmp(suffix, "admin") == 0 ||
+ strcmp(suffix, "doveadm") == 0)
+ return DIRECTOR_SOCKET_TYPE_DOVEADM;
+ else
+ return DIRECTOR_SOCKET_TYPE_UNKNOWN;
+}
+
+static enum director_socket_type
+listener_get_socket_type_fallback(const struct director_settings *set,
+ int listen_fd)
+{
+ unsigned int local_port;
+
+ if (net_getsockname(listen_fd, NULL, &local_port) == 0) {
+ /* TCP/IP connection */
+ if (local_port == set->director_doveadm_port)
+ return DIRECTOR_SOCKET_TYPE_DOVEADM;
+ else
+ return DIRECTOR_SOCKET_TYPE_RING;
+ }
+ return DIRECTOR_SOCKET_TYPE_AUTH;
+}
+
+static void listener_sockets_init(const struct director_settings *set,
+ struct ip_addr *listen_ip_r,
+ unsigned int *listen_port_r)
+{
+ const char *name;
+ unsigned int i, socket_count, port;
+ struct ip_addr ip;
+ enum director_socket_type type;
+
+ *listen_port_r = 0;
+
+ i_array_init(&listener_socket_types, 8);
+ socket_count = master_service_get_socket_count(master_service);
+ for (i = 0; i < socket_count; i++) {
+ int listen_fd = MASTER_LISTEN_FD_FIRST + i;
+
+ name = master_service_get_socket_name(master_service, listen_fd);
+ type = director_socket_type_get_from_name(name);
+ if (type == DIRECTOR_SOCKET_TYPE_UNKNOWN) {
+ /* mainly for backwards compatibility */
+ type = listener_get_socket_type_fallback(set, listen_fd);
+ }
+ if (type == DIRECTOR_SOCKET_TYPE_RING && *listen_port_r == 0 &&
+ net_getsockname(listen_fd, &ip, &port) == 0 && port > 0) {
+ i_warning("listen port = %d", port);
+ *listen_ip_r = ip;
+ *listen_port_r = port;
+ }
+ array_idx_set(&listener_socket_types, listen_fd, &type);
+ }
+}
+
static int director_client_connected(int fd, const struct ip_addr *ip)
{
struct director_host *host;
@@ -70,8 +157,7 @@
{
struct auth_connection *auth;
const char *socket_path;
- struct ip_addr ip;
- unsigned int local_port, len;
+ const enum director_socket_type *typep;
bool userdb;
if (conn->fifo) {
@@ -84,58 +170,36 @@
return;
}
- if (net_getpeername(conn->fd, &ip, NULL) == 0 &&
- net_getsockname(conn->fd, NULL, &local_port) == 0 &&
- (IPADDR_IS_V4(&ip) || IPADDR_IS_V6(&ip))) {
- /* TCP/IP connection */
- if (local_port == director->set->director_doveadm_port) {
+ typep = array_idx(&listener_socket_types, conn->listen_fd);
+ switch (*typep) {
+ case DIRECTOR_SOCKET_TYPE_UNKNOWN:
+ i_unreached();
+ case DIRECTOR_SOCKET_TYPE_AUTH:
+ case DIRECTOR_SOCKET_TYPE_USERDB:
+ /* a) userdb connection, probably for lmtp proxy
+ b) login connection
+ Both of them are handled exactly the same, except for which
+ auth socket they connect to. */
+ userdb = *typep == DIRECTOR_SOCKET_TYPE_USERDB;
+ socket_path = userdb ? AUTH_USERDB_SOCKET_PATH :
+ AUTH_SOCKET_PATH;
+ auth = auth_connection_init(socket_path);
+ if (auth_connection_connect(auth) < 0) {
+ auth_connection_deinit(&auth);
+ break;
+ }
+ master_service_client_connection_accept(conn);
+ (void)login_connection_init(director, conn->fd, auth, userdb);
+ break;
+ case DIRECTOR_SOCKET_TYPE_RING:
+ if (director_client_connected(conn->fd, &conn->remote_ip) == 0)
master_service_client_connection_accept(conn);
- (void)doveadm_connection_init(director, conn->fd);
- } else {
- if (director_client_connected(conn->fd, &ip) == 0)
- master_service_client_connection_accept(conn);
- }
- return;
- }
-
- len = strlen(conn->name);
- if (len > 6 && strcmp(conn->name + len - 6, "-admin") == 0) {
- /* doveadm connection */
+ break;
+ case DIRECTOR_SOCKET_TYPE_DOVEADM:
master_service_client_connection_accept(conn);
(void)doveadm_connection_init(director, conn->fd);
- return;
+ break;
}
-
- /* a) userdb connection, probably for lmtp proxy
- b) login connection
- Both of them are handled exactly the same, except for which
- auth socket they connect to. */
- userdb = len > 7 && strcmp(conn->name + len - 7, "-userdb") == 0;
- socket_path = userdb ? AUTH_USERDB_SOCKET_PATH : AUTH_SOCKET_PATH;
- auth = auth_connection_init(socket_path);
- if (auth_connection_connect(auth) == 0) {
- master_service_client_connection_accept(conn);
- (void)login_connection_init(director, conn->fd, auth, userdb);
- } else {
- auth_connection_deinit(&auth);
- }
-}
-
-static unsigned int
-find_inet_listener_port(struct ip_addr *ip_r,
- const struct director_settings *set)
-{
- unsigned int i, socket_count, port;
-
- socket_count = master_service_get_socket_count(master_service);
- for (i = 0; i < socket_count; i++) {
- int fd = MASTER_LISTEN_FD_FIRST + i;
-
- if (net_getsockname(fd, ip_r, &port) == 0 && port > 0 &&
- port != set->director_doveadm_port)
- return port;
- }
- return 0;
}
static void director_state_changed(struct director *dir)
@@ -177,7 +241,7 @@
}
set = master_service_settings_get_others(master_service)[0];
- listen_port = find_inet_listener_port(&listen_ip, set);
+ listener_sockets_init(set, &listen_ip, &listen_port);
if (listen_port == 0 && *set->director_servers != '\0') {
i_fatal("No inet_listeners defined for director service "
"(for standalone keep director_servers empty)");
@@ -206,6 +270,7 @@
doveadm_connections_deinit();
login_connections_deinit();
auth_connections_deinit();
+ array_free(&listener_socket_types);
}
int main(int argc, char *argv[])
More information about the dovecot-cvs
mailing list