[or-cvs] r19583: {torctl} Add some basic timer support to TorCtl and slightly change h (torctl/trunk/python/TorCtl)

mikeperry at seul.org mikeperry at seul.org
Fri May 29 13:11:47 UTC 2009


Author: mikeperry
Date: 2009-05-29 09:11:47 -0400 (Fri, 29 May 2009)
New Revision: 19583

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

Add some basic timer support to TorCtl and slightly change how
ConserveExitsRestriction behaves.



Modified: torctl/trunk/python/TorCtl/PathSupport.py
===================================================================
--- torctl/trunk/python/TorCtl/PathSupport.py	2009-05-29 13:10:27 UTC (rev 19582)
+++ torctl/trunk/python/TorCtl/PathSupport.py	2009-05-29 13:11:47 UTC (rev 19583)
@@ -134,7 +134,7 @@
   def __init__(self, sorted_r, rstr_list):
     """Constructor. Takes a bandwidth-sorted list of Routers 'sorted_r' 
     and a NodeRestrictionList 'rstr_list'"""
-    self.rstr_list = rstr_list # Check me before you yield!
+    self.rstr_list = rstr_list
     self.rebuild(sorted_r)
 
   def reset_restriction(self, rstr_list):
@@ -263,8 +263,17 @@
 
 class ConserveExitsRestriction(NodeRestriction):
   "Restriction to reject exits from selection"
-  def r_is_ok(self, r): return not "Exit" in r.flags
+  def __init__(self, exit_ports=None):
+    self.exit_ports = exit_ports
 
+  def r_is_ok(self, r):
+    if self.exit_ports:
+      for port in self.exit_ports:
+        if r.will_exit_to("255.255.255.255", port):
+          return False
+      return True
+    return not "Exit" in r.flags
+
   def __str__(self):
     return self.__class__.__name__+"()"
 
@@ -965,7 +974,7 @@
   def __init__(self, pathlen, order_exits,
          percent_fast, percent_skip, min_bw, use_all_exits,
          uniform, use_exit, use_guards,geoip_config=None,
-         restrict_guards=False, extra_node_rstr=None):
+         restrict_guards=False, extra_node_rstr=None, exit_ports=None):
     BaseSelectionManager.__init__(self)
     self.__ordered_exit_gen = None 
     self.pathlen = pathlen
@@ -981,6 +990,7 @@
     self.restrict_guards_only = restrict_guards
     self.bad_restrictions = False
     self.consensus = None
+    self.exit_ports = exit_ports
     self.extra_node_rstr=extra_node_rstr
 
   def reconfigure(self, consensus=None):
@@ -1021,12 +1031,12 @@
 
     entry_rstr = NodeRestrictionList(
       [PercentileRestriction(self.percent_skip, self.percent_fast, sorted_r),
-       ConserveExitsRestriction(),
+       ConserveExitsRestriction(self.exit_ports),
        FlagsRestriction(entry_flags, [])]
     )
     mid_rstr = NodeRestrictionList(
       [PercentileRestriction(nonentry_skip, nonentry_fast, sorted_r),
-       ConserveExitsRestriction(),
+       ConserveExitsRestriction(self.exit_ports),
        FlagsRestriction(["Running","Fast"], [])]
 
     )
@@ -1334,10 +1344,10 @@
       self.do_reconfigure = False
     
     if self.run_all_jobs:
-      self.run_all_jobs = False
       while not self.low_prio_jobs.empty():
         imm_job = self.low_prio_jobs.get_nowait()
         imm_job(self)
+      self.run_all_jobs = False
       return
 
     # If event is stream:NEW*/DETACHED or circ BUILT/FAILED, 

Modified: torctl/trunk/python/TorCtl/SQLSupport.py
===================================================================
--- torctl/trunk/python/TorCtl/SQLSupport.py	2009-05-29 13:10:27 UTC (rev 19582)
+++ torctl/trunk/python/TorCtl/SQLSupport.py	2009-05-29 13:11:47 UTC (rev 19583)
@@ -638,9 +638,12 @@
     TorCtl.DualEventListener.__init__(self)
     self.last_desc_at = time.time()-10.0
     self.consensus = None
+  
+  CONSENSUS_DONE = 0x7fffffff
 
   # TODO: What about non-running routers and uptime information?
   def _update_rank_history(self, idlist):
+    plog("INFO", "Consensus change... Updating rank history")
     for idhex in idlist:
       if idhex not in self.consensus.routers: continue
       rc = self.consensus.routers[idhex]
@@ -652,9 +655,11 @@
       r.bw_history.append(bwh)
       tc_session.add(bwh)
       tc_session.add(r)
+    plog("INFO", "Consensus history updated.")
     tc_session.commit()
  
   def _update_db(self, idlist):
+    plog("INFO", "Consensus change... Updating db")
     for idhex in idlist:
       if idhex in self.consensus.routers:
         rc = self.consensus.routers[idhex]
@@ -668,6 +673,7 @@
  
         r.from_router(rc)
         tc_session.add(r)
