Loading sbws/core/scanner.py +18 −3 Original line number Diff line number Diff line ''' Measure the relays. ''' from ..lib.circuitbuilder import FooCircuitBuilder as CB from ..lib.circuitbuilder import GapsCircuitBuilder as CB from ..lib.resultdump import ResultDump from ..lib.resultdump import ResultSuccess # from ..lib.resultdump import ResultErrorCircuit Loading Loading @@ -188,7 +188,19 @@ def measure_relay(args, conf, destinations, cb, rl, relay): log.warning('Unable to get destination to measure %s %s', relay.nickname, relay.fingerprint[0:8]) return None circ_id = cb.build_circuit([relay.fingerprint]) exits = rl.exits_can_exit_to(dest.hostname, dest.port) exits = [e for e in exits if e.fingerprint != relay.fingerprint] exits = stem_utils.only_relays_with_bandwidth( cb.controller, exits, min_bw=round(relay.bandwidth*1.25), max_bw=max(round(relay.bandwidth*2.00), 100)) if len(exits) < 1: log.warning('No available exits to help measure %s %s', relay.nickname, relay.fingerprint[0:8]) # TODO: Return ResultError of some sort return None exit = random.choice(exits) # exits = stem_utils.only_relays_with_bandwidth() circ_id = cb.build_circuit([relay.fingerprint, exit.fingerprint]) if not circ_id: log.warning('Could not build circuit involving %s', relay.nickname) # TODO: Return ResultError of some sort Loading Loading @@ -217,7 +229,10 @@ def measure_relay(args, conf, destinations, cb, rl, relay): circ_fps = cb.get_circuit_path(circ_id) our_nick = conf['scanner']['nickname'] cb.close_circuit(circ_id) return ResultSuccess(rtts, bw_results, relay, circ_fps, dest.url, our_nick) return [ ResultSuccess(rtts, bw_results, relay, circ_fps, dest.url, our_nick), ResultSuccess(rtts, bw_results, exit, circ_fps, dest.url, our_nick), ] def dispatch_worker_thread(*a, **kw): Loading sbws/lib/destination.py +18 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,24 @@ class Destination: def url(self): return self._url.geturl() @property def hostname(self): return self._url.hostname @property def port(self): p = self._url.port scheme = self._url.scheme if p is None: if scheme == 'http': p = 80 elif scheme == 'https': p = 443 else: assert None, 'Unreachable. Unknown scheme {}'.format(scheme) assert p is not None return p @staticmethod def from_config(conf_section, default_path): assert 'url' in conf_section Loading sbws/util/stem.py +23 −0 Original line number Diff line number Diff line from stem.control import (Controller, EventType) from stem import (SocketError, InvalidRequest, UnsatisfiableRequest) from stem.connection import IncorrectSocketType from stem.descriptor.router_status_entry import RouterStatusEntryV3 from configparser import ConfigParser from threading import RLock import logging Loading @@ -18,6 +19,7 @@ __all__ = [ 'init_controller_with_config', 'is_controller_okay', 'fp_or_nick_to_relay', 'only_relays_with_bandwidth', ] Loading Loading @@ -139,3 +141,24 @@ def _init_controller_socket(socket): return None # TODO: Allow for auth via more than just CookieAuthentication return c def only_relays_with_bandwidth(controller, relays, min_bw=None, max_bw=None): ''' Given a list of relays, only return those that optionally have above **min_bw** and optionally have below **max_bw**, inclusively. If neither min_bw nor max_bw are given, essentially just returns the input list of relays. ''' assert is_controller_okay(controller) assert min_bw is None or min_bw >= 0 assert max_bw is None or max_bw >= 0 ret = [] for relay in relays: assert isinstance(relay, RouterStatusEntryV3) if min_bw is not None and relay.bandwidth < min_bw: continue if max_bw is not None and relay.bandwidth > max_bw: continue ret.append(relay) return ret Loading
sbws/core/scanner.py +18 −3 Original line number Diff line number Diff line ''' Measure the relays. ''' from ..lib.circuitbuilder import FooCircuitBuilder as CB from ..lib.circuitbuilder import GapsCircuitBuilder as CB from ..lib.resultdump import ResultDump from ..lib.resultdump import ResultSuccess # from ..lib.resultdump import ResultErrorCircuit Loading Loading @@ -188,7 +188,19 @@ def measure_relay(args, conf, destinations, cb, rl, relay): log.warning('Unable to get destination to measure %s %s', relay.nickname, relay.fingerprint[0:8]) return None circ_id = cb.build_circuit([relay.fingerprint]) exits = rl.exits_can_exit_to(dest.hostname, dest.port) exits = [e for e in exits if e.fingerprint != relay.fingerprint] exits = stem_utils.only_relays_with_bandwidth( cb.controller, exits, min_bw=round(relay.bandwidth*1.25), max_bw=max(round(relay.bandwidth*2.00), 100)) if len(exits) < 1: log.warning('No available exits to help measure %s %s', relay.nickname, relay.fingerprint[0:8]) # TODO: Return ResultError of some sort return None exit = random.choice(exits) # exits = stem_utils.only_relays_with_bandwidth() circ_id = cb.build_circuit([relay.fingerprint, exit.fingerprint]) if not circ_id: log.warning('Could not build circuit involving %s', relay.nickname) # TODO: Return ResultError of some sort Loading Loading @@ -217,7 +229,10 @@ def measure_relay(args, conf, destinations, cb, rl, relay): circ_fps = cb.get_circuit_path(circ_id) our_nick = conf['scanner']['nickname'] cb.close_circuit(circ_id) return ResultSuccess(rtts, bw_results, relay, circ_fps, dest.url, our_nick) return [ ResultSuccess(rtts, bw_results, relay, circ_fps, dest.url, our_nick), ResultSuccess(rtts, bw_results, exit, circ_fps, dest.url, our_nick), ] def dispatch_worker_thread(*a, **kw): Loading
sbws/lib/destination.py +18 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,24 @@ class Destination: def url(self): return self._url.geturl() @property def hostname(self): return self._url.hostname @property def port(self): p = self._url.port scheme = self._url.scheme if p is None: if scheme == 'http': p = 80 elif scheme == 'https': p = 443 else: assert None, 'Unreachable. Unknown scheme {}'.format(scheme) assert p is not None return p @staticmethod def from_config(conf_section, default_path): assert 'url' in conf_section Loading
sbws/util/stem.py +23 −0 Original line number Diff line number Diff line from stem.control import (Controller, EventType) from stem import (SocketError, InvalidRequest, UnsatisfiableRequest) from stem.connection import IncorrectSocketType from stem.descriptor.router_status_entry import RouterStatusEntryV3 from configparser import ConfigParser from threading import RLock import logging Loading @@ -18,6 +19,7 @@ __all__ = [ 'init_controller_with_config', 'is_controller_okay', 'fp_or_nick_to_relay', 'only_relays_with_bandwidth', ] Loading Loading @@ -139,3 +141,24 @@ def _init_controller_socket(socket): return None # TODO: Allow for auth via more than just CookieAuthentication return c def only_relays_with_bandwidth(controller, relays, min_bw=None, max_bw=None): ''' Given a list of relays, only return those that optionally have above **min_bw** and optionally have below **max_bw**, inclusively. If neither min_bw nor max_bw are given, essentially just returns the input list of relays. ''' assert is_controller_okay(controller) assert min_bw is None or min_bw >= 0 assert max_bw is None or max_bw >= 0 ret = [] for relay in relays: assert isinstance(relay, RouterStatusEntryV3) if min_bw is not None and relay.bandwidth < min_bw: continue if max_bw is not None and relay.bandwidth > max_bw: continue ret.append(relay) return ret