[or-cvs] r18558: {torctl} Update to use the NEWCONSENSUS event. This means that TorCtl (torctl/trunk/python/TorCtl)

mikeperry at seul.org mikeperry at seul.org
Mon Feb 16 09:17:22 UTC 2009


Author: mikeperry
Date: 2009-02-16 04:17:22 -0500 (Mon, 16 Feb 2009)
New Revision: 18558

Modified:
   torctl/trunk/python/TorCtl/PathSupport.py
   torctl/trunk/python/TorCtl/StatsSupport.py
   torctl/trunk/python/TorCtl/TorCtl.py
Log:

Update to use the NEWCONSENSUS event. This means that TorCtl
users who use the PathSupport clases need to have a Tor of
r18556 or newer.



Modified: torctl/trunk/python/TorCtl/PathSupport.py
===================================================================
--- torctl/trunk/python/TorCtl/PathSupport.py	2009-02-16 06:18:44 UTC (rev 18557)
+++ torctl/trunk/python/TorCtl/PathSupport.py	2009-02-16 09:17:22 UTC (rev 18558)
@@ -48,6 +48,7 @@
 import Queue
 import time
 import TorUtil
+import sets
 from TorUtil import *
 
 __all__ = ["NodeRestrictionList", "PathRestrictionList",
@@ -1119,24 +1120,26 @@
       delay_job(self)
 
   def read_routers(self, nslist):
-    for ns in nslist:
-      if not "Running" in ns.flags:
-        if ns.idhex in self.routers:
-          self.routers[ns.idhex].down = True
-          self.routers[ns.idhex].flags = ns.flags
-          if self.routers[ns.idhex].refcount == 0:
-            self.routers[ns.idhex].deleted = True
-            plog("INFO", "Expiring non-running router "+ns.idhex)
-            self.sorted_r.remove(self.routers[ns.idhex])
-            del self.routers[ns.idhex]
-          else:
-            plog("INFO", "Postponing expiring non-running router "+ns.idhex)
-            self.routers[ns.idhex].deleted = True
+    old_idhexes = sets.Set(self.routers.keys())
+    new_idhexes = sets.Set(map(lambda ns: ns.idhex, nslist))
+    removed_idhexes = old_idhexes - new_idhexes
+    removed_idhexes.union_update(sets.Set(map(lambda ns: ns.idhex,
+                      filter(lambda ns: "Running" not in ns.flags, nslist))))
 
-    nslist = filter(lambda ns: "Running" in ns.flags, nslist)
-  
+    for i in removed_idhexes:
+      if i not in self.routers: continue
+      self.routers[i].down = True
+      self.routers[i].flags.remove("Running")
+      if self.routers[i].refcount == 0:
+        self.routers[i].deleted = True
+        plog("INFO", "Expiring non-running router "+i)
+        self.sorted_r.remove(self.routers[i])
+        del self.routers[i]
+      else:
+        plog("INFO", "Postponing expiring non-running router "+ns.idhex)
+        self.routers[i].deleted = True
+
     routers = self.c.read_routers(nslist)
-    new_routers = []
     for r in routers:
       self.name_to_key[r.nickname] = "$"+r.idhex
       if r.idhex in self.routers:
@@ -1149,8 +1152,8 @@
       else:
         rc = self.RouterClass(r)
         self.routers[rc.idhex] = rc
-        new_routers.append(rc)
-    self.sorted_r.extend(new_routers)
+
+    self.sorted_r = filter(lambda r: not r.down, self.routers.itervalues())
     self.sorted_r.sort(lambda x, y: cmp(y.bw, x.bw))
     for i in xrange(len(self.sorted_r)): self.sorted_r[i].list_rank = i
 
@@ -1390,19 +1393,12 @@
       self.streams[s.strm_id].bytes_read += s.bytes_read
       self.streams[s.strm_id].bytes_written += s.bytes_written
 
-  def ns_event(self, n):
+  def newconsensus_event(self, n):
     self.read_routers(n.nslist)
     self.selmgr.path_selector.rebuild_gens(self.sorted_r)
-    plog("DEBUG", "Read " + str(len(n.nslist))+" NS => " 
+    plog("DEBUG", "Read " + str(len(n.nslist))+" NC => " 
        + str(len(self.sorted_r)) + " routers")
   
-  def new_desc_event(self, d):
-    for i in d.idlist: # Is this too slow?
-      self.read_routers(self.c.get_network_status("id/"+i))
-    self.selmgr.path_selector.rebuild_gens(self.sorted_r)
-    plog("DEBUG", "Read " + str(len(d.idlist))+" Desc => " 
-       + str(len(self.sorted_r)) + " routers")
-
   def bandwidth_event(self, b): pass # For heartbeat only..
 
 ################### CircuitHandler #############################

Modified: torctl/trunk/python/TorCtl/StatsSupport.py
===================================================================
--- torctl/trunk/python/TorCtl/StatsSupport.py	2009-02-16 06:18:44 UTC (rev 18557)
+++ torctl/trunk/python/TorCtl/StatsSupport.py	2009-02-16 09:17:22 UTC (rev 18558)
@@ -677,20 +677,21 @@
           self.count_stream_reason_failed(s, reason)
     PathBuilder.stream_status_event(self, s)
 
-  def ns_event(self, n):
-    PathBuilder.ns_event(self, n)
+  def newconsensus_event(self, n):
+    PathBuilder.newconsensus_event(self, n)
     now = n.arrived_at
     for ns in n.nslist:
       if not ns.idhex in self.routers:
         continue
       r = self.routers[ns.idhex]
-      if "Running" in ns.flags:
+      if r.down:
+        if not r.hibernated_at:
+          r.hibernated_at = now
+          r.total_active_uptime += now - r.became_active_at
+        r.became_active_at = 0
+      else:
         if not r.became_active_at:
           r.became_active_at = now
           r.total_hibernation_time += now - r.hibernated_at
         r.hibernated_at = 0
-      else:
-        if not r.hibernated_at:
-          r.hibernated_at = now
-          r.total_active_uptime += now - r.became_active_at
-        r.became_active_at = 0
+

Modified: torctl/trunk/python/TorCtl/TorCtl.py
===================================================================
--- torctl/trunk/python/TorCtl/TorCtl.py	2009-02-16 06:18:44 UTC (rev 18557)
+++ torctl/trunk/python/TorCtl/TorCtl.py	2009-02-16 09:17:22 UTC (rev 18558)
@@ -41,6 +41,7 @@
 import binascii
 import types
 import time
+import sha
 from TorUtil import *
 
 # Types of "EVENT" message.
@@ -50,7 +51,8 @@
           ORCONN="ORCONN",
           STREAM_BW="STREAM_BW",
           BW="BW",
-          NS="NS",
+		  NS="NS",
+          NEWCONSENSUS="NEWCONSENSUS",
           NEWDESC="NEWDESC",
           ADDRMAP="ADDRMAP",
           DEBUG="DEBUG",
@@ -95,6 +97,9 @@
     self.arrived_at = 0
     self.nslist = nslist # List of NetworkStatus objects
 
+class NewConsensusEvent(NetworkStatusEvent):
+  pass
+
 class NewDescEvent:
   def __init__(self, event_name, idlist):
     self.event_name = event_name
@@ -300,7 +305,7 @@
       bw = re.search(r"^bandwidth (\d+) \d+ (\d+)", line)
       up = re.search(r"^uptime (\d+)", line)
       if re.search(r"^opt hibernating 1", line):
-        #dead = 1 # XXX: Technically this may be stale..
+        dead = True 
         if ("Running" in ns.flags):
           plog("INFO", "Hibernating router "+ns.nickname+" is running, flags: "+" ".join(ns.flags))
       if ac:
@@ -320,6 +325,7 @@
              router + " for " + ns.idhex)
     if not bw_observed and not dead and ("Valid" in ns.flags):
       plog("INFO", "No bandwidth for live router "+ns.nickname+", flags: "+" ".join(ns.flags))
+      dead = True
     if not version or not os:
       plog("INFO", "No version and/or OS for router " + ns.nickname)
     return Router(ns.idhex, ns.nickname, bw_observed, dead, exitpolicy,
@@ -684,8 +690,12 @@
 
   def get_router(self, ns):
     """Fill in a Router class corresponding to a given NS class"""
-    desc = self.sendAndRecv("GETINFO desc/id/" + ns.idhex + "\r\n")[0][2].split("\n")
-    return Router.build_from_desc(desc, ns)
+    desc = self.sendAndRecv("GETINFO desc/id/" + ns.idhex + "\r\n")[0][2]
+    sig_start = desc.find("\nrouter-signature\n")+len("\nrouter-signature\n")
+    fp_base64 = sha.sha(desc[:sig_start]).digest().encode("base64")[:-2]
+    if fp_base64 != ns.orhash:
+      plog("WARN", "Router descriptor for "+ns.idhex+" does not match ns fingerprint ("+ns.orhash+" vs "+fp_base64+")")
+    return Router.build_from_desc(desc.split("\n"), ns)
 
 
   def read_routers(self, nslist):
@@ -862,7 +872,8 @@
       "ERR" : self.msg_event,
       "NEWDESC" : self.new_desc_event,
       "ADDRMAP" : self.address_mapped_event,
-      "NS" : self.ns_event
+      "NS" : self.ns_event,
+      "NEWCONSENSUS" : self.newconsensus_event
       }
 
   def _handle1(self, timestamp, lines):
@@ -975,6 +986,8 @@
       event = AddrMapEvent(evtype, fromaddr, toaddr, when)
     elif evtype == "NS":
       event = NetworkStatusEvent(evtype, parse_ns_body(data))
+    elif evtype == "NEWCONSENSUS":
+      event = NewConsensusEvent(evtype, parse_ns_body(data))
     else:
       event = UnknownEvent(evtype, body)
 
@@ -1029,6 +1042,9 @@
   def ns_event(self, event):
     raise NotImplemented()
 
+  def newconsensus_event(self, event):
+    raise NotImplemented()
+
   def address_mapped_event(self, event):
     """Called when Tor adds a mapping for an address if listening
        to ADDRESSMAPPED events.
@@ -1065,6 +1081,9 @@
         ns.updated.isoformat(), ns.ip, str(ns.orport),
         str(ns.dirport), " ".join(ns.flags)))
 
+  def newconsensus_event(self, nc_event):
+    self.ns_event(nc_event)
+
   def new_desc_event(self, newdesc_event):
     print " ".join((newdesc_event.event_name, " ".join(newdesc_event.idlist)))
    
@@ -1146,7 +1165,7 @@
   #set_events(s,[EVENT_TYPE.WARN])
 #  c.set_events([EVENT_TYPE.ORCONN], True)
   c.set_events([EVENT_TYPE.STREAM, EVENT_TYPE.CIRC,
-          EVENT_TYPE.NS, EVENT_TYPE.NEWDESC,
+          EVENT_TYPE.NEWCONSENSUS, EVENT_TYPE.NEWDESC,
           EVENT_TYPE.ORCONN, EVENT_TYPE.BW], True)
 
   th.join()



More information about the tor-commits mailing list