Bind outgoing TCP sockets.
authorGuus Sliepen <guus@tinc-vpn.org>
Thu, 27 Apr 2017 18:58:10 +0000 (20:58 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Thu, 27 Apr 2017 18:58:10 +0000 (20:58 +0200)
This is important for multi-homed users that want to ensure the source
address of outgoing TCP connections is the same as the address that tinc
is listening on.

Binding is done automatically if there is exactly one listening address
for a given address family.

src/net_socket.c

index a4c7f076130e52351a35e73c383078286b44cc23..80ae6778ff3b3d591921a634c768732ff9d29857 100644 (file)
@@ -473,6 +473,33 @@ connect:
                bind_to_interface(c->socket);
        }
 
                bind_to_interface(c->socket);
        }
 
+       int b = -1;
+
+       for(int i = 0; i < listen_sockets; i++) {
+               if(listen_socket[i].sa.sa.sa_family == c->address.sa.sa_family) {
+                       if(b == -1) {
+                               b = i;
+                       } else  {
+                               b = -1;
+                               break;
+                       }
+               }
+       }
+
+       if(b != -1) {
+               sockaddr_t sa = listen_socket[b].sa;
+               if(sa.sa.sa_family == AF_INET)
+                       sa.in.sin_port = 0;
+               else if(sa.sa.sa_family == AF_INET6)
+                       sa.in6.sin6_port = 0;
+
+               if(bind(c->socket, &sa.sa, SALEN(sa.sa))) {
+                       char *addrstr = sockaddr2hostname(&sa);
+                       logger(LOG_ERR, "Can't bind to %s/tcp: %s", addrstr, sockstrerror(sockerrno));
+                       free(addrstr);
+               }
+       }
+
        /* Connect */
 
        if(!proxytype) {
        /* Connect */
 
        if(!proxytype) {