|
@@ -13,12 +13,39 @@ class CellClient(relay.CellHandler):
|
|
|
def __init__(self, myaddr, dirauthaddrs):
|
|
|
super().__init__(myaddr, dirauthaddrs)
|
|
|
self.guardaddr = None
|
|
|
+ self.consensus_cdf = [0]
|
|
|
|
|
|
def get_consensus_from_fallbackrelay(self):
|
|
|
"""Download a fresh consensus from a random fallbackrelay."""
|
|
|
fb = random.choice(network.thenetwork.getfallbackrelays())
|
|
|
self.send_msg(relay.RelayGetConsensusMsg(), fb.netaddr)
|
|
|
|
|
|
+ def ensure_guard_vanilla(self):
|
|
|
+ """Ensure that we have a channel to a guard (Vanilla Onion
|
|
|
+ Routing version)."""
|
|
|
+ while True:
|
|
|
+ if self.guardaddr is None:
|
|
|
+
|
|
|
+ guard = self.consensus.select_weighted_relay(self.consensus_cdf)
|
|
|
+ self.guardaddr = guard.descdict['addr']
|
|
|
+
|
|
|
+
|
|
|
+ try:
|
|
|
+ self.get_channel_to(self.guardaddr)
|
|
|
+ except network.NetNoServer:
|
|
|
+
|
|
|
+ self.guardaddr = None
|
|
|
+
|
|
|
+ if self.guardaddr is not None:
|
|
|
+ break
|
|
|
+
|
|
|
+ print('chose guard=', self.guardaddr)
|
|
|
+
|
|
|
+ def ensure_guard(self):
|
|
|
+ """Ensure that we have a channel to a guard."""
|
|
|
+ if network.thenetwork.womode == network.WOMode.VANILLA:
|
|
|
+ self.ensure_guard_vanilla()
|
|
|
+
|
|
|
def received_msg(self, msg, peeraddr, peer):
|
|
|
"""Callback when a NetMsg not specific to a circuit is
|
|
|
received."""
|
|
@@ -26,6 +53,7 @@ class CellClient(relay.CellHandler):
|
|
|
if isinstance(msg, relay.RelayConsensusMsg):
|
|
|
self.consensus = msg.consensus
|
|
|
dirauth.verify_consensus(self.consensus, network.thenetwork.dirauthkeys())
|
|
|
+ self.consensus_cdf = self.consensus.bw_cdf()
|
|
|
else:
|
|
|
return super().received_msg(msg, peeraddr, peer)
|
|
|
|
|
@@ -35,7 +63,6 @@ class CellClient(relay.CellHandler):
|
|
|
return super().received_cell(circid, cell, peeraddr, peer)
|
|
|
|
|
|
|
|
|
-
|
|
|
class Client:
|
|
|
"""A class representing a Tor client."""
|
|
|
|
|
@@ -72,11 +99,12 @@ class Client:
|
|
|
def newepoch(self, epoch):
|
|
|
"""Callback that fires at the start of each epoch"""
|
|
|
|
|
|
- if self.cellhandler.consensus is None or \
|
|
|
- self.cellhandler.consensus.consdict['epoch'] != \
|
|
|
- network.thenetwork.getepoch():
|
|
|
-
|
|
|
- self.get_consensus()
|
|
|
+
|
|
|
+ self.get_consensus()
|
|
|
+
|
|
|
+
|
|
|
+ self.cellhandler.ensure_guard()
|
|
|
+
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
@@ -146,3 +174,20 @@ if __name__ == '__main__':
|
|
|
|
|
|
if ch.peer.cellhandler.channels[caddr].peer is not ch:
|
|
|
print('asymmetry:', caddr, ad, ch, ch.peer.cellhandler.channels[caddr].peer)
|
|
|
+
|
|
|
+ relays[3].terminate()
|
|
|
+ del relays[3]
|
|
|
+
|
|
|
+
|
|
|
+ network.thenetwork.nextepoch()
|
|
|
+
|
|
|
+
|
|
|
+ for c in clients:
|
|
|
+ print("%s: %s" % (c.netaddr, [ str(k) for k in c.cellhandler.channels.keys()]))
|
|
|
+ caddr = c.netaddr
|
|
|
+ for ad, ch in c.cellhandler.channels.items():
|
|
|
+ if ch.peer.cellhandler.myaddr != ad:
|
|
|
+ print('address mismatch:', caddr, ad, ch.peer.cellhandler.myaddr)
|
|
|
+
|
|
|
+ if ch.peer.cellhandler.channels[caddr].peer is not ch:
|
|
|
+ print('asymmetry:', caddr, ad, ch, ch.peer.cellhandler.channels[caddr].peer)
|