+    plog("INFO", "Consensus db updated")
     tc_session.commit()
 
   def update_consensus(self):
@@ -713,8 +719,8 @@
       if e.arrived_at - self.last_desc_at > 30.0:
         if not PathSupport.PathBuilder.is_urgent_event(e):
           plog("INFO", "Newdesc timer is up. Assuming we have full consensus")
-          self.last_desc_at = 0x7fffffff
           self._update_rank_history(self.consensus.ns_map.iterkeys())
+          self.last_desc_at = ConsensusTrackerListener.CONSENSUS_DONE
 
   def new_consensus_event(self, n):
     if n.state == EVENT_STATE.POSTLISTEN:

Modified: torctl/trunk/python/TorCtl/TorCtl.py
===================================================================
--- torctl/trunk/python/TorCtl/TorCtl.py	2009-05-29 13:10:27 UTC (rev 19582)
+++ torctl/trunk/python/TorCtl/TorCtl.py	2009-05-29 13:11:47 UTC (rev 19583)
@@ -108,6 +108,11 @@
     self.arrived_at = 0
     self.state = EVENT_STATE.PRISTINE
 
+class TimerEvent(Event):
+  def __init__(self, event_name, type):
+    Event.__init__(self, event_name)
+    self.type = type
+
 class NetworkStatusEvent(Event):
   def __init__(self, event_name, nslist):
     Event.__init__(self, event_name)
@@ -584,12 +589,12 @@
       handler.pre_listeners = self._handler.pre_listeners
       handler.post_listeners = self._handler.post_listeners
     self._handler = handler
+    self._handler.c = self
     self._handleFn = handler._handle1
 
   def add_event_listener(self, listener):
     if not self._handler:
-      self._handler = EventHandler()
-      self._handleFn = self._handler._handle1
+      self.set_event_handler(EventHandler())
     self._handler.add_event_listener(listener)
 
   def _read_reply(self):
@@ -641,6 +646,20 @@
       self._debugFile.write(str(time.time())+"\t>>> "+amsg)
     self._s.write(msg)
 
+  def set_timer(self, in_seconds, type=None):
+    event = (("650", "TORCTL_TIMER", type),)
+    threading.Timer(in_seconds, lambda: 
+                  self._eventQueue.put((time.time(), event))).start()
+
+  def set_periodic_timer(self, every_seconds, type=None):
+    event = (("650", "TORCTL_TIMER", type),)
+    def notlambda():
+      plog("DEBUG", "Timer fired for type "+str(type))
+      self._eventQueue.put((time.time(), event))
+      self._eventQueue.put((time.time(), event))
+      threading.Timer(every_seconds, notlambda).start()
+    threading.Timer(every_seconds, notlambda).start()
+
   def sendAndRecv(self, msg="", expectedTypes=("250", "251")):
     """Helper: Send a command 'msg' to Tor, and wait for a command
        in response.  If the response type is in expectedTypes,
@@ -942,6 +961,7 @@
   def ns_event(self, event): pass
   def new_consensus_event(self, event): pass
   def address_mapped_event(self, event): pass
+  def timer_event(self, event): pass
 
 class EventListener(EventSink):
   """An 'EventListener' is a passive sink for parsed Tor events. It 
@@ -968,7 +988,8 @@
       "NEWDESC" : self.new_desc_event,
       "ADDRMAP" : self.address_mapped_event,
       "NS" : self.ns_event,
-      "NEWCONSENSUS" : self.new_consensus_event
+      "NEWCONSENSUS" : self.new_consensus_event,
+      "TORCTL_TIMER" : self.timer_event
       }
     self.parent_handler = None
     self._sabotage()
@@ -1010,8 +1031,10 @@
       "NEWDESC" : self.new_desc_event,
       "ADDRMAP" : self.address_mapped_event,
       "NS" : self.ns_event,
-      "NEWCONSENSUS" : self.new_consensus_event
+      "NEWCONSENSUS" : self.new_consensus_event,
+      "TORCTL_TIMER" : self.timer_event
       }
+    self.c = None # Gets set by Connection.set_event_hanlder()
     self.pre_listeners = []
     self.post_listeners = []
 
@@ -1135,6 +1158,8 @@
       event = NetworkStatusEvent(evtype, parse_ns_body(data))
     elif evtype == "NEWCONSENSUS":
       event = NewConsensusEvent(evtype, parse_ns_body(data))
+    elif evtype == "TORCTL_TIMER":
+      event = TimerEvent(evtype, data)
     else:
       event = UnknownEvent(evtype, body)
 
@@ -1205,6 +1230,9 @@
     """
     pass
 
+  def timer_event(self, event):
+    pass
+
 class Consensus:
   """
   A Consensus is a pickleable container for the members of
@@ -1228,7 +1256,6 @@
   def __init__(self, c, RouterClass=Router):
     EventHandler.__init__(self)
     c.set_event_handler(self)
-    self.c = c
     self.ns_map = {}
     self.routers = {}
     self.sorted_r = []



More information about the tor-commits mailing list