[bridgedb/master] 4297 - Implement ipCategories functionality

commit f022b905ca01a193aabd4d78107f27fce85c40cd Author: aagbsn <aagbsn@extc.org> Date: Fri May 25 16:53:06 2012 -0700 4297 - Implement ipCategories functionality Implement ipCategories with filters so that compound filters can also be used (e.g. filter for ipv6 bridges) --- lib/bridgedb/Dist.py | 93 +++++++++++++++++++++++------------------------- lib/bridgedb/Server.py | 10 ++--- 2 files changed, 49 insertions(+), 54 deletions(-) diff --git a/lib/bridgedb/Dist.py b/lib/bridgedb/Dist.py index 15d9653..995eafb 100644 --- a/lib/bridgedb/Dist.py +++ b/lib/bridgedb/Dist.py @@ -44,11 +44,14 @@ class IPBasedDistributor(bridgedb.Bridges.BridgeHolder): ## areaClusterHmac -- an hmac function used to assign areas to rings. def __init__(self, areaMapper, nClusters, key, ipCategories=(), answerParameters=None): self.areaMapper = areaMapper + self.nClusters = nClusters self.answerParameters = answerParameters self.rings = [] - self.categoryRings = [] #DOCDDOC - self.categories = [] #DOCDOC + + self.categories = [] #DOCDOC + for c in ipCategories: + self.categories.append(c) key2 = bridgedb.Bridges.get_hmac(key, "Assign-Bridges-To-Rings") key3 = bridgedb.Bridges.get_hmac(key, "Order-Areas-In-Rings") @@ -58,36 +61,12 @@ class IPBasedDistributor(bridgedb.Bridges.BridgeHolder): # add splitter and cache the default rings # plus leave room for dynamic filters - ring_cache_size = nClusters + len(ipCategories) + 5 + ring_cache_size = self.nClusters + len(ipCategories) + 5 self.splitter = bridgedb.Bridges.FilteredBridgeSplitter(key2, max_cached_rings=ring_cache_size) logging.debug("added splitter %s" % self.splitter) - # assign bridges using a filter function - for n in xrange(nClusters): - key1 = bridgedb.Bridges.get_hmac(key, "Order-Bridges-In-Ring-%d"%n) - ring = bridgedb.Bridges.BridgeRing(key1, answerParameters) - ring.setName("IP ring %s"%n) #XXX: should be n+1 for consistency? - - g = filterAssignBridgesToRing(self.splitter.hmac, - nClusters + len(ipCategories), n) - self.splitter.addRing(ring, ring.name, g) - self.rings.append(ring) - - n = nClusters - for c in ipCategories: - logging.info("Building ring: Order-Bridges-In-Ring-%d"%n) - key1 = bridgedb.Bridges.get_hmac(key, "Order-Bridges-In-Ring-%d"%n) - ring = bridgedb.Bridges.BridgeRing(key1, answerParameters) - ring.setName("IP category ring %s"%n) #XXX: should be n+1 for consistency? - self.categoryRings.append( ring ) - self.categories.append( (c, ring) ) - g = filterAssignBridgesToRing(self.splitter.hmac, - nClusters + len(ipCategories), n) - self.splitter.addRing(ring, ring.name, g) - n += 1 - def clear(self): self.splitter.clear() @@ -112,29 +91,48 @@ class IPBasedDistributor(bridgedb.Bridges.BridgeHolder): area = self.areaMapper(ip) logging.info("area is %s" % area) - - for category, ring in self.categories: + + key1 = '' + pos = 0 + n = self.nClusters + + # only one of ip categories or area clustering is active + # try to match the request to an ip category + for category in self.categories: + # IP Categories logging.info("---------------------------------") if category.contains(ip): + g = Filters.filterAssignBridgesToRing(self.splitter.hmac, + self.nClusters + + len(self.categories), + n) + bridgeFilterRules.append(g) logging.info("category<%s>%s"%(epoch,area)) pos = self.areaOrderHmac("category<%s>%s"%(epoch,area)) - return ring.getBridges(pos, N, countryCode) - - # Bridge Filter Ruleset Construction + key1 = bridgedb.Bridges.get_hmac(self.splitter.key, + "Order-Bridges-In-Ring-%d"%n) + break; + n += 1 - # IP clustering; select only bridges from the corresponding cluster. - h = int( self.areaClusterHmac(area)[:8], 16) - # length of numClusters - clusterNum = h % len(self.rings) + # if no category matches, use area clustering + else: + # IP clustering + h = int( self.areaClusterHmac(area)[:8], 16) + # length of numClusters + clusterNum = h % self.nClusters - #XXX: assumes len(self.rings) = len(nClusters) - g = filterAssignBridgesToRing(self.splitter.hmac, - len(self.rings) + - len(self.categoryRings), - clusterNum) - bridgeFilterRules.append(g) + g = Filters.filterAssignBridgesToRing(self.splitter.hmac, + self.nClusters + + len(self.categories), + clusterNum) + bridgeFilterRules.append(g) + pos = self.areaOrderHmac("<%s>%s" % (epoch, area)) + key1 = bridgedb.Bridges.get_hmac(self.splitter.key, + "Order-Bridges-In-Ring-%d"%clusterNum) + logging.debug("bridgeFilterRules: %s" % bridgeFilterRules) - #XXX: is there a better way to cache by ruleset signature? + + # try to find a cached copy ruleset = frozenset(bridgeFilterRules) # See if we have a cached copy of the ring, @@ -142,16 +140,15 @@ class IPBasedDistributor(bridgedb.Bridges.BridgeHolder): if ruleset in self.splitter.filterRings.keys(): logging.debug("Cache hit %s" % ruleset) _,ring = self.splitter.filterRings[ruleset] + + # else create the ring and populate it else: logging.debug("Cache miss %s" % ruleset) - key1 = bridgedb.Bridges.get_hmac(self.splitter.key, - "Order-Bridges-In-Ring-%d"%clusterNum) ring = bridgedb.Bridges.BridgeRing(key1, self.answerParameters) - self.splitter.addRing(ring, ruleset, filterBridgesByRules(bridgeFilterRules), + self.splitter.addRing(ring, ruleset, Filters.filterBridgesByRules(bridgeFilterRules), populate_from=self.splitter.bridges) - # Now get the bridge. - pos = self.areaOrderHmac("<%s>%s" % (epoch, area)) + # get the bridge. return ring.getBridges(pos, N) def __len__(self): diff --git a/lib/bridgedb/Server.py b/lib/bridgedb/Server.py index 2de1289..4bdabb3 100644 --- a/lib/bridgedb/Server.py +++ b/lib/bridgedb/Server.py @@ -156,15 +156,13 @@ class WebResource(twisted.web.resource.Resource): ipv6 = False if "ipv6" in request.postpath: ipv6 = True + rules = [] + if ip: if ipv6: - #XXX: this ruleset bypasses areamapper and bridge clusters. - # for now, there are very few IPv6 bridges. - rules=[filterBridgesByIP6] + rules.append(filterBridgesByIP6) else: - #XXX: default to areamapper + cluster, does not use oraddress - rules = None - #rules=[filterBridgesByIP4] + rules.append(filterBridgesByIP4) bridges = self.distributor.getBridgesForIP(ip, interval, self.nBridgesToGive,
participants (1)
-
aagbsn@torproject.org