Feature request: client bind address for replication

John Fawcett john at voipsupport.it
Fri Jan 4 17:25:52 EET 2019


Hi

would it be possible to consider a new parameter for replication:
doveadm_local_ip which allows the source ip address to be set when
connection to a remote dovecot for replication?

It could be useful when the network interface has multiple ips and a
specific one is used for mail services. See attached proposal. I tested
against 2.2.36 only. It applies correctly against 2.3.4 with a warning,.

John


-------------- next part --------------
--- dovecot-2.2.36/src/doveadm/doveadm-settings.c	2018-04-30 15:52:05.000000000 +0200
+++ dovecot-2.2.36-new/src/doveadm/doveadm-settings.c	2019-01-04 14:59:11.556270077 +0100
@@ -62,6 +62,7 @@
 	DEF(SET_UINT, doveadm_worker_count),
 	DEF(SET_IN_PORT, doveadm_port),
 	{ SET_ALIAS, "doveadm_proxy_port", 0, NULL },
+	DEF(SET_STR, doveadm_local_ip),
 	DEF(SET_STR, doveadm_username),
 	DEF(SET_STR, doveadm_password),
 	DEF(SET_STR, doveadm_allowed_commands),
@@ -91,6 +92,7 @@
 	.doveadm_socket_path = "doveadm-server",
 	.doveadm_worker_count = 0,
 	.doveadm_port = 0,
+	.doveadm_local_ip = "",
 	.doveadm_username = "doveadm",
 	.doveadm_password = "",
 	.doveadm_allowed_commands = "",
--- dovecot-2.2.36/src/doveadm/doveadm-settings.h	2017-10-05 19:09:55.000000000 +0200
+++ dovecot-2.2.36-new/src/doveadm/doveadm-settings.h	2019-01-04 14:57:32.906269791 +0100
@@ -19,6 +19,7 @@
 	const char *doveadm_socket_path;
 	unsigned int doveadm_worker_count;
 	in_port_t doveadm_port;
+	const char *doveadm_local_ip;
 	const char *doveadm_username;
 	const char *doveadm_password;
 	const char *doveadm_allowed_commands;
--- dovecot-2.2.36/src/doveadm/doveadm-util.c	2018-04-30 15:52:05.000000000 +0200
+++ dovecot-2.2.36-new/src/doveadm/doveadm-util.c	2019-01-04 15:26:09.326903786 +0100
@@ -100,19 +100,29 @@
 }
 
 static int
-doveadm_tcp_connect_port(const char *host, in_port_t port)
+doveadm_tcp_connect_port(const char *host, in_port_t port, char * my_ip)
 {
 	struct ip_addr *ips;
 	unsigned int ips_count;
 	int ret, fd;
-
+	struct ip_addr my_net_ip;
+	int use_my_ip = 0;
+        if (strcmp(my_ip,"") == 0) {
+                i_info("No doveadm_local_ip setting, local ip supplied by operating system");
+	}
+	if (net_addr2ip(my_ip, &my_net_ip)) {
+                i_error("error using doveadm_local_ip setting %s",my_ip);
+	} else {
+                i_info("Using doveadm_local_ip setting: %s",my_ip);
+		use_my_ip = 1;
+	}
 	alarm(DOVEADM_TCP_CONNECT_TIMEOUT_SECS);
 	ret = net_gethostbyname(host, &ips, &ips_count);
 	if (ret != 0) {
 		i_fatal("Lookup of host %s failed: %s",
 			host, net_gethosterror(ret));
 	}
-	fd = net_connect_ip_blocking(&ips[0], port, NULL);
+	fd = net_connect_ip_blocking(&ips[0], port, use_my_ip ? &my_net_ip : NULL);
 	if (fd == -1) {
 		i_fatal("connect(%s:%u) failed: %m",
 			net_ip2addr(&ips[0]), port);
@@ -121,7 +131,7 @@
 	return fd;
 }
 
-int doveadm_tcp_connect(const char *target, in_port_t default_port)
+int doveadm_tcp_connect(const char *target, in_port_t default_port, char * my_ip)
 {
 	const char *host;
 	in_port_t port;
@@ -130,18 +140,18 @@
 		i_fatal("Port not known for %s. Either set proxy_port "
 			"or use %s:port", target, target);
 	}
-	return doveadm_tcp_connect_port(host, port);
+	return doveadm_tcp_connect_port(host, port, my_ip);
 }
 
 int doveadm_connect_with_default_port(const char *path,
-				      in_port_t default_port)
+				      in_port_t default_port, char * my_ip)
 {
 	int fd;
 
 	/* we'll assume UNIX sockets typically have an absolute path,
 	   or at the very least '/' somewhere. */
 	if (strchr(path, '/') == NULL)
-		fd = doveadm_tcp_connect(path, default_port);
+		fd = doveadm_tcp_connect(path, default_port, my_ip);
 	else {
 		fd = net_connect_unix(path);
 		if (fd == -1)
@@ -152,7 +162,7 @@
 
 int doveadm_connect(const char *path)
 {
-	return doveadm_connect_with_default_port(path, 0);
+	return doveadm_connect_with_default_port(path, 0, "");
 }
 
 int i_strccdascmp(const char *a, const char *b)
--- dovecot-2.2.36/src/doveadm/doveadm-util.h	2017-10-05 19:09:55.000000000 +0200
+++ dovecot-2.2.36-new/src/doveadm/doveadm-util.h	2019-01-04 14:55:52.263289702 +0100
@@ -13,9 +13,9 @@
 const char *unixdate2str(time_t timestamp);
 const char *doveadm_plugin_getenv(const char *name);
 int doveadm_connect(const char *path);
-int doveadm_tcp_connect(const char *target, in_port_t default_port);
+int doveadm_tcp_connect(const char *target, in_port_t default_port, char * my_ip);
 int doveadm_connect_with_default_port(const char *path,
-				      in_port_t default_port);
+				      in_port_t default_port, char * my_ip);
 
 void doveadm_load_modules(void);
 void doveadm_unload_modules(void);
--- dovecot-2.2.36/src/doveadm/server-connection.c	2018-04-30 15:52:05.000000000 +0200
+++ dovecot-2.2.36-new/src/doveadm/server-connection.c	2019-01-04 14:57:08.251519641 +0100
@@ -535,7 +535,7 @@
 	conn->pool = pool;
 	conn->server = server;
 	conn->fd = doveadm_connect_with_default_port(server->name,
-						     doveadm_settings->doveadm_port);
+		     doveadm_settings->doveadm_port,doveadm_settings->doveadm_local_ip);
 	net_set_nonblock(conn->fd, TRUE);
 	conn->input = i_stream_create_fd(conn->fd, MAX_INBUF_SIZE, FALSE);
 	conn->output = o_stream_create_fd(conn->fd, (size_t)-1, FALSE);


More information about the dovecot mailing list