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