From 77c3dab7df2033d48e1c288e07de686978a575fb Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Tue, 29 May 2007 20:52:56 +0000 Subject: r13077@catbus: nickm | 2007-05-29 16:52:46 -0400 Make exitlist script handle multiple descriptors for one router (by only looking at the latest). Resolves bug 405. svn:r10402 --- contrib/exitlist | 49 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 8 deletions(-) (limited to 'contrib/exitlist') diff --git a/contrib/exitlist b/contrib/exitlist index 39c32f9ff..aabf739f6 100755 --- a/contrib/exitlist +++ b/contrib/exitlist @@ -58,6 +58,7 @@ import re import getopt import socket import struct +import time assert sys.version_info >= (2,2) @@ -196,10 +197,12 @@ class Policy: return True class Server: - def __init__(self, name, ip, policy): + def __init__(self, name, ip, policy, published, fingerprint): self.name = name self.ip = ip self.policy = policy + self.published = published + self.fingerprint = fingerprint def uniq_sort(lst): d = {} @@ -235,17 +238,34 @@ usage: cat ~/.tor/cached-routers* | %s [-v] [-x] [host:port [host:port [...]]] servers = [] policy = [] name = ip = None + published = 0 + fp = "" for line in sys.stdin.xreadlines(): if line.startswith('router '): if name: - servers.append(Server(name, ip, Policy.parseLines(policy))) + servers.append(Server(name, ip, Policy.parseLines(policy), + published, fp)) _, name, ip, rest = line.split(" ", 3) policy = [] + published = 0 + fp = "" + elif line.startswith('fingerprint') or \ + line.startswith('opt fingerprint'): + elts = line.strip().split() + if elts[0] == 'opt': del elts[0] + assert elts[0] == 'fingerprint' + del elts[0] + fp = "".join(elts) elif line.startswith('accept ') or line.startswith('reject '): policy.append(line.strip()) + elif line.startswith('published '): + date = time.strptime(line[len('published '):].strip(), + "%Y-%m-%d %H:%M:%S") + published = time.mktime(date) if name: - servers.append(Server(name, ip, Policy.parseLines(policy))) + servers.append(Server(name, ip, Policy.parseLines(policy), published, + fp)) targets = [] for line in ADDRESSES_OF_INTEREST.split("\n"): @@ -254,19 +274,32 @@ usage: cat ~/.tor/cached-routers* | %s [-v] [-x] [host:port [host:port [...]]] p = Pattern.parse(line) targets.append((p.ip, p.portMin)) - accepters, rejecters = [], [] + # remove all but the latest server of each IP/Nickname pair. + latest = {} + for s in servers: + if (not latest.has_key((s.fingerprint)) + or s.published > latest[(s.fingerprint)]): + latest[s.fingerprint] = s + servers = latest.values() + + accepters, rejecters = {}, {} for s in servers: for ip,port in targets: if s.policy.accepts(ip,port): - accepters.append(s) + accepters[s.ip] = s break else: - rejecters.append(s) + rejecters[s.ip] = s + + # If any server at IP foo accepts, the IP does not reject. + for k in accepters.keys(): + if rejecters.has_key(k): + del rejecters[k] if INVERSE: - printlist = rejecters + printlist = rejecters.values() else: - printlist = accepters + printlist = accepters.values() ents = [] if VERBOSE: -- cgit v1.2.3