Browse Source

wip- figure out how client receives cells

Chelsea H. Komlo 4 years ago
parent
commit
fbba94bfe4
2 changed files with 35 additions and 8 deletions
  1. 12 4
      client.py
  2. 23 4
      relay.py

+ 12 - 4
client.py

@@ -158,10 +158,11 @@ class TelescopingExtendedHandler:
 class ClientChannelManager(relay.ChannelManager):
     """The subclass of ChannelManager for clients."""
 
-    def __init__(self, myaddr, dirauthaddrs, perfstats):
+    def __init__(self, myaddr, dirauthaddrs, perfstats, open_circuits):
         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."""
@@ -241,6 +242,8 @@ 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)
@@ -266,6 +269,8 @@ 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)
@@ -280,8 +285,6 @@ class ClientChannelManager(relay.ChannelManager):
         # Send the message
         guardchannel.send_msg(circcreatemsg)
 
-        print("Log: Successfully creating a telescoping circuit")
-
         return circhandler
 
     def new_circuit(self):
@@ -308,6 +311,9 @@ class ClientChannelManager(relay.ChannelManager):
     def received_cell(self, circid, cell, peeraddr, channel):
         """Callback with a circuit-specific cell is received."""
         print("Client %s received cell on circ %d: %s from %s" % (self.myaddr, circid, cell, peeraddr))
+        if isinstance(msg, relay.CloseCell):
+            print("Log: Client received close cell; closing circuit")
+            # TODO close cell
         return super().received_cell(circid, cell, peeraddr, channel)
 
 
@@ -321,7 +327,9 @@ class Client:
         self.perfstats = network.PerfStats(network.EntType.CLIENT)
         self.perfstats.name = "Client at %s" % self.netaddr
         self.perfstats.is_bootstrapping = True
-        self.channelmgr = ClientChannelManager(self.netaddr, dirauthaddrs, self.perfstats)
+        self.open_circuits = {}
+        self.channelmgr = ClientChannelManager(self.netaddr, dirauthaddrs,
+                self.perfstats, self.open_circuits)
 
         # Register for epoch tick notifications
         network.thenetwork.wantepochticks(self, True)

+ 23 - 4
relay.py

@@ -101,6 +101,7 @@ class CloseCell(RelayCell):
     the circuit it was received on and the adjacent one."""
 
 
+
 # It is intentional that VanillaCreateCircuitMsg is a RelayNetMsg and
 # not a RelayCell.  This is the message that _creates_ the circuit, so
 # it can't be sent as a cell _within_ the circuit.
@@ -290,8 +291,9 @@ class TelescopingExtendCircuitHandler:
     existing and new circuits together, and forwards a
     TelescopingCreateCircuitMsg to the next hop."""
 
-    def __init__(self, relaypicker):
+    def __init__(self, relaypicker, current_relay_idkey):
         self.relaypicker = relaypicker
+        self.current_relay_idkey = current_relay_idkey
 
     def received_cell(self, circhandler, cell):
         # Remove ourselves from handling a second
@@ -302,6 +304,14 @@ class TelescopingExtendCircuitHandler:
         # Find the SNIP corresponding to the  index sent by the client
         next_snip = self.relaypicker.pick_relay_by_uniform_index(cell.idx)
 
+        # 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.")
+            circhandler.close()
+            return
+
+
         # Allocate a new circuit id to the requested next hop
         channelmgr = circhandler.channel.channelmgr
         nexthopchannel = channelmgr.get_channel_to(next_snip.snipdict["addr"])
@@ -396,12 +406,15 @@ 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!!!!!!")
         if adjcirchandler is not None:
             adjcirchandler.adjacent_circuit_handler = None
         self.closer()
@@ -700,7 +713,6 @@ class RelayChannelManager(ChannelManager):
             self.send_msg(CircuitCellMsg(msg.circid,
                     VanillaCreatedCircuitCell(reply)), peeraddr)
         elif isinstance(msg, TelescopingCreateCircuitMsg):
-            print("LOG: Received TelescopingCreateCircuitMsg circuit message, handling.")
             # A new circuit has arrived
             circhandler = channel.new_circuit_with_circid(msg.circid)
             # Create the ntor reply
@@ -714,8 +726,15 @@ class RelayChannelManager(ChannelManager):
             # be at most one on this circuit).
             circhandler.replace_celltype_handler(
                     TelescopingExtendCircuitCell,
-                    TelescopingExtendCircuitHandler(self.relaypicker))
-            print("LOG: Sending TelescopingCreatedCircuitMsg circuit message")
+                    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)