Invalidate UDP information on address changes.
authorEtienne Dechamps <etienne@edechamps.fr>
Sun, 21 Sep 2014 14:44:59 +0000 (15:44 +0100)
committerEtienne Dechamps <etienne@edechamps.fr>
Sat, 4 Oct 2014 10:12:36 +0000 (11:12 +0100)
Currently, when tinc receives an UDP packet from an unexpected address
(i.e. an address different from the node's current address), it just
updates its internal UDP address record and carries on like nothing
happened.

This poses two problems:

 - It assumes that the PMTU for the new address is the same as the
   old address, which is risky. Packets might get dropped if the PMTU
   turns out to be smaller (or if UDP communication on the new address
   turns out to be impossible).

 - Because the source address in the UDP packet itself is not
   authenticated (i.e. it can be forged by an attacker), this
   introduces a potential vulnerability by which an attacker with
   control over one link can trick a tinc node into dumping its network
   traffic to an arbitrary IP address.

This commit fixes the issue by invalidating UDP/PMTU state for a node
when its UDP address changes. This will trigger a temporary fallback
to indirect communication until we get confirmation via PMTU discovery
that the node is indeed sitting at the other end of the new UDP address.

src/node.c

index aab83ca..0cb2445 100644 (file)
@@ -140,6 +140,13 @@ void update_node_udp(node_t *n, const sockaddr_t *sa) {
                n->hostname = sockaddr2hostname(&n->address);
                logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
        }
                n->hostname = sockaddr2hostname(&n->address);
                logger(DEBUG_PROTOCOL, LOG_DEBUG, "UDP address of %s set to %s", n->name, n->hostname);
        }
+
+       /* invalidate UDP information - note that this is a security feature as well to make sure
+          we can't be tricked into flooding any random address with UDP packets */
+       n->status.udp_confirmed = false;
+       n->mtuprobes = 0;
+       n->minmtu = 0;
+       n->maxmtu = MTU;
 }
 
 bool dump_nodes(connection_t *c) {
 }
 
 bool dump_nodes(connection_t *c) {