[tor-commits] [compass/master] Re-introduce a separate filter for same network limits
karsten at torproject.org
karsten at torproject.org
Mon Sep 10 10:45:09 UTC 2012
commit dd78cd9b7858a5d9016e3831b6606ac0879e27a4
Author: delber <delber at riseup.net>
Date: Sun Sep 9 14:02:47 2012 +0000
Re-introduce a separate filter for same network limits
---
compass.py | 96 ++++++++++++++++++++++++++++++++----------------------------
1 files changed, 51 insertions(+), 45 deletions(-)
diff --git a/compass.py b/compass.py
index e79b71e..0bd823f 100755
--- a/compass.py
+++ b/compass.py
@@ -9,6 +9,7 @@
FAST_EXIT_BANDWIDTH_RATE = 95 * 125 * 1024 # 95 Mbit/s
FAST_EXIT_ADVERTISED_BANDWIDTH = 5000 * 1024 # 5000 kB/s
FAST_EXIT_PORTS = [80, 443, 554, 1755]
+FAST_EXIT_MAX_PER_NETWORK = 2
ALMOST_FAST_EXIT_BANDWIDTH_RATE = 80 * 125 * 1024 # 80 Mbit/s
ALMOST_FAST_EXIT_ADVERTISED_BANDWIDTH = 2000 * 1024 # 2000 kB/s
@@ -21,6 +22,7 @@ import os
from optparse import OptionParser, OptionGroup
import urllib
import re
+import itertools
class BaseFilter(object):
def accept(self, relay):
@@ -93,11 +95,10 @@ class FastExitFilter(BaseFilter):
self.fp = relay.get('fingerprint')
self.relay = relay
- def __init__(self, bandwidth_rate, advertised_bandwidth, ports, same_network):
+ def __init__(self, bandwidth_rate, advertised_bandwidth, ports):
self.bandwidth_rate = bandwidth_rate
self.advertised_bandwidth = advertised_bandwidth
self.ports = ports
- self.same_network = same_network
def load(self, all_relays):
# First, filter relays based on bandwidth and port requirements.
@@ -128,43 +129,45 @@ class FastExitFilter(BaseFilter):
if 'reject' in summary and not relevant_ports.isdisjoint(policy_ports):
continue
matching_relays.append(relay)
- # Second, filter relays based on same /24 requirement.
- if self.same_network:
- network_data = {}
- for relay in matching_relays:
- or_addresses = relay.get("or_addresses")
- no_of_addresses = 0
- for ip in or_addresses:
- ip, port = ip.rsplit(':', 1)
- # skip if ipv6
- if ':' in ip:
- continue
- no_of_addresses += 1
- if no_of_addresses > 1:
- print "[WARNING] - %s has more than one IPv4 OR address - %s" % relay.get("fingerprint"), or_addresses
- network = ip.rsplit('.', 1)[0]
- relay_info = self.Relay(relay)
- if network_data.has_key(network):
- if len(network_data[network]) > 1:
- # assume current relay to have smallest exit_probability
- min_exit = relay.get('exit_probability')
- min_id = -1
- for id, value in enumerate(network_data[network]):
- if value.exit < min_exit:
- min_exit = value.exit
- min_id = id
- if min_id != -1:
- del network_data[network][min_id]
- network_data[network].append(relay_info)
- else:
- network_data[network].append(relay_info)
- else:
- network_data[network] = [relay_info]
- matching_relays = []
- for relay_list in network_data.values():
- matching_relays.extend([relay.relay for relay in relay_list])
return matching_relays
+class SameNetworkFilter(BaseFilter):
+ def __init__(self, orig_filter, max_per_network=FAST_EXIT_MAX_PER_NETWORK):
+ self.orig_filter = orig_filter
+ self.max_per_network = max_per_network
+
+ def load(self, all_relays):
+ network_data = {}
+ for relay in self.orig_filter.load(all_relays):
+ or_addresses = relay.get("or_addresses")
+ no_of_addresses = 0
+ for ip in or_addresses:
+ ip, port = ip.rsplit(':', 1)
+ # skip if ipv6
+ if ':' in ip:
+ continue
+ no_of_addresses += 1
+ if no_of_addresses > 1:
+ print "[WARNING] - %s has more than one IPv4 OR address - %s" % relay.get("fingerprint"), or_addresses
+ network = ip.rsplit('.', 1)[0]
+ if network_data.has_key(network):
+ if len(network_data[network]) >= FAST_EXIT_MAX_PER_NETWORK:
+ # assume current relay to have smallest exit_probability
+ min_exit = relay.get('exit_probability')
+ min_id = -1
+ for id, value in enumerate(network_data[network]):
+ if value.get('exit_probability') < min_exit:
+ min_exit = value.get('exit_probability')
+ min_id = id
+ if min_id != -1:
+ del network_data[network][min_id]
+ network_data[network].append(relay)
+ else:
+ network_data[network].append(relay)
+ else:
+ network_data[network] = [relay]
+ return list(itertools.chain.from_iterable(network_data.values()))
+
class InverseFilter(BaseFilter):
def __init__(self, orig_filter):
self.orig_filter = orig_filter
@@ -218,20 +221,22 @@ class RelayStats(object):
filters.append(GuardFilter())
if options.fast_exits_only:
filters.append(
- FastExitFilter(FAST_EXIT_BANDWIDTH_RATE, FAST_EXIT_ADVERTISED_BANDWIDTH,
- FAST_EXIT_PORTS, same_network=True))
+ SameNetworkFilter(
+ FastExitFilter(FAST_EXIT_BANDWIDTH_RATE, FAST_EXIT_ADVERTISED_BANDWIDTH,
+ FAST_EXIT_PORTS)))
if options.almost_fast_exits_only:
filters.append(
FastExitFilter(ALMOST_FAST_EXIT_BANDWIDTH_RATE, ALMOST_FAST_EXIT_ADVERTISED_BANDWIDTH,
- ALMOST_FAST_EXIT_PORTS, same_network=False))
+ ALMOST_FAST_EXIT_PORTS))
filters.append(
InverseFilter(
- FastExitFilter(FAST_EXIT_BANDWIDTH_RATE, FAST_EXIT_ADVERTISED_BANDWIDTH,
- FAST_EXIT_PORTS, same_network=True)))
+ SameNetworkFilter(
+ FastExitFilter(FAST_EXIT_BANDWIDTH_RATE, FAST_EXIT_ADVERTISED_BANDWIDTH,
+ FAST_EXIT_PORTS))))
if options.fast_exits_only_any_network:
filters.append(
FastExitFilter(FAST_EXIT_BANDWIDTH_RATE, FAST_EXIT_ADVERTISED_BANDWIDTH,
- FAST_EXIT_PORTS, same_network=False))
+ FAST_EXIT_PORTS))
return filters
def _get_group_function(self, options):
@@ -361,10 +366,11 @@ def create_option_parser():
group.add_option("-g", "--guards-only", action="store_true",
help="select only relays suitable for guard position")
group.add_option("--fast-exits-only", action="store_true",
- help="select only fast exits (%d+ Mbit/s, %d+ KB/s, %s, 2- per /24)" %
+ help="select only fast exits (%d+ Mbit/s, %d+ KB/s, %s, %d- per /24)" %
(FAST_EXIT_BANDWIDTH_RATE / (125 * 1024),
FAST_EXIT_ADVERTISED_BANDWIDTH / 1024,
- '/'.join(map(str, FAST_EXIT_PORTS))))
+ '/'.join(map(str, FAST_EXIT_PORTS)),
+ FAST_EXIT_MAX_PER_NETWORK))
group.add_option("--almost-fast-exits-only", action="store_true",
help="select only almost fast exits (%d+ Mbit/s, %d+ KB/s, %s, not in set of fast exits)" %
(ALMOST_FAST_EXIT_BANDWIDTH_RATE / (125 * 1024),
More information about the tor-commits
mailing list