Exemple #1
0
    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.logger,
                                                     self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config,
                                              openssl_context,
                                              self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)
Exemple #2
0
    def __init__(self):
        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.logger = logger
        config_path = os.path.join(module_data_path, "tls_relay.json")
        self.config = Config(config_path)

        self.ca_cert_fn = os.path.join(module_data_path, "tls_relay_CA.crt")
        self.openssl_context = SSLContext(logger)
        if os.path.isfile(self.ca_cert_fn):
            self.openssl_context.set_ca(self.ca_cert_fn)

        host_fn = os.path.join(module_data_path, "tls_host.json")
        self.host_manager = host_manager.HostManager(host_fn)

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = IpSimpleSource(self.config.ip_source_ips)

        default_ip_list_fn = ""
        ip_list_fn = os.path.join(module_data_path, "tls_relay_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)
        for ip in self.config.ip_source_ips:
            self.ip_manager.add_ip(ip, 100)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        self.account = ""
        self.password = ""

        threading.Thread(target=self.debug_data_clearup_thread).start()
Exemple #3
0
    def __init__(self):
        self.running = True

        self.logger = logger
        self.config = config

        self.host_manager = host_manager.HostManager(self.config, logger)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.openssl_context = SSLContext(
            logger,
            ca_certs=ca_certs,
            support_http2=config.support_http2,
            cipher_suites=[
                'ALL', "!RC4-SHA", "!ECDHE-RSA-RC4-SHA",
                "!ECDHE-RSA-AES128-GCM-SHA256", "!AES128-GCM-SHA256",
                "!ECDHE-RSA-AES128-SHA", "!AES128-SHA"
            ])
        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager.appid_manager = self.appid_manager

        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        self.ipv4_source = Ipv4RangeSource(
            logger, self.config, os.path.join(current_path, "ip_range.txt"),
            os.path.join(module_data_path, "ip_range.txt"))
        self.ipv6_source = Ipv6PoolSource(
            logger, self.config, os.path.join(current_path, "ipv6_list.txt"))
        self.ip_source = IpCombineSource(logger, self.config, self.ipv4_source,
                                         self.ipv6_source)
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    self.ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    None,
                                    os.path.join(module_data_path,
                                                 "good_ip.txt"),
                                    scan_ip_log=None)

        self.appid_manager.check_api = self.check_ip.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)

        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)
Exemple #4
0
    def __init__(self):
        self.running = True

        self.logger = logger
        config_path = os.path.join(module_data_path, "tls_relay.json")
        self.config = Config(config_path)

        self.ca_cert_fn = os.path.join(module_data_path, "tls_relay_CA.crt")
        self.openssl_context = SSLContext(logger)
        if os.path.isfile(self.ca_cert_fn):
            self.openssl_context.set_ca(self.ca_cert_fn)

        if not os.path.isdir(module_data_path):
            os.mkdir(module_data_path)

        if not os.path.isdir(tls_certs_path):
            os.mkdir(tls_certs_path)

        host_fn = os.path.join(module_data_path, "tls_host.json")
        self.host_manager = host_manager.HostManager(host_fn)

        self.connect_creator = connect_creator.ConnectCreator(
            logger, self.config, self.openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = IpSimpleSource(self.config.ip_source_ips)

        default_ip_list_fn = ""
        ip_list_fn = os.path.join(module_data_path, "tls_relay_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)
        for ip in self.config.ip_source_ips:
            self.ip_manager.add_ip(ip, 100)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

        self.account = ""
        self.password = ""
Exemple #5
0
    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config,
                                              openssl_context,
                                              self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        threading.Thread(target=self.debug_data_clearup_thread).start()
Exemple #6
0
    def get_dispatcher(self, host):
        if host not in self.dispatchs:
            http_dispatcher = HttpsDispatcher(logger, config, front.ip_manager,
                                              self.connect_manager)
            self.dispatchs[host] = http_dispatcher

        return self.dispatchs[host]
Exemple #7
0
    def start(self):
        self.running = True

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.openssl_context = SSLContext(
            logger,
            ca_certs=ca_certs,
            support_http2=config.support_http2,
            cipher_suites=[
                'ALL', "!RC4-SHA", "!ECDHE-RSA-RC4-SHA",
                "!ECDHE-RSA-AES128-GCM-SHA256", "!AES128-GCM-SHA256",
                "!ECDHE-RSA-AES128-SHA", "!AES128-SHA"
            ])

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager = host_manager.HostManager(self.config, logger)
        self.host_manager.appid_manager = self.appid_manager

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)

        #self.ip_checker = CheckIp(logger, self.config, self.connect_creator)

        self.ipv6_source = Ipv6PoolSource(logger, self.config, "ipv6_list.txt")
        self.ip_source = self.ipv6_source
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    self.ip_source,
                                    check_local_network,
                                    None,
                                    os.path.join(data_path, "good_ip.txt"),
                                    scan_ip_log=None)

        #self.appid_manager.check_api = self.ip_checker.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)

        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)
Exemple #8
0
 def init_host_dispatcher(self, host):
     if host not in self.dispatchs:
         http_dispatcher = HttpsDispatcher(
             logger,
             self.config,
             self.ip_manager,
             self.connect_manager,
             http2worker=CloudflareHttp2Worker)
         self.dispatchs[host] = http_dispatcher
