Add the LocalDiscoveryAddress option.
authorGuus Sliepen <guus@tinc-vpn.org>
Fri, 31 May 2013 16:50:34 +0000 (18:50 +0200)
committerGuus Sliepen <guus@tinc-vpn.org>
Fri, 31 May 2013 16:50:34 +0000 (18:50 +0200)
When LocalDiscovery is enabled, tinc normally sends broadcast packets during
PMTU discovery to the broadcast address (255.255.255.255 or ff02::1). This
option lets tinc use a different address.

At the moment only one LocalDiscoveryAddress can be specified.

doc/tinc.conf.5.in
doc/tinc.texi
src/net.h
src/net_packet.c
src/net_setup.c

index 89ef739..0376328 100644 (file)
@@ -326,6 +326,9 @@ which normally would prevent the peers from learning each other's LAN address.
 .Pp
 Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
 This feature may not work in all possible situations.
 .Pp
 Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
 This feature may not work in all possible situations.
+.It Va LocalDiscoveryAddress Li = Ar address
+If this variable is specified, local discovery packets are sent to the given
+.Ar address .
 .It Va MACExpire Li = Ar seconds Pq 600
 This option controls the amount of time MAC addresses are kept before they are removed.
 This only has effect when
 .It Va MACExpire Li = Ar seconds Pq 600
 This option controls the amount of time MAC addresses are kept before they are removed.
 This only has effect when
index 5e8df2b..08021f9 100644 (file)
@@ -1056,6 +1056,10 @@ which normally would prevent the peers from learning each other's LAN address.
 Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
 This feature may not work in all possible situations.
 
 Currently, local discovery is implemented by sending broadcast packets to the LAN during path MTU discovery.
 This feature may not work in all possible situations.
 
+@cindex LocalDiscoveryAddress
+@item LocalDiscoveryAddress <@var{address}>
+If this variable is specified, local discovery packets are sent to the given @var{address}.
+
 @cindex Mode
 @item Mode = <router|switch|hub> (router)
 This option selects the way packets are routed to other daemons.
 @cindex Mode
 @item Mode = <router|switch|hub> (router)
 This option selects the way packets are routed to other daemons.
index 879dfff..5f6224e 100644 (file)
--- a/src/net.h
+++ b/src/net.h
@@ -125,6 +125,7 @@ extern int seconds_till_retry;
 extern int addressfamily;
 extern unsigned replaywin;
 extern bool localdiscovery;
 extern int addressfamily;
 extern unsigned replaywin;
 extern bool localdiscovery;
+extern sockaddr_t localdiscovery_address;
 
 extern listen_socket_t listen_socket[MAXSOCKETS];
 extern int listen_sockets;
 
 extern listen_socket_t listen_socket[MAXSOCKETS];
 extern int listen_sockets;
index 26e4907..4bbb2d6 100644 (file)
@@ -56,6 +56,7 @@ static void send_udppacket(node_t *, vpn_packet_t *);
 
 unsigned replaywin = 16;
 bool localdiscovery = false;
 
 unsigned replaywin = 16;
 bool localdiscovery = false;
+sockaddr_t localdiscovery_address;
 
 #define MAX_SEQNO 1073741824
 
 
 #define MAX_SEQNO 1073741824
 
@@ -580,12 +581,22 @@ static void choose_broadcast_address(const node_t *n, const sockaddr_t **sa, int
        *sock = rand() % listen_sockets;
 
        if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
        *sock = rand() % listen_sockets;
 
        if(listen_socket[*sock].sa.sa.sa_family == AF_INET6) {
-               broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
-               broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id;
-               *sa = &broadcast_ipv6;
+               if(localdiscovery_address.sa.sa_family == AF_INET6) {
+                       localdiscovery_address.in6.sin6_port = n->prevedge->address.in.sin_port;
+                       *sa = &localdiscovery_address;
+               } else {
+                       broadcast_ipv6.in6.sin6_port = n->prevedge->address.in.sin_port;
+                       broadcast_ipv6.in6.sin6_scope_id = listen_socket[*sock].sa.in6.sin6_scope_id;
+                       *sa = &broadcast_ipv6;
+               }
        } else {
        } else {
-               broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
-               *sa = &broadcast_ipv4;
+               if(localdiscovery_address.sa.sa_family == AF_INET) {
+                       localdiscovery_address.in.sin_port = n->prevedge->address.in.sin_port;
+                       *sa = &localdiscovery_address;
+               } else {
+                       broadcast_ipv4.in.sin_port = n->prevedge->address.in.sin_port;
+                       *sa = &broadcast_ipv4;
+               }
        }
 }
 
        }
 }
 
index c61a901..ee8296c 100644 (file)
@@ -444,6 +444,7 @@ bool setup_myself_reloadable(void) {
        char *fmode = NULL;
        char *bmode = NULL;
        char *afname = NULL;
        char *fmode = NULL;
        char *bmode = NULL;
        char *afname = NULL;
+       char *address = NULL;
        char *space;
        bool choice;
 
        char *space;
        bool choice;
 
@@ -534,6 +535,16 @@ bool setup_myself_reloadable(void) {
        get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
        get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
 
        get_config_bool(lookup_config(config_tree, "DirectOnly"), &directonly);
        get_config_bool(lookup_config(config_tree, "LocalDiscovery"), &localdiscovery);
 
+       memset(&localdiscovery_address, 0, sizeof localdiscovery_address);
+       if(get_config_string(lookup_config(config_tree, "LocalDiscoveryAddress"), &address)) {
+               struct addrinfo *ai = str2addrinfo(address, myport, SOCK_DGRAM);
+               free(address);
+               if(!ai)
+                       return false;
+               memcpy(&localdiscovery_address, ai->ai_addr, ai->ai_addrlen);
+       }
+
+
        if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) {
                if(!strcasecmp(rmode, "router"))
                        routing_mode = RMODE_ROUTER;
        if(get_config_string(lookup_config(config_tree, "Mode"), &rmode)) {
                if(!strcasecmp(rmode, "router"))
                        routing_mode = RMODE_ROUTER;