Browse Source

Start working on EXTEND/EXTENDED cells

Ian Goldberg 6 years ago
parent
commit
01f3ab560a
2 changed files with 50 additions and 23 deletions
  1. 31 21
      client.py
  2. 19 2
      relay.py

+ 31 - 21
client.py

@@ -9,10 +9,12 @@ import relay
 
 
 import nacl.hash
 import nacl.hash
 
 
-class CreatedHandler:
-    """A handler for VanillaCreatedCircuitMsg cells."""
+class VanillaCreatedExtendedHandler:
+    """A handler for VanillaCreatedCircuitMsg and
+    VanillaExtendedCircuitMsg cells."""
 
 
-    def __init__(self, ntor, expecteddesc):
+    def __init__(self, cellhandler, ntor, expecteddesc):
+        self.cellhandler = cellhandler
         self.ntor = ntor
         self.ntor = ntor
         self.expecteddesc = expecteddesc
         self.expecteddesc = expecteddesc
         self.onionkey = expecteddesc.descdict['onionkey']
         self.onionkey = expecteddesc.descdict['onionkey']
@@ -23,14 +25,38 @@ class CreatedHandler:
         enckey = nacl.hash.sha256(secret + b'upstream')
         enckey = nacl.hash.sha256(secret + b'upstream')
         deckey = nacl.hash.sha256(secret + b'downstream')
         deckey = nacl.hash.sha256(secret + b'downstream')
         circhandler.add_crypt_layer(enckey, deckey)
         circhandler.add_crypt_layer(enckey, deckey)
+        if len(circhandler.circuit_descs) == 0:
+            # This was a VanillaCreatedCircuitMsg
+            del circhandler.cell_dispatch_table[relay.VanillaCreatedCircuitMsg]
+        else:
+            # This was a VanillaExtendedCircuitMsg
+            del circhandler.cell_dispatch_table[relay.VanillaExtendedCircuitMsg]
         circhandler.circuit_descs.append(self.expecteddesc)
         circhandler.circuit_descs.append(self.expecteddesc)
 
 
         # Are we done building the circuit?
         # Are we done building the circuit?
         if len(circhandler.circuit_descs) == 3:
         if len(circhandler.circuit_descs) == 3:
             # Yes!
             # Yes!
-            del circhandler.cell_dispatch_table[relay.VanillaCreatedCircuitMsg]
             return
             return
 
 
+        nexthop = None
+        while nexthop is None:
+            nexthop = self.cellhandler.consensus.select_weighted_relay( \
+                    self.cellhandler.consensus_cdf)
+            if nexthop.descdict['addr'] in circhandler.circuit_descs:
+                nexthop = None
+
+        # Construct the VanillaExtendCircuitMsg cell
+        ntor = relay.NTor(self.cellhandler.perfstats)
+        ntor_request = ntor.request()
+        circextendmsg = relay.VanillaExtendCircuitMsg( \
+                nexthop.descdict['addr'], ntor_request)
+
+        # Set up the reply handler
+        circhandler.cell_dispatch_table[relay.VanillaExtendedCircuitMsg] = \
+                VanillaCreatedExtendedHandler(self, ntor, nexthop)
+
+        # Send the cell
+        circhandler.send_cell(circextendmsg)
 
 
 
 
 class CellClient(relay.CellHandler):
 class CellClient(relay.CellHandler):
@@ -92,27 +118,11 @@ class CellClient(relay.CellHandler):
 
 
         # Set up the reply handler
         # Set up the reply handler
         circhandler.cell_dispatch_table[relay.VanillaCreatedCircuitMsg] = \
         circhandler.cell_dispatch_table[relay.VanillaCreatedCircuitMsg] = \
-                CreatedHandler(ntor, self.guard)
+                VanillaCreatedExtendedHandler(self, ntor, self.guard)
 
 
         # Send the message
         # Send the message
         guardchannel.send_msg(circcreatemsg)
         guardchannel.send_msg(circcreatemsg)
 
 
-        # We have a guard already at this point, so choose a middle and
-        # an exit.  They must all be different.
-        middle = None
-        while middle is None:
-            middle = self.consensus.select_weighted_relay(self.consensus_cdf)
-            if middle.descdict['addr'] == self.guardaddr:
-                middle = None
-
-        exit = None
-        while exit is None:
-            exit = self.consensus.select_weighted_relay(self.consensus_cdf)
-            if exit.descdict['addr'] == self.guardaddr or \
-                    exit.descdict['addr'] == middle.descdict['addr']:
-                middle = None
-
-
     def new_circuit(self):
     def new_circuit(self):
         """Create a new circuit from this client."""
         """Create a new circuit from this client."""
         if network.thenetwork.womode == network.WOMode.VANILLA:
         if network.thenetwork.womode == network.WOMode.VANILLA:

+ 19 - 2
relay.py

@@ -55,6 +55,23 @@ class VanillaCreatedCircuitMsg(RelayNetMsg):
         self.ntor_reply = ntor_reply
         self.ntor_reply = ntor_reply
 
 
 
 
+class VanillaExtendCircuitMsg(RelayNetMsg):
+    """The message for requesting circuit creation in Vanilla Onion
+    Routing."""
+
+    def __init__(self, hopaddr, ntor_request):
+        self.hopaddr = hopaddr
+        self.ntor_request = ntor_request
+
+
+class VanillaExtendedCircuitMsg(RelayNetMsg):
+    """The message for responding to circuit creation in Vanilla Onion
+    Routing."""
+
+    def __init__(self, ntor_reply):
+        self.ntor_reply = ntor_reply
+
+
 class CircuitCellMsg(RelayNetMsg):
 class CircuitCellMsg(RelayNetMsg):
     """Send a message tagged with a circuit id."""
     """Send a message tagged with a circuit id."""
 
 
@@ -197,12 +214,12 @@ class CircuitHandler:
         if isinstance(cell, EncryptedMsg):
         if isinstance(cell, EncryptedMsg):
             cell = self.crypt_layer.decrypt_msg(cell)
             cell = self.crypt_layer.decrypt_msg(cell)
 
 
+        print("CircuitHandler: %s received cell %s on circuit %d from %s" % (self.channel.cellhandler.myaddr, cell, self.circid, self.channel.peer.cellhandler.myaddr))
+
         celltype = type(cell)
         celltype = type(cell)
         if celltype in self.cell_dispatch_table:
         if celltype in self.cell_dispatch_table:
             self.cell_dispatch_table[celltype].received_cell(self, cell)
             self.cell_dispatch_table[celltype].received_cell(self, cell)
 
 
-        print("CircuitHandler: %s received cell %s on circuit %d from %s" % (self.channel.cellhandler.myaddr, cell, self.circid, self.channel.peer.cellhandler.myaddr))
-
     def add_crypt_layer(self, enckey, deckey):
     def add_crypt_layer(self, enckey, deckey):
         """Add a processing layer to this CircuitHandler so that cells
         """Add a processing layer to this CircuitHandler so that cells
         we send will get encrypted with the first given key, and cells
         we send will get encrypted with the first given key, and cells