def sort_routers(self, sorted_routers): routers = copy.copy(sorted_routers) def ratio_cmp(r1, r2): if r1.bw / float(r1.desc_bw) > r2.bw / float(r2.desc_bw): return -1 elif r1.bw / float(r1.desc_bw) < r2.bw / float(r2.desc_bw): return 1 else: return 0 if self.speed == "fast": pass # no action needed elif self.speed == "slow": routers.reverse() elif self.speed == "fastratio": routers.sort(ratio_cmp) elif self.speed == "slowratio": routers.sort(lambda x, y: ratio_cmp(y, x)) # Print top 5 routers + ratios for i in xrange(5): TorUtil.plog( "DEBUG", self.speed + " router " + routers[i].nickname + " #" + str(i) + ": " + str(routers[i].bw) + "/" + str(routers[i].desc_bw) + " = " + str(routers[i].bw / float(routers[i].desc_bw))) return routers
def sort_routers(self, sorted_routers): routers = copy.copy(sorted_routers) def ratio_cmp(r1, r2): if r1.bw/float(r1.desc_bw) > r2.bw/float(r2.desc_bw): return -1 elif r1.bw/float(r1.desc_bw) < r2.bw/float(r2.desc_bw): return 1 else: return 0 if self.speed == "fast": pass # no action needed elif self.speed == "slow": routers.reverse() elif self.speed == "fastratio": routers.sort(ratio_cmp) elif self.speed == "slowratio": routers.sort(lambda x,y: ratio_cmp(y,x)) # Print top 3 routers + ratios if len(routers) < SAMPLE_SIZE: TorUtil.plog("WARN", "Only "+str(len(routers))+" in our list!") else: for i in xrange(SAMPLE_SIZE): TorUtil.plog("INFO", self.speed+" router "+routers[i].nickname+" #"+str(i)+": " +str(routers[i].bw)+"/"+str(routers[i].desc_bw)+" = " +str(routers[i].bw/float(routers[i].desc_bw))) return routers
def sort_routers(self, sorted_routers): routers = copy.copy(sorted_routers) def ratio_cmp(r1, r2): if r1.bw/float(r1.desc_bw) > r2.bw/float(r2.desc_bw): return -1 elif r1.bw/float(r1.desc_bw) < r2.bw/float(r2.desc_bw): return 1 else: return 0 if self.speed == "fast": pass # no action needed elif self.speed == "slow": routers.reverse() elif self.speed == "fastratio": routers.sort(ratio_cmp) elif self.speed == "slowratio": routers.sort(lambda x,y: ratio_cmp(y,x)) # Print top 5 routers + ratios for i in xrange(5): TorUtil.plog("DEBUG", self.speed+" router "+routers[i].nickname+" #"+str(i)+": " +str(routers[i].bw)+"/"+str(routers[i].desc_bw)+" = " +str(routers[i].bw/float(routers[i].desc_bw))) return routers
def new_desc_event(self, n): TorCtl.ConsensusTracker.new_desc_event(self, n) if self.need_guards and self.consensus_count >= DESCRIPTORS_NEEDED*len(self.ns_map): TorUtil.plog("INFO", "We have enough routers. Rejoice!") self.used_entries = [] self.set_entries() self.need_guards = False else: self.need_guards = True
def __init__(self, conn, speed): TorCtl.ConsensusTracker.__init__(self, conn, consensus_only=False) self.speed = speed self.used_entries = [] if self.consensus_count < DESCRIPTORS_NEEDED*len(self.ns_map): TorUtil.plog("NOTICE", "Insufficient routers to choose new guard. Waiting for more..") self.need_guards = True else: self.set_entries() self.need_guards = False
def set_entries(self): # XXX: This is inefficient, but if we do it now, we're sure that # we're always using the very latest networkstatus and descriptor data sorted_routers = self.sort_routers(self.current_consensus().sorted_r) entry_nodes = [] for i in xrange(len(sorted_routers)): if len(entry_nodes) >= SAMPLE_SIZE: break if (not sorted_routers[i].down and "Guard" in sorted_routers[i].flags): entry_nodes.append(sorted_routers[i].idhex) self.used_entries.append(sorted_routers[i].idhex) self.c.set_option("EntryNodes", ",".join(entry_nodes)) TorUtil.plog("NOTICE", self.speed+": Changed EntryNodes to: " + ",".join(map(lambda x: self.ns_map[x].nickname+"="+x, entry_nodes)))
def stream_status_event(self, event): if event.status == "NEW": if event.purpose != "USER": self.ignore_streams[event.strm_id] = True return if event.strm_id in self.ignore_streams: if event.status == "CLOSED": del self.ignore_streams[event.strm_id] return if event.circ_id not in self.all_circs: if event.circ_id: TorUtil.plog("WARN", "Unknown circuit id %d has a stream event %d %s" % \ (event.circ_id, event.strm_id, event.status)) return circ = self.all_circs[event.circ_id] if event.status == 'DETACHED' or event.status == 'FAILED': # Detached usually means there was some failure assert not circ.strm_id circ.used = True circ.strm_id = event.strm_id circ.stream_failed = True circ.stream_end_time = event.arrived_at if event.reason: circ.stream_fail_reason = event.reason if event.remote_reason: circ.stream_fail_reason += ":"+event.remote_reason self.write_circ(circ) # We have no explicit assurance here that tor will not # try to reuse this circuit later... But we should # print out a warn above if that happens. del self.all_circs[event.circ_id] # Some STREAM FAILED events are paired with a CLOSED, some are not :( if event.status == "FAILED": self.ignore_streams[event.strm_id] = True if event.status == 'CLOSED': assert not circ.strm_id or circ.stream_failed circ.used = True circ.strm_id = event.strm_id circ.stream_end_time = event.arrived_at self.write_circ(circ) del self.all_circs[event.circ_id]
def main(): if len(sys.argv) < 3: usage() return port = int(sys.argv[1]) speed = sys.argv[2] if not speed in ("fast", "slow", "fastratio", "slowratio"): TorUtil.plog("ERROR", "Second parameter must be 'fast', 'slow', 'fastratio', or 'slowratio'") return conn = TorCtl.connect(HOST, port) conn.set_option("StrictEntryNodes", "1") conn.set_option("UseEntryNodes", "1") EntryTracker(conn, speed) conn.set_events(["NEWCONSENSUS", "NEWDESC", "NS", "GUARD"]) conn.block_until_close()
def handle_entry_deaths(self, event): state = event.status if (state == "DOWN" or state == "BAD" or state == "DROPPED"): if self.consensus_count < DESCRIPTORS_NEEDED*len(self.ns_map): self.need_guards = True TorUtil.plog("NOTICE", "Insufficient routers to choose new guard. Waiting for more..") return nodes_tuple = self.c.get_option("EntryNodes") nodes_list = nodes_tuple[0][1].split(",") try: nodes_list.remove(event.idhex) nodes_list.append(self.get_next_guard()) self.c.set_option("EntryNodes", ",".join(nodes_list)) TorUtil.plog("NOTICE", "Entry: " + event.nick + ":" + event.idhex + " died, and we replaced it with: " + nodes_list[-1] + "!") nodes_tuple = self.c.get_option("EntryNodes") nodes_list = nodes_tuple[0][1] TorUtil.plog("INFO", "New nodes_list: " + nodes_list) except ValueError: TorUtil.plog("INFO", "GUARD event notified of an entry death that " + "is not in nodes_list! Mysterioush!") TorUtil.plog("INFO", "It was: " + event.nick + " : " + event.idhex)
def handle_entry_deaths(self, event): state = event.status if (state == "DOWN" or state == "BAD" or state == "DROPPED"): nodes_tuple = self.c.get_option("EntryNodes") nodes_list = nodes_tuple[0][1].split(",") try: nodes_list.remove(event.idhex) nodes_list.append(self.get_next_router(event.idhex, nodes_list)) self.c.set_option("EntryNodes", ",".join(nodes_list)) TorUtil.plog("NOTICE", "Entry: " + event.nick + ":" + event.idhex + " died, and we replaced it with: " + nodes_list[-1] + "!") nodes_tuple = self.c.get_option("EntryNodes") nodes_list = nodes_tuple[0][1] TorUtil.plog("INFO", "New nodes_list: " + nodes_list) except ValueError: TorUtil.plog("INFO", "GUARD event notified of an entry death that " + "is not in nodes_list! Mysterioush!") TorUtil.plog("INFO", "It was: " + event.nick + " : " + event.idhex)
def handle_entry_deaths(self, event): state = event.status if (state == "DOWN" or state == "BAD" or state == "DROPPED"): nodes_tuple = self.c.get_option("EntryNodes") nodes_list = nodes_tuple[0][1].split(",") try: nodes_list.remove(event.idhex) nodes_list.append(self.get_next_router(event.idhex, nodes_list)) self.c.set_option("EntryNodes", ",".join(nodes_list)) TorUtil.plog( "NOTICE", "Entry: " + event.nick + ":" + event.idhex + " died, and we replaced it with: " + nodes_list[-1] + "!") nodes_tuple = self.c.get_option("EntryNodes") nodes_list = nodes_tuple[0][1] TorUtil.plog("INFO", "New nodes_list: " + nodes_list) except ValueError: TorUtil.plog( "INFO", "GUARD event notified of an entry death that " + "is not in nodes_list! Mysterioush!") TorUtil.plog("INFO", "It was: " + event.nick + " : " + event.idhex)
def new_consensus_event(self, n): TorCtl.ConsensusTracker.new_consensus_event(self, n) TorUtil.plog("INFO", "New consensus arrived. Rejoice!") self.used_entries = [] self.set_entries()