class TrackerService(object): def __init__(self): """ Initialize the variables of the TrackerServiceMaker and the logger. """ self.endpoint = None self.stopping = False self.overlay = None async def start_tracker(self, listen_port): """ Main method to startup the tracker. """ self.endpoint = UDPEndpoint(listen_port) await self.endpoint.open() self.overlay = EndpointServer(self.endpoint) async def signal_handler(sig): print("Received shut down signal %s" % sig) if not self.stopping: self.stopping = True await self.overlay.unload() self.endpoint.close() get_event_loop().stop() signal.signal(signal.SIGINT, lambda sig, _: ensure_future(signal_handler(sig))) signal.signal(signal.SIGTERM, lambda sig, _: ensure_future(signal_handler(sig))) print("Started tracker")
def start_tracker(self, options): """ Main method to startup the tracker. """ self.endpoint = UDPEndpoint(options["listen_port"]) self.endpoint.open() self.overlay = EndpointServer(self.endpoint) def signal_handler(sig, _): msg("Received shut down signal %s" % sig) if not self.stopping: self.stopping = True def close_ep(): self.endpoint.close().addCallback( lambda *args, **kwargs: reactor.callFromThread(reactor. stop)) self.overlay.unload() close_ep() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) msg("Started tracker")
def test_tunnel_data(self): """ Check if data is correctly exited. """ # Listen in on communication of the target self.public_endpoint = UDPEndpoint(8080) self.public_endpoint.open() ep_listener = MockEndpointListener(self.public_endpoint) # Build a tunnel self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(1) yield self.deliver_messages() # Construct a data packet prefix = '\x00' * 23 data = prefix + ''.join([chr(i) for i in range(256)]) self.public_endpoint.assert_open() # Tunnel the data to the endpoint circuit = self.nodes[0].overlay.circuits.values()[0] self.nodes[0].overlay.send_data( [circuit.sock_addr], circuit.circuit_id, ('localhost', self.public_endpoint.get_address()[1]), ('0.0.0.0', 0), data) # This is not test communication, but actual socket communication, we can't do a smart sleep yield self.sleep() self.assertEqual(len(ep_listener.received_packets), 1) self.assertEqual(ep_listener.received_packets[0][1], data)
class TrackerServiceMaker(object): implements(IServiceMaker, IPlugin) tapname = "tracker" description = "IPv8 tracker twistd plugin" options = Options def __init__(self): """ Initialize the variables of the TrackerServiceMaker and the logger. """ self.endpoint = None self.stopping = False self.overlay = None def start_tracker(self, options): """ Main method to startup the tracker. """ self.endpoint = UDPEndpoint(options["listen_port"]) self.endpoint.open() self.overlay = EndpointServer(self.endpoint) def signal_handler(sig, _): msg("Received shut down signal %s" % sig) if not self.stopping: self.stopping = True def close_ep(): self.endpoint.close().addCallback( lambda *args, **kwargs: reactor.callFromThread(reactor. stop)) self.overlay.unload() close_ep() signal.signal(signal.SIGINT, signal_handler) signal.signal(signal.SIGTERM, signal_handler) msg("Started tracker") def makeService(self, options): """ Construct a tracker service. """ tracker_service = MultiService() tracker_service.setName("IPv8Tracker") reactor.callWhenRunning(self.start_tracker, options) return tracker_service
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) 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'], 'r') 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'], 'w') 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)
async def start_tracker(self, listen_port): """ Main method to startup the tracker. """ self.endpoint = UDPEndpoint(listen_port) await self.endpoint.open() self.overlay = EndpointServer(self.endpoint) async def signal_handler(sig): print("Received shut down signal %s" % sig) if not self.stopping: self.stopping = True await self.overlay.unload() self.endpoint.close() get_event_loop().stop() signal.signal(signal.SIGINT, lambda sig, _: ensure_future(signal_handler(sig))) signal.signal(signal.SIGTERM, lambda sig, _: ensure_future(signal_handler(sig))) print("Started tracker")
async def produce_anonymized_endpoint(self): base_endpoint = UDPEndpoint(port=0, ip=self.configuration['address']) await base_endpoint.open() return TunnelEndpoint(base_endpoint)
class TrackerService: def __init__(self): """ Initialize the variables of the TrackerServiceMaker and the logger. """ self.endpoint = None self.stopping = False self.overlay = None self.site = None def create_endpoint_server(self): return EndpointServer(self.endpoint) async def start_tracker(self, listen_port): """ Main method to startup the tracker. """ self.endpoint = UDPEndpoint(listen_port) await self.endpoint.open() self.overlay = self.create_endpoint_server() async def signal_handler(sig): print("Received shut down signal %s" % sig) if not self.stopping: self.stopping = True await self.overlay.unload() self.endpoint.close() if self.site: await self.site.stop() get_event_loop().stop() signal.signal(signal.SIGINT, lambda sig, _: ensure_future(signal_handler(sig))) signal.signal(signal.SIGTERM, lambda sig, _: ensure_future(signal_handler(sig))) print("Started tracker") async def start_api(self, listen_port, api_key, cert_file): ssl_context = None if cert_file: ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) ssl_context.load_cert_chain(cert_file) async def get_services(_): services = set.union(*self.overlay.network.services_per_peer.values()) \ if self.overlay.network.services_per_peer else set() return Response({ hexlify(service).decode(): [ str(p) for p in self.overlay.network.get_peers_for_service( service) ] for service in services }) app = web.Application(middlewares=[ApiKeyMiddleware(api_key)]) app.add_routes([web.get('/services', get_services)]) runner = web.AppRunner(app, access_log=None) await runner.setup() self.site = web.TCPSite(runner, '0.0.0.0', listen_port, ssl_context=ssl_context) await self.site.start() print("Started API server")
class TestTunnelCommunity(TestBase): def setUp(self): super(TestTunnelCommunity, self).setUp() self.initialize(TunnelCommunity, 2) # An actual UDPEndpoint, if needed by the test (for catching exited data) self.public_endpoint = None def tearDown(self): super(TestTunnelCommunity, self).tearDown() # If an endpoint was used, close it if self.public_endpoint: self.public_endpoint.close() def create_node(self): # Initialize a TunnelCommunity without circuits or exit node functionality settings = TunnelSettings() settings.become_exitnode = False settings.min_circuits = 0 settings.max_circuits = 0 ipv8 = MockIPv8(u"curve25519", TunnelCommunity, settings=settings) # Then kill all automated circuit creation ipv8.overlay.cancel_all_pending_tasks() # Finally, use the proper exitnode and circuit settings for manual creation ipv8.overlay.settings.min_circuits = 1 ipv8.overlay.settings.max_circuits = 1 return ipv8 @twisted_test def test_introduction_as_exit(self): """ Check if introduction requests share the fact that nodes are exit nodes. """ self.nodes[0].overlay.settings.become_exitnode = True self.nodes[1].overlay.settings.become_exitnode = False yield self.introduce_nodes() self.assertIn(self.nodes[0].my_peer.public_key.key_to_bin(), self.nodes[1].overlay.exit_candidates) self.assertNotIn(self.nodes[1].my_peer.public_key.key_to_bin(), self.nodes[0].overlay.exit_candidates) @twisted_test def test_introduction_as_exit_twoway(self): """ Check if two nodes can have each other as exit nodes. """ self.nodes[0].overlay.settings.become_exitnode = True self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.assertIn(self.nodes[0].my_peer.public_key.key_to_bin(), self.nodes[1].overlay.exit_candidates) self.assertIn(self.nodes[1].my_peer.public_key.key_to_bin(), self.nodes[0].overlay.exit_candidates) @twisted_test def test_introduction_as_exit_noway(self): """ Check if two nodes don't advertise themselves as exit node incorrectly. """ self.nodes[0].overlay.settings.become_exitnode = False self.nodes[1].overlay.settings.become_exitnode = False yield self.introduce_nodes() self.assertEqual(len(self.nodes[0].overlay.exit_candidates), 0) self.assertEqual(len(self.nodes[1].overlay.exit_candidates), 0) @twisted_test def test_create_circuit(self): """ Check if 1 hop circuit creation works. """ self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() # Let node 0 build tunnels of 1 hop (settings.min_circuits = settings.max_circuits = 1) # It should use node 1 for this self.nodes[0].overlay.build_tunnels(1) # Let the circuit creation commence yield self.deliver_messages() # Node 0 should now have all of its required 1 hop circuits (1.0/100%) self.assertEqual(self.nodes[0].overlay.tunnels_ready(1), 1.0) # Node 1 has an exit socket open self.assertEqual(len(self.nodes[1].overlay.exit_sockets), 1) @twisted_test def test_create_circuit_no_exit(self): """ Check if 1 hop circuit creation fails without exit nodes. """ self.nodes[1].overlay.settings.become_exitnode = False yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(1) # Attempt circuit creation yield self.deliver_messages() # Node 0 should now have no 1 hop circuits (0.0/0%) self.assertEqual(self.nodes[0].overlay.tunnels_ready(1), 0.0) # Node 1 should not have an exit socket open self.assertEqual(len(self.nodes[1].overlay.exit_sockets), 0) @twisted_test def test_destroy_circuit(self): """ Check if a 1 hop circuit can be destroyed. """ self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(1) yield self.deliver_messages() # Destroy the circuit we just created using a destroy message self.nodes[0].overlay.remove_circuit( self.nodes[0].overlay.circuits.keys()[0], destroy=True) yield self.deliver_messages() # Node 0 should now have no 1 hop circuits (0.0/0%) self.assertEqual(self.nodes[0].overlay.tunnels_ready(1), 0.0) # Node 1 should not have an exit socket open self.assertEqual(len(self.nodes[1].overlay.exit_sockets), 0) @twisted_test def test_destroy_circuit_bad_id(self): """ Check if the correct circuit gets destroyed. """ self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(1) yield self.deliver_messages() # Destroy a circuit which does not exist (circuit_id + 1) # This should not affect other circuits self.nodes[0].overlay.remove_circuit( self.nodes[0].overlay.circuits.keys()[0] + 1, destroy=True) yield self.deliver_messages() # Node 0 should still have all of its required 1 hop circuits (1.0/100%) self.assertEqual(self.nodes[0].overlay.tunnels_ready(1), 1.0) # Node 1 still has an exit socket open self.assertEqual(len(self.nodes[1].overlay.exit_sockets), 1) @twisted_test def test_tunnel_data(self): """ Check if data is correctly exited. """ # Listen in on communication of the target self.public_endpoint = UDPEndpoint(8080) self.public_endpoint.open() ep_listener = MockEndpointListener(self.public_endpoint) # Build a tunnel self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(1) yield self.deliver_messages() # Construct a data packet prefix = '\x00' * 23 data = prefix + ''.join([chr(i) for i in range(256)]) self.public_endpoint.assert_open() # Tunnel the data to the endpoint circuit = self.nodes[0].overlay.circuits.values()[0] self.nodes[0].overlay.send_data( [circuit.sock_addr], circuit.circuit_id, ('localhost', self.public_endpoint.get_address()[1]), ('0.0.0.0', 0), data) # This is not test communication, but actual socket communication, we can't do a smart sleep yield self.sleep() self.assertEqual(len(ep_listener.received_packets), 1) self.assertEqual(ep_listener.received_packets[0][1], data) @twisted_test def test_two_hop_circuit(self): """ Check if a two hop circuit is correctly created. Note that we avoid exit nodes in the relay path, so we explicitly set relay nodes to not be exits. """ self.add_node_to_experiment(self.create_node()) # Build a tunnel self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(2) yield self.deliver_messages() self.assertEqual(self.nodes[0].overlay.tunnels_ready(2), 1.0) @twisted_test def test_three_hop_circuit(self): """ Check if a three hop circuit is correctly created. Note that we avoid exit nodes in the relay path, so we explicitly set relay nodes to not be exits. """ self.add_node_to_experiment(self.create_node()) self.add_node_to_experiment(self.create_node()) # Build a tunnel self.nodes[1].overlay.settings.become_exitnode = True yield self.introduce_nodes() self.nodes[0].overlay.build_tunnels(3) yield self.deliver_messages() self.assertEqual(self.nodes[0].overlay.tunnels_ready(3), 1.0) @twisted_test def test_create_two_circuit(self): """ Check if multiple 1 hop circuit creation works. """ self.add_node_to_experiment(self.create_node()) self.nodes[0].overlay.settings.min_circuits = 2 self.nodes[0].overlay.settings.max_circuits = 2 self.nodes[1].overlay.settings.become_exitnode = True self.nodes[2].overlay.settings.become_exitnode = True yield self.introduce_nodes() # Let node 0 build tunnels of 1 hop (settings.min_circuits = settings.max_circuits = 2) # It should use node 1 and 2 for this self.nodes[0].overlay.build_tunnels(1) # Let the circuit creation commence yield self.deliver_messages() # Node 0 should now have all of its required 1 hop circuits (1.0/100%) self.assertEqual(self.nodes[0].overlay.tunnels_ready(1), 1.0) self.assertEqual(len(self.nodes[0].overlay.circuits), 2) # Two exit sockets are open between node 1 and 2 (NOT evenly spread) self.assertEqual( len(self.nodes[1].overlay.exit_sockets) + len(self.nodes[2].overlay.exit_sockets), 2)