def __init__(self, configuration, endpoint_override=None, enable_statistics=False, extra_communities=None): if endpoint_override: self.endpoint = endpoint_override else: self.endpoint = UDPEndpoint(port=configuration['port'], ip=configuration['address']) self.endpoint.open() if enable_statistics: self.endpoint = StatisticsEndpoint(self, self.endpoint) if any([ overlay.get('initialize', {}).get('anonymize') for overlay in configuration['overlays'] ]): self.endpoint = TunnelEndpoint(self.endpoint) self.network = Network() # Load/generate keys self.keys = {} for key_block in configuration['keys']: if key_block['file'] and isfile(key_block['file']): with open(key_block['file'], 'rb') as f: content = f.read() try: # IPv8 Standardized bin format self.keys[key_block['alias']] = Peer( default_eccrypto.key_from_private_bin(content)) except ValueError: try: # Try old Tribler M2Crypto PEM format content = b64decode(content[31:-30].replace( '\n', '')) peer = Peer(M2CryptoSK(keystring=content)) peer.mid # This will error out if the keystring is not M2Crypto self.keys[key_block['alias']] = peer except: # Try old LibNacl format content = "LibNaCLSK:" + content self.keys[key_block['alias']] = Peer( default_eccrypto.key_from_private_bin( content)) else: self.keys[key_block['alias']] = Peer( default_eccrypto.generate_key(key_block['generation'])) if key_block['file']: with open(key_block['file'], 'wb') as f: f.write( self.keys[key_block['alias']].key.key_to_bin()) # Setup logging logging.basicConfig(**configuration['logger']) self.overlay_lock = RLock() self.strategies = [] self.overlays = [] for overlay in configuration['overlays']: overlay_class = _COMMUNITIES.get(overlay['class'], (extra_communities or {}).get(overlay['class'])) my_peer = self.keys[overlay['key']] overlay_instance = overlay_class(my_peer, self.endpoint, self.network, **overlay['initialize']) self.overlays.append(overlay_instance) for walker in overlay['walkers']: strategy_class = _WALKERS.get( walker['strategy'], overlay_instance.get_available_strategies().get( walker['strategy'])) args = walker['init'] target_peers = walker['peers'] self.strategies.append( (strategy_class(overlay_instance, **args), target_peers)) for config in overlay['on_start']: reactor.callWhenRunning( getattr(overlay_instance, config[0]), *config[1:]) self.state_machine_lc = LoopingCall(self.on_tick) self.state_machine_lc.start(configuration['walker_interval'], False)
class IPv8(object): def __init__(self, configuration, endpoint_override=None, enable_statistics=False, extra_communities=None): super(IPv8, self).__init__() self.configuration = configuration if endpoint_override: self.endpoint = endpoint_override else: self.endpoint = DispatcherEndpoint(["UDPIPv4"], UDPIPv4={ 'port': configuration['port'], 'ip': configuration['address'] }) if enable_statistics: self.endpoint = StatisticsEndpoint(self.endpoint) if any([ overlay.get('initialize', {}).get('anonymize') for overlay in configuration['overlays'] ]): self.endpoint = TunnelEndpoint(self.endpoint) self.network = Network() # Load/generate keys self.keys = {} for key_block in configuration['keys']: if key_block['file'] and isfile(key_block['file']): with open(key_block['file'], 'rb') as f: content = f.read() try: # IPv8 Standardized bin format self.keys[key_block['alias']] = Peer( default_eccrypto.key_from_private_bin(content)) except ValueError: try: # Try old Tribler M2Crypto PEM format content = b64decode(content[31:-30].replace( '\n', '')) peer = Peer(M2CryptoSK(keystring=content)) peer.mid # This will error out if the keystring is not M2Crypto self.keys[key_block['alias']] = peer except Exception: # Try old LibNacl format content = "LibNaCLSK:" + content self.keys[key_block['alias']] = Peer( default_eccrypto.key_from_private_bin( content)) else: self.keys[key_block['alias']] = Peer( default_eccrypto.generate_key(key_block['generation'])) if key_block['file']: with open(key_block['file'], 'wb') as f: f.write( self.keys[key_block['alias']].key.key_to_bin()) # Setup logging logging.basicConfig(**configuration['logger']) self.overlay_lock = RLock() self.strategies = [] self.overlays = [] self.on_start = [] for overlay in configuration['overlays']: overlay_class = _COMMUNITIES.get(overlay['class'], (extra_communities or {}).get(overlay['class'])) my_peer = self.keys[overlay['key']] overlay_instance = overlay_class(my_peer, self.endpoint, self.network, **overlay['initialize']) self.overlays.append(overlay_instance) for walker in overlay['walkers']: strategy_class = _WALKERS.get( walker['strategy'], overlay_instance.get_available_strategies().get( walker['strategy'])) args = walker['init'] target_peers = walker['peers'] self.strategies.append( (strategy_class(overlay_instance, **args), target_peers)) for config in overlay['on_start']: self.on_start.append((getattr(overlay_instance, config[0]), config[1:])) for bootstrapper in overlay['bootstrappers']: bootstrapper_class = _BOOTSTRAPPERS.get( bootstrapper['class']) if bootstrapper_class: overlay_instance.bootstrappers.append( bootstrapper_class(**bootstrapper['init'])) self.walk_interval = configuration['walker_interval'] self.state_machine_task = None async def start(self): await self.endpoint.open() await gather(*(ensure_future(maybe_coroutine(func, *args)) for func, args in self.on_start)) async def ticker(): while True: await self.on_tick() await sleep(0.0) self.state_machine_task = ensure_future(ticker()) async def on_tick(self): if self.endpoint.is_open(): with self.overlay_lock: smooth = self.walk_interval // len( self.strategies) if self.strategies else 0 ticker = len(self.strategies) for strategy, target_peers in self.strategies: peer_count = len(strategy.overlay.get_peers()) start_time = time.time() if (target_peers == -1) or (peer_count < target_peers): # We wrap the take_step into a general except as it is prone to programmer error. try: strategy.take_step() except Exception: logging.error( "Exception occurred while trying to walk!\n" + ''.join(format_exception(*sys.exc_info()))) ticker -= 1 if ticker else 0 sleep_time = smooth - (time.time() - start_time) if ticker and sleep_time > 0.01: await sleep(sleep_time) if self.state_machine_task.done(): # By awaiting, we might have been stopped. # In that case, exit out of the loop. break else: await sleep(self.walk_interval) def add_strategy(self, overlay, strategy, target_peers): with self.overlay_lock: if overlay not in self.overlays: self.overlays.append(overlay) self.strategies.append((strategy, target_peers)) def unload_overlay(self, instance): with self.overlay_lock: self.overlays = [ overlay for overlay in self.overlays if overlay != instance ] self.strategies = [(strategy, target_peers) for (strategy, target_peers) in self.strategies if strategy.overlay != instance] return maybe_coroutine(instance.unload) def get_overlay(self, overlay_cls): return next(self.get_overlays(overlay_cls), None) def get_overlays(self, overlay_cls): return (o for o in self.overlays if isinstance(o, overlay_cls)) async def produce_anonymized_endpoint(self): base_endpoint = UDPEndpoint(port=0, ip=self.configuration['address']) await base_endpoint.open() return TunnelEndpoint(base_endpoint) async def stop(self, stop_loop=True): if self.state_machine_task: self.state_machine_task.cancel() with suppress(CancelledError): await self.state_machine_task with self.overlay_lock: unload_list = [ self.unload_overlay(overlay) for overlay in self.overlays[:] ] await gather(*unload_list) self.endpoint.close() if stop_loop: loop = get_event_loop() loop.call_later(0, loop.stop)
class IPv8(object): def __init__(self, configuration, endpoint_override=None, enable_statistics=False, extra_communities=None): if endpoint_override: self.endpoint = endpoint_override else: self.endpoint = UDPEndpoint(port=configuration['port'], ip=configuration['address']) self.endpoint.open() if enable_statistics: self.endpoint = StatisticsEndpoint(self, self.endpoint) if any([ overlay.get('initialize', {}).get('anonymize') for overlay in configuration['overlays'] ]): self.endpoint = TunnelEndpoint(self.endpoint) self.network = Network() # Load/generate keys self.keys = {} for key_block in configuration['keys']: if key_block['file'] and isfile(key_block['file']): with open(key_block['file'], 'rb') as f: content = f.read() try: # IPv8 Standardized bin format self.keys[key_block['alias']] = Peer( default_eccrypto.key_from_private_bin(content)) except ValueError: try: # Try old Tribler M2Crypto PEM format content = b64decode(content[31:-30].replace( '\n', '')) peer = Peer(M2CryptoSK(keystring=content)) peer.mid # This will error out if the keystring is not M2Crypto self.keys[key_block['alias']] = peer except: # Try old LibNacl format content = "LibNaCLSK:" + content self.keys[key_block['alias']] = Peer( default_eccrypto.key_from_private_bin( content)) else: self.keys[key_block['alias']] = Peer( default_eccrypto.generate_key(key_block['generation'])) if key_block['file']: with open(key_block['file'], 'wb') as f: f.write( self.keys[key_block['alias']].key.key_to_bin()) # Setup logging logging.basicConfig(**configuration['logger']) self.overlay_lock = RLock() self.strategies = [] self.overlays = [] for overlay in configuration['overlays']: overlay_class = _COMMUNITIES.get(overlay['class'], (extra_communities or {}).get(overlay['class'])) my_peer = self.keys[overlay['key']] overlay_instance = overlay_class(my_peer, self.endpoint, self.network, **overlay['initialize']) self.overlays.append(overlay_instance) for walker in overlay['walkers']: strategy_class = _WALKERS.get( walker['strategy'], overlay_instance.get_available_strategies().get( walker['strategy'])) args = walker['init'] target_peers = walker['peers'] self.strategies.append( (strategy_class(overlay_instance, **args), target_peers)) for config in overlay['on_start']: reactor.callWhenRunning( getattr(overlay_instance, config[0]), *config[1:]) self.state_machine_lc = LoopingCall(self.on_tick) self.state_machine_lc.start(configuration['walker_interval'], False) @inlineCallbacks def on_tick(self): if self.endpoint.is_open(): with self.overlay_lock: smooth = self.state_machine_lc.interval / len( self.strategies) if self.strategies else 0 ticker = len(self.strategies) for strategy, target_peers in self.strategies: peer_count = len(strategy.overlay.get_peers()) start_time = time.time() if (target_peers == -1) or (peer_count < target_peers): # We wrap the take_step into a general except as it is prone to programmer error. try: strategy.take_step() except: logging.error( "Exception occurred while trying to walk!\n" + ''.join(format_exception(*sys.exc_info()))) ticker -= 1 if ticker else 0 sleep_time = smooth - (time.time() - start_time) if ticker and sleep_time > 0.01: yield deferLater(reactor, sleep_time, lambda: None) if not self.state_machine_lc.running: # By yielding, we might have been stopped. # In that case, exit out of the loop. break def unload_overlay(self, instance): with self.overlay_lock: self.overlays = [ overlay for overlay in self.overlays if overlay != instance ] self.strategies = [(strategy, target_peers) for (strategy, target_peers) in self.strategies if strategy.overlay != instance] return maybeDeferred(instance.unload) @inlineCallbacks def stop(self, stop_reactor=True): self.state_machine_lc.stop() with self.overlay_lock: unload_list = [ self.unload_overlay(overlay) for overlay in self.overlays[:] ] yield DeferredList(unload_list) yield self.endpoint.close() if stop_reactor: reactor.callFromThread(reactor.stop)
async def produce_anonymized_endpoint(self): base_endpoint = UDPEndpoint(port=0, ip=self.configuration['address']) await base_endpoint.open() return TunnelEndpoint(base_endpoint)