Browse Source

wip telescoping extend

Chelsea H. Komlo 4 years ago
parent
commit
bfd5f8f2a1
3 changed files with 90 additions and 13 deletions
  1. 66 7
      client.py
  2. 9 1
      dirauth.py
  3. 15 5
      relay.py

+ 66 - 7
client.py

@@ -64,14 +64,14 @@ class VanillaCreatedExtendedHandler:
         circhandler.send_cell(circextendmsg)
 
 class TelescopingCreatedHandler:
-    """A handler for TelescopingCreatedCircuitCell cells."""
+    """A handler for TelescopingCreatedCircuitCell cells; this will only always
+    communicate with the client's guard."""
 
-    def __init__(self, channelmgr, ntor, guarddesc):
+    def __init__(self, channelmgr, ntor):
         self.channelmgr = channelmgr
         self.ntor = ntor
-        self.guarddesc = guarddesc
-        self.onionkey = guarddesc.snipdict['onionkey']
-        self.idkey = guarddesc.snipdict['idkey']
+        self.onionkey = self.channelmgr.guard.snipdict['onionkey']
+        self.idkey = self.channelmgr.guard.snipdict['idkey']
 
     def received_cell(self, circhandler, cell):
         print("LOG: Received cell in TelescopingCreatedHandler")
@@ -81,13 +81,72 @@ class TelescopingCreatedHandler:
         deckey = nacl.hash.sha256(secret + b'downstream')
         circhandler.add_crypt_layer(enckey, deckey)
 
+        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")
+
+        # Construct the VanillaExtendCircuitCell
+        ntor = relay.NTor(self.channelmgr.perfstats)
+        ntor_request = ntor.request()
+        circextendmsg = relay.TelescopingExtendCircuitCell(
+                nexthopidx, ntor_request)
+
+        # Set up the reply handler
+        circhandler.replace_celltype_handler(
+                relay.TelescopingExtendedCircuitCell,
+                TelescopingExtendedHandler(self.channelmgr, ntor))
+
+        # Send the cell
+        circhandler.send_cell(circextendmsg)
+
+
+class TelescopingExtendedHandler:
+    """A handler for TelescopingExtendedCircuitCell cells."""
+
+    def __init__(self, channelmgr, ntor):
+        self.channelmgr = channelmgr
+        self.ntor = ntor
+
+    def received_cell(self, circhandler, cell):
+        print("LOG: Received cell in TelescopingExtendedHandler")
+
+        #TODO verify the SNIP that was received
+        # Bail if it is invalid
+
+        onionkey = cell.snip.snipdict['onionkey']
+        idkey = cell.snip.snipdict['idkey']
+
+        secret = self.ntor.verify(cell.ntor_reply, onionkey, idkey)
+        enckey = nacl.hash.sha256(secret + b'upstream')
+        deckey = nacl.hash.sha256(secret + b'downstream')
+        circhandler.add_crypt_layer(enckey, deckey)
+
+
         # Are we done building the circuit?
+        print("WARNING: we may need another circhandler structure for snips")
         if len(circhandler.circuit_descs) == 3:
             # Yes!
             return
 
-        sys.exit("Err: Unimplemented! Need to implement circuit extension for telescoping.")
+        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")
 
+        # Construct the VanillaExtendCircuitCell
+        ntor = relay.NTor(self.channelmgr.perfstats)
+        ntor_request = ntor.request()
+        circextendmsg = relay.TelescopingExtendCircuitCell(
+                nexthopidx, ntor_request)
+
+        # Set up the reply handler
+        circhandler.replace_celltype_handler(
+                relay.TelescopingExtendedCircuitCell,
+                TelescopingExtendedHandler(self.channelmgr, ntor))
+
+        # Send the cell
+        circhandler.send_cell(circextendmsg)
 
 class ClientChannelManager(relay.ChannelManager):
     """The subclass of ChannelManager for clients."""
