|
@@ -10,6 +10,48 @@ import nacl.public
|
|
|
import network
|
|
|
import dirauth
|
|
|
|
|
|
+class CircuitCellMsg(network.NetMsg):
|
|
|
+ """Send a message tagged with a circuit id."""
|
|
|
+ def __init__(self, circuitid, msg):
|
|
|
+ self.circid = circuitid
|
|
|
+ self.msg = msg
|
|
|
+
|
|
|
+ def __str__(self):
|
|
|
+ return "C%d:%s" % (self.circid, self.msg)
|
|
|
+
|
|
|
+
|
|
|
+class MultiplexedCircuitConnection(network.Connection):
|
|
|
+ """A class representing a connection between a relay and either a
|
|
|
+ client or a relay, transporting cells from various circuits."""
|
|
|
+ def __init__(self):
|
|
|
+ super().__init__()
|
|
|
+ # The CellRelay managing this MultiplexedCircuitConnection
|
|
|
+ self.cellrelay = None
|
|
|
+ # The MultiplexedCircuitConnection at the other end
|
|
|
+ self.peer = None
|
|
|
+ # The function to call when the connection closes
|
|
|
+ self.closer = lambda: 0
|
|
|
+
|
|
|
+ def closed(self):
|
|
|
+ self.closer()
|
|
|
+ self.peer = None
|
|
|
+
|
|
|
+ def close(self):
|
|
|
+ if self.peer is not None:
|
|
|
+ self.peer.closed()
|
|
|
+ self.closed()
|
|
|
+
|
|
|
+ def send_cell(self, circid, msg):
|
|
|
+ """Send the given message, tagged for the given circuit id."""
|
|
|
+ cell = CircuitCellMsg(circid, msg)
|
|
|
+ self.peer.received(self, cell)
|
|
|
+
|
|
|
+ def received(self, peer, cell):
|
|
|
+ """Callback when a cell is received from the network."""
|
|
|
+ circid, msg = cell.circid, cell.msg
|
|
|
+ print("received", msg, "on circuit", circid, "from", peer)
|
|
|
+
|
|
|
+
|
|
|
class Relay(network.Server):
|
|
|
"""The class representing an onion relay."""
|
|
|
|
|
@@ -68,6 +110,18 @@ class Relay(network.Server):
|
|
|
c.sendmsg(descmsg)
|
|
|
c.close()
|
|
|
|
|
|
+ def connected(self, peer):
|
|
|
+ """Callback invoked when someone (client or relay) connects to
|
|
|
+ us. Create a pair of linked MultiplexedCircuitConnections and
|
|
|
+ return the peer half to the peer."""
|
|
|
+
|
|
|
+ # Create the linked pair
|
|
|
+ peerconn = MultiplexedCircuitConnection()
|
|
|
+ ourconn = MultiplexedCircuitConnection()
|
|
|
+ peerconn.peer = ourconn
|
|
|
+ ourconn.peer = peerconn
|
|
|
+
|
|
|
+ return peerconn
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
# Start some dirauths
|
|
@@ -79,6 +133,7 @@ if __name__ == '__main__':
|
|
|
|
|
|
# Start some relays
|
|
|
numrelays = 10
|
|
|
+ relays = []
|
|
|
for i in range(numrelays):
|
|
|
# Relay bandwidths (at least the ones fast enough to get used)
|
|
|
# in the live Tor network (as of Dec 2019) are well approximated
|
|
@@ -86,7 +141,7 @@ if __name__ == '__main__':
|
|
|
# uniform integer in [1,2500]
|
|
|
x = random.randint(1,2500)
|
|
|
bw = int(200000-(200000-25000)/3*math.log10(x))
|
|
|
- Relay(dirauthaddrs, bw, 0)
|
|
|
+ relays.append(Relay(dirauthaddrs, bw, 0))
|
|
|
|
|
|
# Tick the epoch
|
|
|
network.thenetwork.nextepoch()
|
|
@@ -94,3 +149,7 @@ if __name__ == '__main__':
|
|
|
dirauth.DirAuth.consensus.verify(network.thenetwork.dirauthkeys())
|
|
|
|
|
|
print('ticked; epoch=', network.thenetwork.getepoch())
|
|
|
+
|
|
|
+ c = network.thenetwork.connect(relays[3].netaddr,relays[3].consensus.consdict['relays'][5].descdict['addr'])
|
|
|
+
|
|
|
+ c.send_cell(1, network.StringNetMsg("test"))
|