Fix dynamic UDP SPTPS relaying.
authorEtienne Dechamps <etienne@edechamps.fr>
Sun, 8 Mar 2015 14:20:15 +0000 (14:20 +0000)
committerEtienne Dechamps <etienne@edechamps.fr>
Sun, 8 Mar 2015 14:28:07 +0000 (14:28 +0000)
Refactoring commit 0e653260478005eb7c824a9a1a3df04f39938cd6 broke UDP
SPTPS relaying by accidently removing try_tx_sptps() logic related to
establishing connectivity to so-called "dynamic" relays (i.e. relays
that are not specified by IndirectData configuration statements, but
are used on-the-fly to circumvent loss of direct UDP connectivity).

Specifically, the TX path was not trying to establish a tunnel to
dynamic relays (nexthop) anymore. This meant that MTU was not being
discovered with dynamic relays, which basically meant that all packets
being sent to dynamic relays went over TCP, thereby defeating the whole
purpose of SPTPS UDP relaying.

Note that this bug could easily go unnoticed if a tunnel was established
with the dynamic tunnel for some other reason (i.e. exchanging actual
data packets with the relay node).

src/net_packet.c

index 9e57df5..df87e27 100644 (file)
@@ -1125,23 +1125,31 @@ static void try_tx_sptps(node_t *n, bool mtu) {
 
        try_sptps(n);
 
-       /* Do we need to relay packets? */
+       /* Do we need to statically relay packets? */
 
        node_t *via = (n->via == myself) ? n->nexthop : n->via;
 
-       /* If the relay doesn't support SPTPS, everything goes via TCP anyway. */
+       /* If the static relay doesn't support SPTPS, everything goes via TCP anyway. */
 
        if((via->options >> 24) < 4)
                return;
 
-       /* If we do have a relay, try everything with that one instead. */
+       /* If we do have a static relay, try everything with that one instead. */
 
        if(via != n)
-               return try_tx_sptps(via, mtu);
+               try_tx_sptps(via, mtu);
+
+       /* Otherwise, try to establish UDP connectivity. */
 
        try_udp(n);
        if(mtu)
                try_mtu(n);
+
+       /* If we don't have UDP connectivity (yet), we need to use a dynamic relay (nexthop)
+          while we try to establish direct connectivity. */
+
+       if(!n->status.udp_confirmed && n != n->nexthop && (n->nexthop->options >> 24) >= 4)
+               try_tx_sptps(n->nexthop, mtu);
 }
 
 static void try_tx_legacy(node_t *n, bool mtu) {