]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: connection: Added support for connecting from an explicit source IP.
authorStephan Bosch <stephan.bosch@dovecot.fi>
Tue, 27 Feb 2018 20:56:55 +0000 (21:56 +0100)
committerStephan Bosch <stephan.bosch@dovecot.fi>
Tue, 27 Feb 2018 20:56:55 +0000 (21:56 +0100)
src/lib/connection.c
src/lib/connection.h

index b43d3094ed96d2a3a4c1aa6edc1cf2cbba52cae8..739dbaf788f1a4f3a3033c0f674cc997cb2fc333 100644 (file)
@@ -244,9 +244,10 @@ void connection_init_server(struct connection_list *list,
        connection_init_streams(conn);
 }
 
-void connection_init_client_ip(struct connection_list *list,
-                              struct connection *conn,
-                              const struct ip_addr *ip, in_port_t port)
+void connection_init_client_ip_from(struct connection_list *list,
+                                   struct connection *conn,
+                                   const struct ip_addr *ip, in_port_t port,
+                                   const struct ip_addr *my_ip)
 {
        i_assert(list->set.client);
 
@@ -257,6 +258,18 @@ void connection_init_client_ip(struct connection_list *list,
 
        conn->ip = *ip;
        conn->port = port;
+
+       if (my_ip != NULL)
+               conn->my_ip = *my_ip;
+       else
+               i_zero(&conn->my_ip);
+}
+
+void connection_init_client_ip(struct connection_list *list,
+                              struct connection *conn,
+                              const struct ip_addr *ip, in_port_t port)
+{
+       connection_init_client_ip_from(list, conn, ip, port, NULL);
 }
 
 void connection_init_client_unix(struct connection_list *list,
@@ -323,9 +336,10 @@ int connection_client_connect(struct connection *conn)
        i_assert(conn->list->set.client);
        i_assert(conn->fd_in == -1);
 
-       if (conn->port != 0)
-               fd = net_connect_ip(&conn->ip, conn->port, NULL);
-       else if (conn->list->set.unix_client_connect_msecs == 0)
+       if (conn->port != 0) {
+               fd = net_connect_ip(&conn->ip, conn->port,
+                       (conn->my_ip.family != 0 ? &conn->my_ip : NULL));
+       } else if (conn->list->set.unix_client_connect_msecs == 0)
                fd = net_connect_unix(conn->name);
        else
                fd = net_connect_unix_with_retries(conn->name, conn->list->set.unix_client_connect_msecs);
index 3252520ed3a081cf012350c1abea29ba9ef25b53..d842930920b2a7fde478b96fbb17afebb17961c4 100644 (file)
@@ -92,7 +92,7 @@ struct connection {
        struct timeval connect_finished;
 
        /* for IP client: */
-       struct ip_addr ip;
+       struct ip_addr ip, my_ip;
        in_port_t port;
 
        /* received minor version */
@@ -121,6 +121,10 @@ void connection_init_server(struct connection_list *list,
 void connection_init_client_ip(struct connection_list *list,
                               struct connection *conn,
                               const struct ip_addr *ip, in_port_t port);
+void connection_init_client_ip_from(struct connection_list *list,
+                                   struct connection *conn,
+                                   const struct ip_addr *ip, in_port_t port,
+                                   const struct ip_addr *my_ip) ATTR_NULL(5);
 void connection_init_client_unix(struct connection_list *list,
                                 struct connection *conn, const char *path);
 void connection_init_from_streams(struct connection_list *list,