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);