Exemple #9
0
    def start(self):
        self.running = True

        ca_certs = 'cacert.pem'
        self.openssl_context = SSLContext(
            logger,
            ca_certs=ca_certs,
            support_http2=config.support_http2,
            protocol="TLSv1_2"
            #cipher_suites=[b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA", b"!ECDHE-RSA-AES128-GCM-SHA256",
            #               b"!AES128-GCM-SHA256", b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"]
        )

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager = host_manager.HostManager(self.config, logger)
        self.host_manager.appid_manager = self.appid_manager

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)

        # self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator)

        self.ip_manager = IpManager(logger,
                                    self.config,
                                    check_local_network,
                                    None,
                                    'good_ip.txt',
                                    scan_ip_log=None)

        # self.appid_manager.check_api = self.ip_checker.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)

        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)
Exemple #10
0
    def __init__(self):
        self.running = True

        self.logger = logger
        self.config = config

        self.host_manager = host_manager.HostManager(self.config, logger)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.openssl_context = SSLContext(
            logger, ca_certs=ca_certs, support_http2=config.support_http2,
            cipher_suites=['ALL', "!RC4-SHA","!ECDHE-RSA-RC4-SHA", "!ECDHE-RSA-AES128-GCM-SHA256",
                           "!AES128-GCM-SHA256", "!ECDHE-RSA-AES128-SHA", "!AES128-SHA"]
        )
        self.connect_creator = ConnectCreator(
            logger, self.config, self.openssl_context, self.host_manager)

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager.appid_manager = self.appid_manager

        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        self.ipv4_source = Ipv4RangeSource(
            logger, self.config,
            os.path.join(current_path, "ip_range.txt"),
            os.path.join(module_data_path, "ip_range.txt")
        )
        self.ipv6_source = Ipv6PoolSource(
            logger, self.config,
            os.path.join(current_path, "ipv6_list.txt")
        )
        self.ip_source = IpCombineSource(
            logger, self.config,
            self.ipv4_source, self.ipv6_source
        )
        self.ip_manager = IpManager(
            logger, self.config, self.ip_source, check_local_network,
            self.check_ip.check_ip,
            None,
            os.path.join(module_data_path, "good_ip.txt"),
            scan_ip_log=None)

        self.appid_manager.check_api = self.check_ip.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(
            logger, self.config, self.connect_creator, self.ip_manager, check_local_network)

        self.http_dispatcher = HttpsDispatcher(
            logger, self.config, self.ip_manager, self.connect_manager
        )
Exemple #11
0
    def get_dispatcher(self, host=None):
        if host is None:
            host = self.last_host
        else:
            self.last_host = host

        if host not in self.dispatchs:
            http_dispatcher = HttpsDispatcher(
                logger, self.config, self.ip_manager, self.connect_manager
            )
            self.dispatchs[host] = http_dispatcher

        dispatcher = self.dispatchs[host]
        return dispatcher
Exemple #12
0
    def __init__(self):
        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.logger = logger
        config_path = os.path.join(module_data_path, "tls_relay.json")
        self.config = Config(config_path)

        self.ca_cert_fn = os.path.join(module_data_path, "tls_relay_CA.crt")
        self.openssl_context = SSLContext(logger)
        if os.path.isfile(self.ca_cert_fn):
            self.openssl_context.set_ca(self.ca_cert_fn)

        host_fn = os.path.join(module_data_path, "tls_host.json")
        self.host_manager = host_manager.HostManager(host_fn)

        self.connect_creator = ConnectCreator(logger, self.config, self.openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = IpSimpleSource(self.config.ip_source_ips)

        default_ip_list_fn = ""
        ip_list_fn = os.path.join(module_data_path, "tls_relay_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network, self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)
        for ip in self.config.ip_source_ips:
            self.ip_manager.add_ip(ip, 100)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        self.account = ""
        self.password = ""

        threading.Thread(target=self.debug_data_clearup_thread).start()
Exemple #13
0
    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.logger, self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network,
                    self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)
Exemple #14
0
    def get_dispatcher(self, host=None):
        if not host:
            host = self.last_host
        else:
            self.last_host = host

        if host not in self.dispatchs:
            if host in ["center.xx-net.org", "dns.xx-net.org"]:
                config = self.light_config
            else:
                config = self.config

            http_dispatcher = HttpsDispatcher(
                logger,
                config,
                self.ip_manager,
                self.connect_manager,
                http2worker=CloudflareHttp2Worker)
            self.dispatchs[host] = http_dispatcher

        dispatcher = self.dispatchs[host]
        return dispatcher
Exemple #15
0
    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network,
                    self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)

        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        threading.Thread(target=self.debug_data_clearup_thread).start()
