[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] r10402: Make exitlist script handle multiple descriptors for one rou (in tor/trunk: . contrib)



Author: nickm
Date: 2007-05-29 16:52:56 -0400 (Tue, 29 May 2007)
New Revision: 10402

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/contrib/exitlist
Log:
 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.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r13077] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2007-05-29 20:31:40 UTC (rev 10401)
+++ tor/trunk/ChangeLog	2007-05-29 20:52:56 UTC (rev 10402)
@@ -159,6 +159,11 @@
     - Make the NodeFamilies config option work. (Reported by
       lodger -- it has never actually worked, even though we added it
       in Oct 2004.)
+    - In the exitlist script, only consider the most recently published
+      server descriptor for each server.  Also, when the user requests
+      a list of servers that _reject_ connections to a given address,
+      explicitly exclude the IPs that also have servers that accept
+      connections to that address.  (Resolves bug 405.)
 
   o Minor bugfixes (controller):
     - Make 'getinfo fingerprint' return a 551 error if we're not a

Modified: tor/trunk/contrib/exitlist
===================================================================
--- tor/trunk/contrib/exitlist	2007-05-29 20:31:40 UTC (rev 10401)
+++ tor/trunk/contrib/exitlist	2007-05-29 20:52:56 UTC (rev 10402)
@@ -58,6 +58,7 @@
 import getopt
 import socket
 import struct
+import time
 
 assert sys.version_info >= (2,2)
 
@@ -196,10 +197,12 @@
         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 @@
     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 @@
         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: