[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] r19380: {torctl} Add RateLimitedRestriction. Make the NodeRestrictionList be (torctl/trunk/python/TorCtl)
Author: mikeperry
Date: 2009-04-26 23:05:34 -0400 (Sun, 26 Apr 2009)
New Revision: 19380
Modified:
torctl/trunk/python/TorCtl/PathSupport.py
torctl/trunk/python/TorCtl/TorCtl.py
Log:
Add RateLimitedRestriction. Make the NodeRestrictionList be
MetaRestriction (and thus pass isinstance(self,
NodeRestriction)). Similar change for PathRestrictionList.
Modified: torctl/trunk/python/TorCtl/PathSupport.py
===================================================================
--- torctl/trunk/python/TorCtl/PathSupport.py 2009-04-26 23:57:26 UTC (rev 19379)
+++ torctl/trunk/python/TorCtl/PathSupport.py 2009-04-27 03:05:34 UTC (rev 19380)
@@ -73,7 +73,7 @@
"CountryCodeRestriction", "CountryRestriction",
"UniqueCountryRestriction", "SingleCountryRestriction",
"ContinentRestriction", "ContinentJumperRestriction",
-"UniqueContinentRestriction"]
+"UniqueContinentRestriction", "MetaPathRestriction", "RateLimitedRestriction"]
#################### Path Support Interfaces #####################
@@ -91,46 +91,19 @@
"Returns true if Router 'r' is acceptable for this restriction"
return True
-class NodeRestrictionList:
- "Class to manage a list of NodeRestrictions"
- def __init__(self, restrictions):
- "Constructor. 'restrictions' is a list of NodeRestriction instances"
- self.restrictions = restrictions
-
- def r_is_ok(self, r):
- "Returns true of Router 'r' passes all of the contained restrictions"
- for rs in self.restrictions:
- if not rs.r_is_ok(r): return False
- return True
-
- def add_restriction(self, restr):
- "Add a NodeRestriction 'restr' to the list of restrictions"
- self.restrictions.append(restr)
-
- # TODO: This does not collapse meta restrictions..
- def del_restriction(self, RestrictionClass):
- """Remove all restrictions of type RestrictionClass from the list.
- Does NOT inspect or collapse MetaNode Restrictions (though
- MetaRestrictions can be removed if RestrictionClass is
- MetaNodeRestriction)"""
- self.restrictions = filter(
- lambda r: not isinstance(r, RestrictionClass),
- self.restrictions)
-
- def clear(self):
- """ Remove all restrictions """
- self.restrictions = []
-
- def __str__(self):
- return self.__class__.__name__+"("+str(map(str, self.restrictions))+")"
-
class PathRestriction:
"Interface for path restriction policies"
def path_is_ok(self, path):
"Return true if the list of Routers in path satisfies this restriction"
return True
-class PathRestrictionList:
+# TODO: Or, Not, N of M
+class MetaPathRestriction(PathRestriction):
+ "MetaPathRestrictions are path restriction aggregators."
+ def add_restriction(self, rstr): raise NotImplemented()
+ def del_restriction(self, RestrictionClass): raise NotImplemented()
+
+class PathRestrictionList(MetaPathRestriction):
"""Class to manage a list of PathRestrictions"""
def __init__(self, restrictions):
"Constructor. 'restrictions' is a list of PathRestriction instances"
@@ -331,6 +304,15 @@
def __str__(self):
return self.__class__.__name__+"("+str(self.min_bw)+")"
+
+class RateLimitedRestriction(NodeRestriction):
+ def __init__(self, limited=True):
+ self.limited = limited
+
+ def r_is_ok(self, router): return router.rate_limited == self.limited
+
+ def __str__(self):
+ return self.__class__.__name__+"("+str(self.limited)+")"
class VersionIncludeRestriction(NodeRestriction):
"""Require that the version match one in the list"""
@@ -394,6 +376,7 @@
class MetaNodeRestriction(NodeRestriction):
"""Interface for a NodeRestriction that is an expression consisting of
multiple other NodeRestrictions"""
+ def add_restriction(self, rstr): raise NotImplemented()
# TODO: these should collapse the restriction and return a new
# instance for re-insertion (or None)
def next_rstr(self): raise NotImplemented()
@@ -444,7 +427,40 @@
def __str__(self):
return self.__class__.__name__+"("+str(map(str, self.rstrs))+","+str(self.n)+")"
+class NodeRestrictionList(MetaNodeRestriction):
+ "Class to manage a list of NodeRestrictions"
+ def __init__(self, restrictions):
+ "Constructor. 'restrictions' is a list of NodeRestriction instances"
+ self.restrictions = restrictions
+ def r_is_ok(self, r):
+ "Returns true of Router 'r' passes all of the contained restrictions"
+ for rs in self.restrictions:
+ if not rs.r_is_ok(r): return False
+ return True
+
+ def add_restriction(self, restr):
+ "Add a NodeRestriction 'restr' to the list of restrictions"
+ self.restrictions.append(restr)
+
+ # TODO: This does not collapse meta restrictions..
+ def del_restriction(self, RestrictionClass):
+ """Remove all restrictions of type RestrictionClass from the list.
+ Does NOT inspect or collapse MetaNode Restrictions (though
+ MetaRestrictions can be removed if RestrictionClass is
+ MetaNodeRestriction)"""
+ self.restrictions = filter(
+ lambda r: not isinstance(r, RestrictionClass),
+ self.restrictions)
+
+ def clear(self):
+ """ Remove all restrictions """
+ self.restrictions = []
+
+ def __str__(self):
+ return self.__class__.__name__+"("+str(map(str, self.restrictions))+")"
+
+
#################### Path Restrictions #####################
class Subnet16Restriction(PathRestriction):
@@ -897,10 +913,16 @@
manager, you must schedule a config update job using
PathBuilder.schedule_selmgr() with a worker function to modify
this object.
+
+ XXX: Warning. The constructor of this class is subject to change
+ and may undergo reorganization in the near future. Watch for falling
+ bits.
"""
+ # XXX: Hrmm, consider simplifying this. It is confusing and unweildy.
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):
+ uniform, use_exit, use_guards,geoip_config=None,
+ restrict_guards=False, extra_node_rstr=None):
BaseSelectionManager.__init__(self)
self.__ordered_exit_gen = None
self.pathlen = pathlen
@@ -916,6 +938,7 @@
self.restrict_guards_only = restrict_guards
self.bad_restrictions = False
self.consensus = None
+ self.extra_node_rstr=extra_node_rstr
def reconfigure(self, consensus=None):
try:
@@ -977,6 +1000,10 @@
[PercentileRestriction(nonentry_skip, nonentry_fast, sorted_r),
FlagsRestriction(["Valid", "Running","Fast"], ["BadExit"])])
+ if self.extra_node_rstr:
+ entry_rstr.add_restriction(self.extra_node_rstr)
+ mid_rstr.add_restriction(self.extra_node_rstr)
+ self.exit_rstr.add_restriction(self.extra_node_rstr)
# GeoIP configuration
if self.geoip_config:
@@ -1147,7 +1174,7 @@
# sometimes circuit closed events come before the stream
# close and we need to track those failures..
self.carried_streams = []
-
+
def id_path(self):
"Returns a list of idhex keys for the path of Routers"
return map(lambda r: r.idhex, self.path)
@@ -1413,7 +1440,7 @@
if s.strm_id in self.streams and self.streams[s.strm_id].ignored:
plog("DEBUG", "Ignoring stream: " + str(s.strm_id))
return
-
+
# XXX: Copy s.circ_id==0 check+reset from StatsSupport here too?
if s.status == "NEW" or s.status == "NEWRESOLVE":
Modified: torctl/trunk/python/TorCtl/TorCtl.py
===================================================================
--- torctl/trunk/python/TorCtl/TorCtl.py 2009-04-26 23:57:26 UTC (rev 19379)
+++ torctl/trunk/python/TorCtl/TorCtl.py 2009-04-27 03:05:34 UTC (rev 19380)
@@ -265,7 +265,7 @@
self.__dict__[i] = copy.deepcopy(args[0].__dict__[i])
return
else:
- (idhex, name, bw, down, exitpolicy, flags, ip, version, os, uptime, published, contact) = args
+ (idhex, name, bw, down, exitpolicy, flags, ip, version, os, uptime, published, contact, rate_limited) = args
self.idhex = idhex
self.nickname = name
self.bw = bw
@@ -282,6 +282,7 @@
self.refcount = 0 # How many open circs are we currently in?
self.deleted = False # Has Tor already deleted this descriptor?
self.contact = contact
+ self.rate_limited = rate_limited
def __str__(self):
s = self.idhex, self.nickname
@@ -328,7 +329,11 @@
elif rj:
exitpolicy.append(ExitPolicyLine(False, *rj.groups()))
elif bw:
- bw_observed = min(map(int, bw.groups()))
+ bws = map(int, bw.groups())
+ bw_observed = min(bws)
+ rate_limited = False
+ if bws[0] < bws[1]:
+ rate_limited = True
elif pl:
version, os = pl.groups()
elif up:
@@ -348,7 +353,7 @@
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,
- ns.flags, ip, version, os, uptime, published, contact)
+ ns.flags, ip, version, os, uptime, published, contact, rate_limited)
build_from_desc = Callable(build_from_desc)
def update_to(self, new):