From b811e980e3a2a301c019459b91df2252468fd572 Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Fri, 31 May 2013 18:50:34 +0200 Subject: [PATCH] Add the LocalDiscoveryAddress option. 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 | 3 +++ doc/tinc.texi | 4 ++++ src/net.h | 1 + src/net_packet.c | 21 ++++++++++++++++----- src/net_setup.c | 11 +++++++++++ 5 files changed, 35 insertions(+), 5 deletions(-) diff --git a/doc/tinc.conf.5.in b/doc/tinc.conf.5.in index 89ef7397..0376328f 100644 --- a/doc/tinc.conf.5.in +++ b/doc/tinc.conf.5.in @@ -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. +.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 diff --git a/doc/tinc.texi b/doc/tinc.texi index 5e8df2b7..08021f9a 100644 --- a/doc/tinc.texi +++ b/doc/tinc.texi @@ -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. +@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) This option selects the way packets are routed to other daemons. diff --git a/src/net.h b/src/net.h index 879dfffb..5f6224e2 100644 --- 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 sockaddr_t localdiscovery_address; extern listen_socket_t listen_socket[MAXSOCKETS]; extern int listen_sockets; diff --git a/src/net_packet.c b/src/net_packet.c index 26e49071..4bbb2d6f 100644 --- a/src/net_packet.c +++ b/src/net_packet.c @@ -56,6 +56,7 @@ static void send_udppacket(node_t *, vpn_packet_t *); unsigned replaywin = 16; bool localdiscovery = false; +sockaddr_t localdiscovery_address; #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) { - 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 { - 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; + } } } diff --git a/src/net_setup.c b/src/net_setup.c index c61a9012..ee8296cd 100644 --- a/src/net_setup.c +++ b/src/net_setup.c @@ -444,6 +444,7 @@ bool setup_myself_reloadable(void) { char *fmode = NULL; char *bmode = NULL; char *afname = NULL; + char *address = NULL; 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); + 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; -- 2.20.1