Exemple #16
0
class Front(object):
    name = "tls_relay_front"

    def __init__(self):
        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.logger = logger
        config_path = os.path.join(module_data_path, "tls_relay.json")
        self.config = Config(config_path)

        self.ca_cert_fn = os.path.join(module_data_path, "tls_relay_CA.crt")
        self.openssl_context = SSLContext(logger)
        if os.path.isfile(self.ca_cert_fn):
            self.openssl_context.set_ca(self.ca_cert_fn)

        host_fn = os.path.join(module_data_path, "tls_host.json")
        self.host_manager = host_manager.HostManager(host_fn)

        self.connect_creator = ConnectCreator(logger, self.config, self.openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = IpSimpleSource(self.config.ip_source_ips)

        default_ip_list_fn = ""
        ip_list_fn = os.path.join(module_data_path, "tls_relay_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network, self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)
        for ip in self.config.ip_source_ips:
            self.ip_manager.add_ip(ip, 100)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        self.account = ""
        self.password = ""

        threading.Thread(target=self.debug_data_clearup_thread).start()

    def set_x_tunnel_account(self, account, password):
        self.account = account
        self.password = password

    def log_debug_data(self, rtt, sent, received):
        now = time.time()

        self.rtts.append((rtt, now))

        with self.traffics_lock:
            self.traffics.append((sent, received, now))
            self.recent_sent += sent
            self.recent_received += received
            self.total_sent += sent
            self.total_received += received

    def get_rtt(self):
        now = time.time()

        while len(self.rtts) > 1:
            with self.rtts_lock:
                rtt, log_time = rtt_log = max(self.rtts)

                if now - log_time > 5:
                    self.rtts.remove(rtt_log)
                    continue

            return rtt

        return self.rtts[0][0]

    def debug_data_clearup_thread(self):
        while self.running:
            now = time.time()

            with self.rtts_lock:
                if len(self.rtts) > 1 and now - self.rtts[0][-1] > 5:
                    self.rtts.popleft()

            with self.traffics_lock:
                if self.traffics and now - self.traffics[0][-1] > 60:
                    sent, received, _ = self.traffics.popleft()
                    self.recent_sent -= sent
                    self.recent_received -= received

            time.sleep(1)

    def worker_num(self):
        return len(self.http_dispatcher.workers)

    def set_ips(self, ips):
        if not ips:
            return

        host_info = {}
        ca_certs = []
        ipss = []
        for ip in ips:
            dat = ips[ip]
            ca_cert = dat["ca_crt"]
            sni = dat["sni"]

            host_info[ip] = {"sni":sni, "ca_crt":ca_cert}
            if ca_cert not in ca_certs:
                ca_certs.append(ca_cert)
            ipss.append(ip)

        self.ip_manager.update_ips(ipss)
        self.ip_manager.save(True)
        self.host_manager.set_host(host_info)

        ca_content = "\n\n".join(ca_certs)
        with open(self.ca_cert_fn, "w") as fd:
            fd.write(ca_content)
        self.openssl_context.set_ca(self.ca_cert_fn)
        self.logger.info("set_ips:%s", ",".join(ipss))

    def get_score(self, host=None):
        now = time.time()
        if now - self.last_fail_time < self.config.front_continue_fail_block and \
                self.continue_fail_num > self.config.front_continue_fail_num:
            return None

        worker = self.http_dispatcher.get_worker(nowait=True)
        if not worker:
            return None

        return worker.get_score()

    def request(self, method, host, path="/", headers={}, data="", timeout=120):
        headers = dict(headers)
        headers["XX-Account"] = self.account

        response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)
        if not response:
            logger.warn("req %s get response timeout", path)
            return "", 602, {}

        status = response.status
        if status not in [200, 405]:
            # logger.warn("front request %s %s%s fail, status:%d", method, host, path, status)
            self.fail_num += 1
            self.continue_fail_num += 1
            self.last_fail_time = time.time()
        else:
            self.success_num += 1
            self.continue_fail_num = 0

        content = response.task.read_all()
        if status == 200:
            logger.debug("%s %s%s status:%d trace:%s", method, host, path, status,
                       response.task.get_trace())
        else:
            logger.warn("%s %s%s status:%d trace:%s", method, host, path, status,
                       response.task.get_trace())
        return content, status, response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #17
0
class Front(object):
    name = "gae_front"

    def __init__(self):
        self.logger = logger
        self.config = config

    def start(self):
        self.running = True

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.openssl_context = SSLContext(
            logger,
            ca_certs=ca_certs,
            support_http2=config.support_http2,
            cipher_suites=[
                b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA",
                b"!ECDHE-RSA-AES128-GCM-SHA256", b"!AES128-GCM-SHA256",
                b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"
            ])

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager = host_manager.HostManager(self.config, logger)
        self.host_manager.appid_manager = self.appid_manager

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)

        self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator)

        self.ipv4_source = Ipv4RangeSource(
            logger, self.config, os.path.join(current_path, "ip_range.txt"),
            os.path.join(module_data_path, "ip_range.txt"))
        self.ipv6_source = Ipv6PoolSource(
            logger, self.config, os.path.join(current_path, "ipv6_list.txt"))
        self.ip_source = IpCombineSource(logger, self.config, self.ipv4_source,
                                         self.ipv6_source)
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    self.ip_source,
                                    check_local_network,
                                    self.check_ip,
                                    None,
                                    os.path.join(module_data_path,
                                                 "good_ip.txt"),
                                    scan_ip_log=None)

        self.appid_manager.check_api = self.ip_checker.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)

        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

    def check_ip(self, ip):
        sni = self.host_manager.sni_manager.get()
        host = self.config.check_ip_host
        return self.ip_checker.check_ip(ip, sni=sni, host=host)

    def get_dispatcher(self):
        return self.http_dispatcher

    def request(self,
                method,
                host,
                path=b"/",
                headers={},
                data="",
                timeout=120):
        response = self.http_dispatcher.request(method,
                                                host,
                                                path,
                                                dict(headers),
                                                data,
                                                timeout=timeout)

        return response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #18
0
class Front(object):
    name = "heroku_front"

    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.logger, self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network,
                    self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)

    def get_dispatcher(self, host=None):
        return self.http_dispatcher

    def set_ips(self, ips):
        self.ip_manager.set_ips(ips)

    def _request(self, method, host, path="/", headers={}, data="", timeout=40):
        try:
            response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)
            if not response:
                return "", 500, {}

            status = response.status
            if status != 200:
                self.logger.warn("front request %s %s%s fail, status:%d", method, host, path, status)

            content = response.task.read_all()
            # self.logger.debug("%s %s%s trace:%s", method, response.ssl_sock.host, path, response.task.get_trace())
            return content, status, response
        except Exception as e:
            self.logger.exception("front request %s %s%s fail:%s", method, host, path, e)
            return "", 500, {}

    def request(self, method, host, schema="http", path="/", headers={}, data="", timeout=40):
        schema = "http"
        # force schema to http, avoid cert fail on heroku curl.
        # and all x-server provide ipv4 access

        url = schema + "://" + host + path
        payloads = ['%s %s HTTP/1.1\r\n' % (method, url)]
        for k in headers:
            v = headers[k]
            payloads.append('%s: %s\r\n' % (k, v))
        head_payload = "".join(payloads)

        request_body = '%s%s%s%s' % \
                       ((struct.pack('!H', len(head_payload)),  head_payload,
                         struct.pack('!I', len(data)), data))
        request_headers = {'Content-Length': len(data), 'Content-Type': 'application/octet-stream'}

        heroku_host = ""
        content, status, response = self._request(
                                            "POST", heroku_host, "/2/",
                                            request_headers, request_body, timeout)

        # self.logger.info('%s "PHP %s %s %s" %s %s', handler.address_string(), handler.command, url, handler.protocol_version, response.status, response.getheader('Content-Length', '-'))
        # self.logger.debug("status:%d", status)

        if hasattr(response, "task"):
            self.logger.debug("%s %s%s status:%d trace:%s", method, host, path, status, response.task.get_trace())
        else:
            self.logger.debug("%s %s%s status:%d", method, host, path, status)

        if status == 404:
            heroku_host = response.ssl_sock.host
            self.logger.warn("heroku appid:%s fail", heroku_host)
            try:
                self.host_manager.remove(heroku_host)
            except:
                pass
            return "", 501, {}

        if not content:
            return "", 501, {}

        try:
            res = simple_http_client.TxtResponse(content)
        except Exception as e:
            self.logger.warn("decode %s response except:%r", content, e)
            return "", 501, {}

        res.worker = response.worker
        res.task = response.task
        return res.body, res.status, res

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #19
0
class Front(object):
    name = "heroku_front"

    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network,
                    self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)

        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        threading.Thread(target=self.debug_data_clearup_thread).start()

    def log_debug_data(self, rtt, sent, received):
        now = time.time()

        self.rtts.append((rtt, now))

        with self.traffics_lock:
            self.traffics.append((sent, received, now))
            self.recent_sent += sent
            self.recent_received += received
            self.total_sent += sent
            self.total_received += received

    def get_rtt(self):
        now = time.time()

        while len(self.rtts) > 1:
            with self.rtts_lock:
                rtt, log_time = rtt_log = max(self.rtts)

                if now - log_time > 5:
                    self.rtts.remove(rtt_log)
                    continue

            return rtt

        return self.rtts[0][0]

    def debug_data_clearup_thread(self):
        while self.running:
            now = time.time()

            with self.rtts_lock:
                if len(self.rtts) > 1 and now - self.rtts[0][-1] > 5:
                    self.rtts.popleft()

            with self.traffics_lock:
                if self.traffics and now - self.traffics[0][-1] > 60:
                    sent, received, _ = self.traffics.popleft()
                    self.recent_sent -= sent
                    self.recent_received -= received

            time.sleep(1)

    def worker_num(self):
        return len(self.http_dispatcher.workers)

    def set_ips(self, ips):
        self.ip_manager.set_ips(ips)

    def get_score(self, host=None):
        if not self.host_manager.appids:
            return None

        now = time.time()
        if now - self.last_fail_time < self.config.front_continue_fail_block and \
                self.continue_fail_num > self.config.front_continue_fail_num:
            return None

        worker = self.http_dispatcher.get_worker(nowait=True)
        if not worker:
            return None

        return worker.get_score()

    def _request(self, method, host, path="/", headers={}, data="", timeout=40):
        try:
            response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)
            if not response:
                return "", 500, {}

            status = response.status
            if status != 200:
                xlog.warn("front request %s %s%s fail, status:%d", method, host, path, status)

            content = response.task.read_all()
            # xlog.debug("%s %s%s trace:%s", method, response.ssl_sock.host, path, response.task.get_trace())
            return content, status, response
        except Exception as e:
            xlog.exception("front request %s %s%s fail:%r", method, host, path, e)
            return "", 500, {}

    def request(self, method, host, schema="http", path="/", headers={}, data="", timeout=40):
        # change top domain to xx-net.net
        # this domain bypass the cloudflare front for ipv4
        #p = host.find(".")
        #host_sub = host[:p]
        #host = host_sub + ".xx-net.net"

        schema = "http"
        # force schema to http, avoid cert fail on heroku curl.
        # and all x-server provide ipv4 access

        url = schema + "://" + host + path
        payloads = ['%s %s HTTP/1.1\r\n' % (method, url)]
        for k in headers:
            v = headers[k]
            payloads.append('%s: %s\r\n' % (k, v))
        head_payload = "".join(payloads)

        request_body = '%s%s%s%s' % \
                       ((struct.pack('!H', len(head_payload)),  head_payload,
                         struct.pack('!I', len(data)), data))
        request_headers = {'Content-Length': len(data), 'Content-Type': 'application/octet-stream'}

        heroku_host = ""
        content, status, response = self._request(
                                            "POST", heroku_host, "/2/",
                                            request_headers, request_body, timeout)

        # xlog.info('%s "PHP %s %s %s" %s %s', handler.address_string(), handler.command, url, handler.protocol_version, response.status, response.getheader('Content-Length', '-'))
        # xlog.debug("status:%d", status)
        if status == 200:
            xlog.debug("%s %s%s trace:%s", method, host, path, response.task.get_trace())
            self.last_success_time = time.time()
            self.continue_fail_num = 0
            self.success_num += 1
        else:
            if status == 404:
                heroku_host = response.ssl_sock.host
                xlog.warn("heroku:%s fail", heroku_host)
                try:
                    self.host_manager.remove(heroku_host)
                except:
                    pass

            self.last_fail_time = time.time()
            self.continue_fail_num += 1
            self.fail_num += 1

        try:
            res = simple_http_client.TxtResponse(content)
        except:
            return "", 501, {}

        res.worker = response.worker
        res.task = response.task
        return res.body, res.status, res

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #20
0
class Front(object):
    name = "gae_front"

    def __init__(self):
        self.running = True

        self.logger = logger
        self.config = config

        self.host_manager = host_manager.HostManager(self.config, logger)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.openssl_context = SSLContext(
            logger, ca_certs=ca_certs, support_http2=config.support_http2,
            cipher_suites=['ALL', "!RC4-SHA","!ECDHE-RSA-RC4-SHA", "!ECDHE-RSA-AES128-GCM-SHA256",
                           "!AES128-GCM-SHA256", "!ECDHE-RSA-AES128-SHA", "!AES128-SHA"]
        )
        self.connect_creator = ConnectCreator(
            logger, self.config, self.openssl_context, self.host_manager)

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager.appid_manager = self.appid_manager

        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        self.ipv4_source = Ipv4RangeSource(
            logger, self.config,
            os.path.join(current_path, "ip_range.txt"),
            os.path.join(module_data_path, "ip_range.txt")
        )
        self.ipv6_source = Ipv6PoolSource(
            logger, self.config,
            os.path.join(current_path, "ipv6_list.txt")
        )
        self.ip_source = IpCombineSource(
            logger, self.config,
            self.ipv4_source, self.ipv6_source
        )
        self.ip_manager = IpManager(
            logger, self.config, self.ip_source, check_local_network,
            self.check_ip.check_ip,
            None,
            os.path.join(module_data_path, "good_ip.txt"),
            scan_ip_log=None)

        self.appid_manager.check_api = self.check_ip.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(
            logger, self.config, self.connect_creator, self.ip_manager, check_local_network)

        self.http_dispatcher = HttpsDispatcher(
            logger, self.config, self.ip_manager, self.connect_manager
        )

    def get_dispatcher(self):
        return self.http_dispatcher

    def request(self, method, host, path="/", headers={}, data="", timeout=120):
        response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)

        return response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #21
0
class Front(object):
    name = "heroku_front"

    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.logger, self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config, openssl_context, self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger, self.config, ip_source, check_local_network,
                    self.check_ip.check_ip,
                 default_ip_list_fn, ip_list_fn, scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config, self.connect_creator, self.ip_manager, check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config, self.ip_manager, self.connect_manager)

    def get_dispatcher(self, host=None):
        if len(self.host_manager.appids) == 0:
            return None

        return self.http_dispatcher

    def set_ips(self, ips):
        self.ip_manager.set_ips(ips)

    def _request(self, method, host, path="/", headers={}, data="", timeout=40):
        try:
            response = self.http_dispatcher.request(method, host, path, dict(headers), data, timeout=timeout)
            if not response:
                return "", 500, {}

            status = response.status
            if status != 200:
                self.logger.warn("front request %s %s%s fail, status:%d", method, host, path, status)

            content = response.task.read_all()
            # self.logger.debug("%s %s%s trace:%s", method, response.ssl_sock.host, path, response.task.get_trace())
            return content, status, response
        except Exception as e:
            self.logger.exception("front request %s %s%s fail:%s", method, host, path, e)
            return "", 500, {}

    def request(self, method, host, schema="http", path="/", headers={}, data="", timeout=40):
        schema = "http"
        # force schema to http, avoid cert fail on heroku curl.
        # and all x-server provide ipv4 access

        url = schema + "://" + host + path
        payloads = ['%s %s HTTP/1.1\r\n' % (method, url)]
        for k in headers:
            v = headers[k]
            payloads.append('%s: %s\r\n' % (k, v))
        head_payload = "".join(payloads)

        request_body = '%s%s%s%s' % \
                       ((struct.pack('!H', len(head_payload)),  head_payload,
                         struct.pack('!I', len(data)), data))
        request_headers = {'Content-Length': len(data), 'Content-Type': 'application/octet-stream'}

        heroku_host = ""
        content, status, response = self._request(
                                            "POST", heroku_host, "/2/",
                                            request_headers, request_body, timeout)

        # self.logger.info('%s "PHP %s %s %s" %s %s', handler.address_string(), handler.command, url, handler.protocol_version, response.status, response.getheader('Content-Length', '-'))
        # self.logger.debug("status:%d", status)

        if hasattr(response, "task"):
            self.logger.debug("%s %s%s status:%d trace:%s", method, host, path, status, response.task.get_trace())
        else:
            self.logger.debug("%s %s%s status:%d", method, host, path, status)

        if status == 404:
            heroku_host = response.ssl_sock.host
            self.logger.warn("heroku appid:%s fail", heroku_host)
            try:
                self.host_manager.remove(heroku_host)
            except:
                pass
            return "", 501, {}

        if not content:
            return "", 501, {}

        try:
            res = simple_http_client.TxtResponse(content)
        except Exception as e:
            self.logger.warn("decode %s response except:%r", content, e)
            return "", 501, {}

        res.worker = response.worker
        res.task = response.task
        return res.body, res.status, res

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #22
0
class Front(object):
    name = "tls_relay_front"

    def __init__(self):
        self.running = True

        self.logger = logger
        config_path = os.path.join(module_data_path, "tls_relay.json")
        self.config = Config(config_path)

        self.ca_cert_fn = os.path.join(module_data_path, "tls_relay_CA.crt")
        self.openssl_context = SSLContext(logger)
        if os.path.isfile(self.ca_cert_fn):
            self.openssl_context.set_ca(self.ca_cert_fn)

        host_fn = os.path.join(module_data_path, "tls_host.json")
        self.host_manager = host_manager.HostManager(host_fn)

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = IpSimpleSource(self.config.ip_source_ips)

        default_ip_list_fn = ""
        ip_list_fn = os.path.join(module_data_path, "tls_relay_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)
        for ip in self.config.ip_source_ips:
            self.ip_manager.add_ip(ip, 100)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

        self.account = ""
        self.password = ""

    def get_dispatcher(self, host=None):
        return self.http_dispatcher

    def set_x_tunnel_account(self, account, password):
        self.account = account
        self.password = password

    def set_ips(self, ips):
        if not ips:
            return

        host_info = {}
        ca_certs = []
        ipss = []
        for ip in ips:
            dat = ips[ip]
            ca_cert = dat["ca_crt"]
            sni = dat["sni"]

            host_info[ip] = {"sni": sni, "ca_crt": ca_cert}
            if ca_cert not in ca_certs:
                ca_certs.append(ca_cert)
            ipss.append(ip)

        self.ip_manager.update_ips(ipss)
        self.ip_manager.save(True)
        self.host_manager.set_host(host_info)

        ca_content = "\n\n".join(ca_certs)
        with open(self.ca_cert_fn, "w") as fd:
            fd.write(ca_content)
        self.openssl_context.set_ca(self.ca_cert_fn)
        self.logger.info("set_ips:%s", ",".join(ipss))

    def request(self,
                method,
                host,
                path="/",
                headers={},
                data="",
                timeout=120):
        headers = dict(headers)
        headers["XX-Account"] = self.account

        response = self.http_dispatcher.request(method,
                                                host,
                                                path,
                                                dict(headers),
                                                data,
                                                timeout=timeout)
        if not response:
            logger.warn("req %s get response timeout", path)
            return "", 602, {}

        status = response.status

        content = response.task.read_all()
        if status == 200:
            logger.debug("%s %s%s status:%d trace:%s", method, host, path,
                         status, response.task.get_trace())
        else:
            logger.warn("%s %s%s status:%d trace:%s", method, host, path,
                        status, response.task.get_trace())
        return content, status, response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #23
0
class Front(object):
    name = "gae_front"

    def __init__(self):
        self.logger = logger
        self.config = config

    def start(self):
        self.running = True

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.openssl_context = SSLContext(
            logger,
            ca_certs=ca_certs,
            support_http2=config.support_http2,
            cipher_suites=[
                'ALL', "!RC4-SHA", "!ECDHE-RSA-RC4-SHA",
                "!ECDHE-RSA-AES128-GCM-SHA256", "!AES128-GCM-SHA256",
                "!ECDHE-RSA-AES128-SHA", "!AES128-SHA"
            ])

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager = host_manager.HostManager(self.config, logger)
        self.host_manager.appid_manager = self.appid_manager

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)

        #self.ip_checker = CheckIp(logger, self.config, self.connect_creator)

        self.ipv6_source = Ipv6PoolSource(logger, self.config, "ipv6_list.txt")
        self.ip_source = self.ipv6_source
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    self.ip_source,
                                    check_local_network,
                                    None,
                                    os.path.join(data_path, "good_ip.txt"),
                                    scan_ip_log=None)

        #self.appid_manager.check_api = self.ip_checker.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)

        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

    def request(self,
                method,
                host,
                path="/",
                headers={},
                data="",
                timeout=120):
        response = self.http_dispatcher.request(method,
                                                host,
                                                path,
                                                dict(headers),
                                                data,
                                                timeout=timeout)

        return response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False