@@ -209,7 +268,7 @@ class ClientChannelManager(relay.ChannelManager):
         # Set up the reply handler
         circhandler.replace_celltype_handler(
                 relay.TelescopingCreatedCircuitCell,
-                TelescopingCreatedHandler(self, ntor, self.guard))
+                TelescopingCreatedHandler(self, ntor))
 
         # Send the message
         guardchannel.send_msg(circcreatemsg)

+ 9 - 1
dirauth.py

@@ -302,6 +302,14 @@ class RelayPicker:
         idx = random.randint(0, totbw-1)
         return self.pick_relay_by_uniform_index(idx)
 
+    def pick_weighted_relay_index(self):
+        """Select a random relay index (for use in Walkig Onions) with probability proportional to its bw
+        weight."""
+        totbw = self.totbw
+        if totbw < 1:
+            raise ValueError("No relays to choose from")
+
+        return random.randint(0, totbw-1)
 
 class DirAuthNetMsg(network.NetMsg):
     """The subclass of NetMsg for messages to and from directory
@@ -425,7 +433,7 @@ class DirAuthConnection(network.ClientConnection):
             self.endive = msg.endive
         else:
             raise TypeError('Not a server-originating DirAuthNetMsg', msg)
-    
+
 
 class DirAuth(network.Server):
     """The class representing directory authorities."""

+ 15 - 5
relay.py

@@ -2,6 +2,7 @@
 
 import random # For simulation, not cryptography!
 import math
+import sys
 
 import nacl.utils
 import nacl.signing
@@ -166,8 +167,9 @@ class TelescopingExtendedCircuitCell(RelayCell):
     """The message for responding to circuit extension in Telescoping Walking
     Onions."""
 
-    def __init__(self, ntor_reply):
+    def __init__(self, ntor_reply, snip):
         self.ntor_reply = ntor_reply
+        self.snip = snip
 
 
 class EncryptedCell(RelayCell):
@@ -287,19 +289,24 @@ class TelescopingExtendCircuitHandler:
     existing and new circuits together, and forwards a
     TelescopingCreateCircuitMsg to the next hop."""
 
+    def __init__(self, relaypicker):
+        self.relaypicker = relaypicker
+
     def received_cell(self, circhandler, cell):
         # Remove ourselves from handling a second
         # TelescopingExtendCircuitCell on this circuit
         circhandler.replace_celltype_handler(TelescopingExtendCircuitCell, None)
 
+        # Find the SNIP corresponding to the  index sent by the client
+        next_snip = self.relaypicker.pick_relay_by_uniform_index(cell.idx)
+
         # Allocate a new circuit id to the requested next hop
         channelmgr = circhandler.channel.channelmgr
-        nexthopchannel = channelmgr.get_channel_to(cell.hopaddr)
-        print("WARNING: Unimplemented! " +  cell.hopaddr)
+        nexthopchannel = channelmgr.get_channel_to(next_snip.snipdict["addr"])
 
         #newcircid, newcirchandler = nexthopchannel.new_circuit()
 
-        print("WARNING: Unimplemented! TelescopingExtendCircuitHandler")
+        sys.exit("WARNING: Unimplemented! TelescopingExtendCircuitHandler")
 
 
 
@@ -679,11 +686,14 @@ class RelayChannelManager(ChannelManager):
             # Add a handler for if an Extend Cell arrives (there should
             # be at most one on this circuit).
             circhandler.replace_celltype_handler(
-                    TelescopingExtendCircuitCell, TelescopingExtendCircuitHandler())
+                    TelescopingExtendCircuitCell,
+                    TelescopingExtendCircuitHandler(self.relaypicker))
             print("LOG: Sending TelescopingCreatedCircuitMsg circuit message")
             # Send the ntor reply
             self.send_msg(CircuitCellMsg(msg.circid,
                     TelescopingCreatedCircuitCell(reply)), peeraddr)
+        elif isinstance(msg, TelescopingExtendCircuitMsg):
+            sys.exit("ERR: TelescopingExtendCircuitMsg is not yet implemented ")
         else:
             return super().received_msg(msg, peeraddr, channel)