Przeglądaj źródła

In telescoping WO, be sure to not pick the guard as the exit

The guard and middle will already reject attempts to pick themselves as
the hop right after them, so we just have to watch out for
guard-middle-guard circuits.
Ian Goldberg 6 lat temu
rodzic
commit
8e7b52b98d
1 zmienionych plików z 18 dodań i 2 usunięć
  1. 18 2
      client.py

+ 18 - 2
client.py

@@ -140,14 +140,16 @@ class TelescopingExtendedHandler:
             return
             return
 
 
         nexthopidx = None
         nexthopidx = None
+        guardrange = circhandler.circuit_descs[0].snipdict["range"]
         while nexthopidx is None:
         while nexthopidx is None:
             # Relays make sure that when the extend to a relay, they are not
             # Relays make sure that when the extend to a relay, they are not
             # extending to themselves. So here, we just need to make sure that
             # extending to themselves. So here, we just need to make sure that
             # this ID is not the same as the guard ID, to protect against the
             # this ID is not the same as the guard ID, to protect against the
             # guard and exit being the same relay
             # guard and exit being the same relay
-            print("WARNING: Unimplemented! Need to check that sampled ID is not the same as the guard.")
             nexthopidx = self.channelmgr.relaypicker.pick_weighted_relay_index()
             nexthopidx = self.channelmgr.relaypicker.pick_weighted_relay_index()
-            logging.warning("Unimplemented! Need to check if this idx is in the list of circhandlers idxs")
+            if guardrange[0] <= nexthopidx and nexthopidx < guardrange[1]:
+                # We've picked this relay already.  Try again.
+                nexthopidx = None
 
 
         # Construct the VanillaExtendCircuitCell
         # Construct the VanillaExtendCircuitCell
         ntor = relay.NTor(self.channelmgr.perfstats)
         ntor = relay.NTor(self.channelmgr.perfstats)
@@ -309,6 +311,20 @@ class ClientChannelManager(relay.ChannelManager):
             logging.debug("Circuit was already closed, not sending bytes. circid: " + str(circid))
             logging.debug("Circuit was already closed, not sending bytes. circid: " + str(circid))
             return None
             return None
 
 
+        # In Telescoping Walking Onions, it should never happen that the
+        # guard and exit are the same node, as the
+        # TelescopingExtendedHandler takes care to not pick an index for
+        # the exit that matches the guard's range.  So this test should
+        # never trigger.  In Single-Pass Walking Onions, however, the
+        # equivalent test is needed here (but should just log a debug,
+        # not an error, since the client cannot control the index value
+        # selected for the exit.
+        if circhandler.circuit_descs[0].snipdict["addr"] == \
+                circhandler.circuit_descs[2].snipdict["addr"]:
+            logging.error("CIRCUIT IN A LOOP")
+            circhandler.close()
+            circhandler = None
+
         return circhandler
         return circhandler
 
 
     def new_circuit_singlepass(self):
     def new_circuit_singlepass(self):