Exemple #24
0
class Front(object):
    name = "gae_front"

    def __init__(self):
        self.logger = logger
        self.config = config

    def start(self):
        self.running = True

        ca_certs = 'cacert.pem'
        self.openssl_context = SSLContext(
            logger,
            ca_certs=ca_certs,
            support_http2=config.support_http2,
            protocol="TLSv1_2"
            #cipher_suites=[b'ALL', b"!RC4-SHA", b"!ECDHE-RSA-RC4-SHA", b"!ECDHE-RSA-AES128-GCM-SHA256",
            #               b"!AES128-GCM-SHA256", b"!ECDHE-RSA-AES128-SHA", b"!AES128-SHA"]
        )

        self.appid_manager = AppidManager(self.config, logger)

        self.host_manager = host_manager.HostManager(self.config, logger)
        self.host_manager.appid_manager = self.appid_manager

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)

        # self.ip_checker = CheckIp(xlog.null, self.config, self.connect_creator)

        self.ip_manager = IpManager(logger,
                                    self.config,
                                    check_local_network,
                                    None,
                                    'good_ip.txt',
                                    scan_ip_log=None)

        # self.appid_manager.check_api = self.ip_checker.check_ip
        self.appid_manager.ip_manager = self.ip_manager

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)

        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

    def get_dispatcher(self):
        return self.http_dispatcher

    def request(self,
                method,
                host,
                path=b"/",
                headers={},
                data="",
                timeout=120):
        response = self.http_dispatcher.request(method,
                                                host,
                                                path,
                                                dict(headers),
                                                data,
                                                timeout=timeout)

        return response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #25
0
class Front(object):
    name = "tls_relay_front"

    def __init__(self):
        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.logger = logger
        config_path = os.path.join(module_data_path, "tls_relay.json")
        self.config = Config(config_path)

        self.ca_cert_fn = os.path.join(module_data_path, "tls_relay_CA.crt")
        self.openssl_context = SSLContext(logger)
        if os.path.isfile(self.ca_cert_fn):
            self.openssl_context.set_ca(self.ca_cert_fn)

        host_fn = os.path.join(module_data_path, "tls_host.json")
        self.host_manager = host_manager.HostManager(host_fn)

        self.connect_creator = ConnectCreator(logger, self.config,
                                              self.openssl_context,
                                              self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = IpSimpleSource(self.config.ip_source_ips)

        default_ip_list_fn = ""
        ip_list_fn = os.path.join(module_data_path, "tls_relay_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)
        for ip in self.config.ip_source_ips:
            self.ip_manager.add_ip(ip, 100)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        self.account = ""
        self.password = ""

        threading.Thread(target=self.debug_data_clearup_thread).start()

    def set_x_tunnel_account(self, account, password):
        self.account = account
        self.password = password

    def log_debug_data(self, rtt, sent, received):
        now = time.time()

        self.rtts.append((rtt, now))

        with self.traffics_lock:
            self.traffics.append((sent, received, now))
            self.recent_sent += sent
            self.recent_received += received
            self.total_sent += sent
            self.total_received += received

    def get_rtt(self):
        now = time.time()

        while len(self.rtts) > 1:
            with self.rtts_lock:
                rtt, log_time = rtt_log = max(self.rtts)

                if now - log_time > 5:
                    self.rtts.remove(rtt_log)
                    continue

            return rtt

        return self.rtts[0][0]

    def debug_data_clearup_thread(self):
        while self.running:
            now = time.time()

            with self.rtts_lock:
                if len(self.rtts) > 1 and now - self.rtts[0][-1] > 5:
                    self.rtts.popleft()

            with self.traffics_lock:
                if self.traffics and now - self.traffics[0][-1] > 60:
                    sent, received, _ = self.traffics.popleft()
                    self.recent_sent -= sent
                    self.recent_received -= received

            time.sleep(1)

    def worker_num(self):
        return len(self.http_dispatcher.workers)

    def set_ips(self, ips):
        if not ips:
            return

        host_info = {}
        ca_certs = []
        ipss = []
        for ip in ips:
            dat = ips[ip]
            ca_cert = dat["ca_crt"]
            sni = dat["sni"]

            host_info[ip] = {"sni": sni, "ca_crt": ca_cert}
            if ca_cert not in ca_certs:
                ca_certs.append(ca_cert)
            ipss.append(ip)

        self.ip_manager.update_ips(ipss)
        self.ip_manager.save(True)
        self.host_manager.set_host(host_info)

        ca_content = "\n\n".join(ca_certs)
        with open(self.ca_cert_fn, "w") as fd:
            fd.write(ca_content)
        self.openssl_context.set_ca(self.ca_cert_fn)
        self.logger.info("set_ips:%s", ",".join(ipss))

    def get_score(self, host=None):
        now = time.time()
        if now - self.last_fail_time < self.config.front_continue_fail_block and \
                self.continue_fail_num > self.config.front_continue_fail_num:
            return None

        worker = self.http_dispatcher.get_worker(nowait=True)
        if not worker:
            return None

        return worker.get_score()

    def request(self,
                method,
                host,
                path="/",
                headers={},
                data="",
                timeout=120):
        headers = dict(headers)
        headers["XX-Account"] = self.account

        response = self.http_dispatcher.request(method,
                                                host,
                                                path,
                                                dict(headers),
                                                data,
                                                timeout=timeout)
        if not response:
            logger.warn("req %s get response timeout", path)
            return "", 602, {}

        status = response.status
        if status not in [200, 405]:
            # logger.warn("front request %s %s%s fail, status:%d", method, host, path, status)
            self.fail_num += 1
            self.continue_fail_num += 1
            self.last_fail_time = time.time()
        else:
            self.success_num += 1
            self.continue_fail_num = 0

        content = response.task.read_all()
        if status == 200:
            logger.debug("%s %s%s status:%d trace:%s", method, host, path,
                         status, response.task.get_trace())
        else:
            logger.warn("%s %s%s status:%d trace:%s", method, host, path,
                        status, response.task.get_trace())
        return content, status, response

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()
Exemple #26
0
class Front(object):
    name = "heroku_front"

    def __init__(self):
        self.logger = logger
        config_path = os.path.join(module_data_path, "heroku_front.json")
        self.config = Config(config_path)

        ca_certs = os.path.join(current_path, "cacert.pem")
        self.host_manager = host_manager.HostManager(self.config.appids)

        openssl_context = SSLContext(logger, ca_certs=ca_certs)
        self.connect_creator = ConnectCreator(logger, self.config,
                                              openssl_context,
                                              self.host_manager)
        self.check_ip = CheckIp(xlog.null, self.config, self.connect_creator)

        ip_source = None
        default_ip_list_fn = os.path.join(current_path, "good_ip.txt")
        ip_list_fn = os.path.join(module_data_path, "heroku_ip_list.txt")
        self.ip_manager = IpManager(logger,
                                    self.config,
                                    ip_source,
                                    check_local_network,
                                    self.check_ip.check_ip,
                                    default_ip_list_fn,
                                    ip_list_fn,
                                    scan_ip_log=None)

        self.connect_manager = ConnectManager(logger, self.config,
                                              self.connect_creator,
                                              self.ip_manager,
                                              check_local_network)
        self.http_dispatcher = HttpsDispatcher(logger, self.config,
                                               self.ip_manager,
                                               self.connect_manager)

        self.success_num = 0
        self.fail_num = 0
        self.continue_fail_num = 0
        self.last_fail_time = 0
        self.running = True

        self.rtts = collections.deque([(0, time.time())])
        self.rtts_lock = threading.Lock()
        self.traffics = collections.deque()
        self.traffics_lock = threading.Lock()
        self.recent_sent = 0
        self.recent_received = 0
        self.total_sent = 0
        self.total_received = 0

        threading.Thread(target=self.debug_data_clearup_thread).start()

    def log_debug_data(self, rtt, sent, received):
        now = time.time()

        self.rtts.append((rtt, now))

        with self.traffics_lock:
            self.traffics.append((sent, received, now))
            self.recent_sent += sent
            self.recent_received += received
            self.total_sent += sent
            self.total_received += received

    def get_rtt(self):
        now = time.time()

        while len(self.rtts) > 1:
            with self.rtts_lock:
                rtt, log_time = rtt_log = max(self.rtts)

                if now - log_time > 5:
                    self.rtts.remove(rtt_log)
                    continue

            return rtt

        return self.rtts[0][0]

    def debug_data_clearup_thread(self):
        while self.running:
            now = time.time()

            with self.rtts_lock:
                if len(self.rtts) > 1 and now - self.rtts[0][-1] > 5:
                    self.rtts.popleft()

            with self.traffics_lock:
                if self.traffics and now - self.traffics[0][-1] > 60:
                    sent, received, _ = self.traffics.popleft()
                    self.recent_sent -= sent
                    self.recent_received -= received

            time.sleep(1)

    def worker_num(self):
        return len(self.http_dispatcher.workers)

    def set_ips(self, ips):
        self.ip_manager.set_ips(ips)

    def get_score(self, host=None):
        if not self.host_manager.appids:
            return None

        now = time.time()
        if now - self.last_fail_time < self.config.front_continue_fail_block and \
                self.continue_fail_num > self.config.front_continue_fail_num:
            return None

        worker = self.http_dispatcher.get_worker(nowait=True)
        if not worker:
            return None

        return worker.get_score()

    def _request(self,
                 method,
                 host,
                 path="/",
                 headers={},
                 data="",
                 timeout=40):
        try:
            response = self.http_dispatcher.request(method,
                                                    host,
                                                    path,
                                                    dict(headers),
                                                    data,
                                                    timeout=timeout)
            status = response.status
            if status != 200:
                xlog.warn("front request %s %s%s fail, status:%d", method,
                          host, path, status)

            content = response.task.read_all()
            # xlog.debug("%s %s%s trace:%s", method, response.ssl_sock.host, path, response.task.get_trace())
            return content, status, response
        except Exception as e:
            xlog.exception("front request %s %s%s fail:%r", method, host, path,
                           e)

            return "", 500, {}

    def request(self,
                method,
                host,
                schema="http",
                path="/",
                headers={},
                data="",
                timeout=40):
        # change top domain to xx-net.net
        # this domain bypass the cloudflare front for ipv4
        p = host.find(".")
        host_sub = host[:p]
        host = host_sub + ".xx-net.net"

        schema = "http"
        # force schema to http, avoid cert fail on heroku curl.
        # and all x-server provide ipv4 access

        url = schema + "://" + host + path
        payloads = ['%s %s HTTP/1.1\r\n' % (method, url)]
        for k in headers:
            v = headers[k]
            payloads.append('%s: %s\r\n' % (k, v))
        head_payload = "".join(payloads)

        request_body = '%s%s%s%s' % \
                       ((struct.pack('!H', len(head_payload)),  head_payload,
                         struct.pack('!I', len(data)), data))
        request_headers = {
            'Content-Length': len(data),
            'Content-Type': 'application/octet-stream'
        }

        heroku_host = ""
        content, status, response = self._request("POST", heroku_host, "/2/",
                                                  request_headers,
                                                  request_body, timeout)

        # xlog.info('%s "PHP %s %s %s" %s %s', handler.address_string(), handler.command, url, handler.protocol_version, response.status, response.getheader('Content-Length', '-'))
        # xlog.debug("status:%d", status)
        if status == 200:
            xlog.debug("%s %s%s trace:%s", method, host, path,
                       response.task.get_trace())
            self.last_success_time = time.time()
            self.continue_fail_num = 0
            self.success_num += 1
        else:
            if status == 404:
                heroku_host = response.ssl_sock.host
                xlog.warn("heroku:%s fail", heroku_host)
                try:
                    self.host_manager.remove(heroku_host)
                except:
                    pass

            self.last_fail_time = time.time()
            self.continue_fail_num += 1
            self.fail_num += 1

        try:
            res = simple_http_client.TxtResponse(content)
        except:
            return "", 501, {}

        res.worker = response.worker
        res.task = response.task
        return res.body, res.status, res

    def stop(self):
        logger.info("terminate")
        self.connect_manager.set_ssl_created_cb(None)
        self.http_dispatcher.stop()
        self.connect_manager.stop()
        self.ip_manager.stop()

        self.running = False

    def set_proxy(self, args):
        logger.info("set_proxy:%s", args)

        self.config.PROXY_ENABLE = args["enable"]
        self.config.PROXY_TYPE = args["type"]
        self.config.PROXY_HOST = args["host"]
        self.config.PROXY_PORT = args["port"]
        self.config.PROXY_USER = args["user"]
        self.config.PROXY_PASSWD = args["passwd"]

        self.config.save()

        self.connect_creator.update_config()