Browse Source

Fix to close circuit & stop sending in case of error in telescoping.

Chelsea H. Komlo 4 years ago
parent
commit
3571eb1566
2 changed files with 18 additions and 22 deletions
  1. 11 10
      client.py
  2. 7 12
      relay.py

+ 11 - 10
client.py

@@ -86,7 +86,8 @@ class TelescopingCreatedHandler:
         nexthopidx = None
         while nexthopidx is None:
             nexthopidx = self.channelmgr.relaypicker.pick_weighted_relay_index()
-            print("WARNING: Unimplemented! Need to check if this idx is in the list of circhandlers idxs")
+            #print("WARNING: Unimplemented! Need to check if this idx is in the list of circhandlers idxs")
+            # TODO verify we don't need to do the above
 
         # Construct the VanillaExtendCircuitCell
         ntor = relay.NTor(self.channelmgr.perfstats)
@@ -128,7 +129,6 @@ class TelescopingExtendedHandler:
                     relay.TelescopingExtendedCircuitCell, None)
         circhandler.circuit_descs.append(cell.snip)
 
-
         # Are we done building the circuit?
         print("WARNING: we may need another circhandler structure for snips")
         if len(circhandler.circuit_descs) == 3:
@@ -158,11 +158,10 @@ class TelescopingExtendedHandler:
 class ClientChannelManager(relay.ChannelManager):
     """The subclass of ChannelManager for clients."""
 
-    def __init__(self, myaddr, dirauthaddrs, perfstats, open_circuits):
+    def __init__(self, myaddr, dirauthaddrs, perfstats):
         super().__init__(myaddr, dirauthaddrs, perfstats)
         self.guardaddr = None
         self.guard = None
-        self.open_circuits = open_circuits
 
     def get_consensus_from_fallbackrelay(self):
         """Download a fresh consensus from a random fallbackrelay."""
@@ -242,8 +241,6 @@ class ClientChannelManager(relay.ChannelManager):
 
         # Allocate a new circuit id on it
         circid, circhandler = guardchannel.new_circuit()
-        # store a reference to this new circuit.
-        self.open_circuits[circid] = circhandler
 
         # Construct the VanillaCreateCircuitMsg
         ntor = relay.NTor(self.perfstats)
@@ -269,8 +266,6 @@ class ClientChannelManager(relay.ChannelManager):
 
         # Allocate a new circuit id on it
         circid, circhandler = guardchannel.new_circuit()
-        # store a reference to this new circuit.
-        self.open_circuits[circid] = circhandler
 
         # Construct the VanillaCreateCircuitMsg
         ntor = relay.NTor(self.perfstats)
@@ -285,6 +280,13 @@ class ClientChannelManager(relay.ChannelManager):
         # Send the message
         guardchannel.send_msg(circcreatemsg)
 
+        # Check to make sure the circuit is open before sending it- if there
+        # was an error when establishing it, the circuit could already be
+        # closed.
+        if not guardchannel.is_circuit_open(circid):
+            print("ERR: Circuit was already closed, not sending bytes. circid: " + str(circid))
+            return None
+
         return circhandler
 
     def new_circuit(self):
@@ -327,9 +329,8 @@ class Client:
         self.perfstats = network.PerfStats(network.EntType.CLIENT)
         self.perfstats.name = "Client at %s" % self.netaddr
         self.perfstats.is_bootstrapping = True
-        self.open_circuits = {}
         self.channelmgr = ClientChannelManager(self.netaddr, dirauthaddrs,
-                self.perfstats, self.open_circuits)
+                self.perfstats)
 
         # Register for epoch tick notifications
         network.thenetwork.wantepochticks(self, True)

+ 7 - 12
relay.py

@@ -276,7 +276,6 @@ class VanillaExtendCircuitHandler:
 
         # Set up a handler for when the VanillaCreatedCircuitCell comes
         # back
-        #TODO shouldn't these be extended?
         newcirchandler.replace_celltype_handler(
                 VanillaCreatedCircuitCell,
                 VanillaCreatedRelayHandler())
@@ -298,7 +297,6 @@ class TelescopingExtendCircuitHandler:
     def received_cell(self, circhandler, cell):
         # Remove ourselves from handling a second
         # TelescopingExtendCircuitCell on this circuit
-        print("Log: Received TelescopingExtendCircuitHandler cell")
         circhandler.replace_celltype_handler(TelescopingExtendCircuitCell, None)
 
         # Find the SNIP corresponding to the  index sent by the client
@@ -307,7 +305,7 @@ class TelescopingExtendCircuitHandler:
         # Check to make sure that we aren't extending to ourselves. If we are,
         # close the circuit.
         if next_snip.snipdict["idkey"] == self.current_relay_idkey:
-            print("ERR: Client requested extending the circuit to a relay already in the path; aborting.")
+            print("ERR: Client requested extending the circuit to a relay already in the path; aborting. my circid: " + str(circhandler.circid))
             circhandler.close()
             return
 
@@ -406,15 +404,13 @@ class CircuitHandler:
         self.adjacent_circuit_handler = None
         # The function to call when this circuit closes
         self.closer = lambda: self.channel.circuithandlers.pop(circid)
-        self.is_closed = False
 
     def close(self):
         """Close the circuit.  Sends a CloseCell on the circuit (and its
         adjacent circuit, if present) and closes both."""
         adjcirchandler = self.adjacent_circuit_handler
         self.adjacent_circuit_handler = None
-        self.is_closed = True
-        print("CLOSED CIRCUIT!!!!!!")
+        print("Log: CLosing circuit. circid: " + str(self.circid))
         if adjcirchandler is not None:
             adjcirchandler.adjacent_circuit_handler = None
         self.closer()
@@ -458,6 +454,7 @@ class CircuitHandler:
                             self.circid, self.channel.peer.channelmgr.myaddr))
 
             elif isinstance(cell, CloseCell):
+                print("WARNING: Received CloseCell on circuit " + str(self.circid))
                 # Forward the CloseCell (without encryption) to the
                 # adjacent circuit, if any, and close both this and the
                 # adjacent circuit
@@ -538,6 +535,10 @@ class Channel(network.Connection):
         self.circuithandlers[circid] = circuithandler
         return circid, circuithandler
 
+    def is_circuit_open(self, circid):
+        is_open = (circid in self.circuithandlers) and (self.circuithandlers[circid] is not None)
+        return is_open
+
     def new_circuit_with_circid(self, circid):
         """Allocate a new circuit on this channel, with the circuit id
         received from our peer.  Return the new CircuitHandler"""
@@ -729,12 +730,6 @@ class RelayChannelManager(ChannelManager):
                     TelescopingExtendCircuitHandler(self.relaypicker,
                         self.idpubkey))
 
-            # first check to make sure the circuit is still open, in case there
-            # were any errors when creating it
-            if circhandler.is_closed:
-                print("CIRCUIT IS CLOSED")
-                self.channel_send_cell(CloseCell())
-
             # Send the ntor reply
             self.send_msg(CircuitCellMsg(msg.circid,
                     TelescopingCreatedCircuitCell(reply)), peeraddr)