Exemple #1
0
class TunnelHelperService(TaskManager):
    def __init__(self):
        super(TunnelHelperService, self).__init__()
        self._stopping = False
        self.log_circuits = False
        self.session = None
        self.community = None

    def on_circuit_reject(self, reject_time, balance):
        with open(
                os.path.join(self.session.config.get_state_dir(),
                             "circuit_rejects.log"), 'a') as out_file:
            time_millis = int(round(reject_time * 1000))
            out_file.write("%d,%d\n" % (time_millis, balance))

    def tribler_started(self):
        async def signal_handler(sig):
            print("Received shut down signal %s" % sig)
            if not self._stopping:
                self._stopping = True
                await self.session.shutdown()
                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)))

        self.register_task("bootstrap",
                           self.session.tunnel_community.bootstrap,
                           interval=30)

        # Remove all logging handlers
        root_logger = logging.getLogger()
        handlers = root_logger.handlers
        for handler in handlers:
            root_logger.removeHandler(handler)
        logging.getLogger().setLevel(logging.ERROR)

        new_strategies = []
        with self.session.ipv8.overlay_lock:
            for strategy, target_peers in self.session.ipv8.strategies:
                if strategy.overlay == self.session.tunnel_community:
                    new_strategies.append((strategy, -1))
                else:
                    new_strategies.append((strategy, target_peers))
            self.session.ipv8.strategies = new_strategies

    def circuit_removed(self, circuit, additional_info):
        self.session.ipv8.network.remove_by_address(circuit.peer.address)
        if self.log_circuits:
            with open(
                    os.path.join(self.session.config.get_state_dir(),
                                 "circuits.log"), 'a') as out_file:
                duration = time.time() - circuit.creation_time
                out_file.write("%d,%f,%d,%d,%s\n" %
                               (circuit.circuit_id, duration, circuit.bytes_up,
                                circuit.bytes_down, additional_info))

    async def start(self, options):
        # Determine ipv8 port
        ipv8_port = options.ipv8_port
        if ipv8_port == -1 and "HELPER_INDEX" in os.environ and "HELPER_BASE" in os.environ:
            base_port = int(os.environ["HELPER_BASE"])
            ipv8_port = base_port + int(os.environ["HELPER_INDEX"]) * 5

        statedir = Path(
            os.path.join(get_root_state_directory(), "tunnel-%d") % ipv8_port)
        config = TriblerConfig(statedir,
                               config_file=statedir / 'triblerd.conf')
        config.set_tunnel_community_socks5_listen_ports([])
        config.set_tunnel_community_random_slots(options.random_slots)
        config.set_tunnel_community_competing_slots(options.competing_slots)
        config.set_torrent_checking_enabled(False)
        config.set_ipv8_enabled(True)
        config.set_libtorrent_enabled(False)
        config.set_ipv8_port(ipv8_port)
        config.set_ipv8_address(options.ipv8_address)
        config.set_trustchain_enabled(True)
        config.set_market_community_enabled(False)
        config.set_dht_enabled(True)
        config.set_tunnel_community_exitnode_enabled(bool(options.exit))
        config.set_popularity_community_enabled(False)
        config.set_testnet(bool(options.testnet))
        config.set_chant_enabled(False)
        config.set_bootstrap_enabled(False)

        if not options.no_rest_api:
            config.set_http_api_enabled(True)
            api_port = options.restapi
            if "HELPER_INDEX" in os.environ and "HELPER_BASE" in os.environ:
                api_port = int(os.environ["HELPER_BASE"]) + 10000 + int(
                    os.environ["HELPER_INDEX"])
            config.set_http_api_port(api_port)

        if options.ipv8_bootstrap_override is not None:
            config.set_ipv8_bootstrap_override(options.ipv8_bootstrap_override)

        self.session = Session(config)

        self.log_circuits = options.log_circuits
        self.session.notifier.add_observer(NTFY.TUNNEL_REMOVE,
                                           self.circuit_removed)

        await self.session.start()

        if options.log_rejects:
            # We set this after Tribler has started since the tunnel_community won't be available otherwise
            self.session.tunnel_community.reject_callback = self.on_circuit_reject

        # Tunnel helpers store more TrustChain blocks
        self.session.trustchain_community.settings.max_db_blocks = 5000000

        self.tribler_started()

    async def stop(self):
        await self.shutdown_task_manager()
        if self.session:
            return self.session.shutdown()
class TinyTriblerService:
    """Lightweight tribler service, that used for experiments.

    All overlays are disabled by default.
    """

    def __init__(self, config, timeout_in_sec=None, working_dir=Path('/tmp/tribler'),
                 config_path=Path('tribler.conf')):
        self.logger = logging.getLogger(self.__class__.__name__)

        self.session = None
        self.process_checker = None
        self.working_dir = working_dir
        self.config_path = config_path
        self.config = config
        self.timeout_in_sec = timeout_in_sec

    async def on_tribler_started(self):
        """Function will calls after the Tribler session is started

        It is good place to add a custom code.
        """

    async def start_tribler(self):
        self.logger.info(f'Starting tribler instance in directory: {self.working_dir}')

        self._check_already_running()
        await self._start_session()

        if self.timeout_in_sec:
            asyncio.create_task(self._terminate_by_timeout())

        self._enable_graceful_shutdown()
        await self.on_tribler_started()

    @staticmethod
    def create_default_config(working_dir, config_path):
        config = TriblerConfig(working_dir, config_path)

        config.set_tunnel_community_enabled(False)
        config.set_popularity_community_enabled(False)
        config.set_bootstrap_enabled(False)

        config.set_torrent_checking_enabled(True)
        config.set_ipv8_enabled(False)
        config.set_libtorrent_enabled(False)
        config.set_dht_enabled(False)
        config.set_chant_enabled(False)

        return config

    async def _start_session(self):
        self.logger.info(f"Starting Tribler session with config: {self.config}")

        self.session = Session(self.config)
        await self.session.start()

        self.logger.info("Tribler session started")

    def _check_already_running(self):
        self.logger.info(f'Check if we are already running a Tribler instance in: {self.working_dir}')

        self.process_checker = ProcessChecker()
        if self.process_checker.already_running:
            self.logger.error(f"Another Tribler instance is already using directory: {self.working_dir}")
            asyncio.get_running_loop().stop()

    def _enable_graceful_shutdown(self):
        self.logger.info("Enabling graceful shutdown")

        def signal_handler(signum, frame):
            self.logger.info(f"Received shut down signal {signum} in frame {frame}")
            self._graceful_shutdown()

        signal.signal(signal.SIGINT, signal_handler)
        signal.signal(signal.SIGTERM, signal_handler)

    def _graceful_shutdown(self):
        self.logger.info("Shutdown gracefully")

        if not self.session.shutdownstarttime:
            task = asyncio.create_task(self.session.shutdown())
            task.add_done_callback(lambda result: asyncio.get_running_loop().stop())

    async def _terminate_by_timeout(self):
        self.logger.info(f"Scheduling terminating by timeout {self.timeout_in_sec}s from now")
        await asyncio.sleep(self.timeout_in_sec)

        self.logger.info("Terminating by timeout")
        self._graceful_shutdown()