Don't try to relay packets to unreachable nodes.
authorEtienne Dechamps <etienne@edechamps.fr>
Sun, 31 May 2015 19:19:48 +0000 (20:19 +0100)
committerEtienne Dechamps <etienne@edechamps.fr>
Sun, 31 May 2015 19:19:48 +0000 (20:19 +0100)
It is not unusual for tinc to receive SPTPS packets to be relayed to
nodes that just became unreachable, due to state propagation delays in
the metagraph.

Unfortunately, the current code doesn't handle that situation correctly,
and still tries to relay the packet to the unreachable node. This
typically ends up segfaulting.

This commit fixes the issue by checking for reachability before relaying
the packet.

src/net_packet.c

index e4b839e..69835ee 100644 (file)
@@ -454,6 +454,13 @@ bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) {
                return true;
        }
 
+       if(!to->status.reachable) {
+               /* This can happen in the form of a race condition
+                  if the node just became unreachable. */
+               logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot relay TCP packet from %s (%s) because the destination, %s (%s), is unreachable", from->name, from->hostname, to->name, to->hostname);
+               return;
+       }
+
        /* Help the sender reach us over UDP.
           Note that we only do this if we're the destination or the static relay;
           otherwise every hop would initiate its own UDP info message, resulting in elevated chatter. */
@@ -1461,6 +1468,13 @@ skip_harder:
                        return;
                }
 
+               if(!to->status.reachable) {
+                       /* This can happen in the form of a race condition
+                          if the node just became unreachable. */
+                       logger(DEBUG_TRAFFIC, LOG_WARNING, "Cannot relay packet from %s (%s) because the destination, %s (%s), is unreachable", from->name, from->hostname, to->name, to->hostname);
+                       return;
+               }
+
                /* The packet is supposed to come from the originator or its static relay
                   (i.e. with no dynamic relays in between).
                   If it did not, "help" the static relay by sending it UDP info.