예제 #1
0
def main():
    shell.check_python()

    # fix py2exe
    if hasattr(sys, "frozen") and sys.frozen in \
            ("windows_exe", "console_exe"):
        p = os.path.dirname(os.path.abspath(sys.executable))
        os.chdir(p)

    config = shell.get_config(True)
    daemon.daemon_exec(config)

    logging.info("starting local at %s:%d" %
                 (config['local_address'], config['local_port']))

    dns_resolver = asyncdns.DNSResolver()
    tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)
    udp_server = udprelay.UDPRelay(config, dns_resolver, True)
    loop = eventloop.EventLoop()
    dns_resolver.add_to_loop(loop)
    tcp_server.add_to_loop(loop)
    udp_server.add_to_loop(loop)

    def handler(signum, _):
        logging.warn('received SIGQUIT, doing graceful shutting down..')
        tcp_server.close(next_tick=True)
        udp_server.close(next_tick=True)
    signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)

    def int_handler(signum, _):
        sys.exit(1)
    signal.signal(signal.SIGINT, int_handler)

    daemon.set_user(config.get('user', None))
    loop.run()
예제 #2
0
def main():
    utils.check_python()

    # fix py2exe
    if hasattr(sys, "frozen") and sys.frozen in \
            ("windows_exe", "console_exe"):
        p = os.path.dirname(os.path.abspath(sys.executable))
        os.chdir(p)

    config = utils.get_config(True)

    utils.print_shadowsocks()

    encrypt.init_table(config['password'], config['method'])

    try:
        logging.info("starting local at %s:%d" %
                     (config['local_address'], config['local_port']))

        tcp_server = tcprelay.TCPRelay(config, True)
        udp_server = udprelay.UDPRelay(config, True)
        loop = eventloop.EventLoop()
        tcp_server.add_to_loop(loop)
        udp_server.add_to_loop(loop)
        loop.run()
    except (KeyboardInterrupt, IOError, OSError) as e:
        logging.error(e)
        os._exit(0)
예제 #3
0
    def cb_new_server(self, port, password):
        ret = True
        port = int(port)

        if 'server' in self.config:
            if port in self.tcp_servers_pool:
                logging.info("server already at %s:%d" %
                             (self.config['server'], port))
                return 'this port server is already running'
            else:
                a_config = self.config.copy()
                a_config['server_port'] = port
                a_config['password'] = password
                try:
                    logging.info("starting server at %s:%d" %
                                 (a_config['server'], port))
                    tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver,
                                                   False)
                    tcp_server.add_to_loop(self.loop)
                    self.tcp_servers_pool[port] = tcp_server
                    #udp_server = udprelay.UDPRelay(a_config, self.dns_resolver, False)
                    #udp_server.add_to_loop(self.loop)
                    #self.udp_servers_pool.update({port: udp_server})
                except Exception, e:
                    logging.warn(e)
예제 #4
0
def main():
    shell.check_python()

    # fix py2exe
    if hasattr(sys, "frozen") and sys.frozen in \
            ("windows_exe", "console_exe"):
        p = os.path.dirname(os.path.abspath(sys.executable))
        os.chdir(p)

    config = shell.get_config(True)

    if not config.get('dns_ipv6', False):
        asyncdns.IPV6_CONNECTION_SUPPORT = False

    daemon.daemon_exec(config)
    logging.info(
        "local start with protocol[%s] password [%s] method [%s] obfs [%s] obfs_param [%s]"
        % (config['protocol'], config['password'], config['method'],
           config['obfs'], config['obfs_param']))

    try:
        logging.info("starting local at %s:%d" %
                     (config['local_address'], config['local_port']))

        dns_resolver = asyncdns.DNSResolver()
        tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)
        udp_server = udprelay.UDPRelay(config, dns_resolver, True)
        loop = eventloop.EventLoop()
        dns_resolver.add_to_loop(loop)
        tcp_server.add_to_loop(loop)
        udp_server.add_to_loop(loop)

        def handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            tcp_server.close(next_tick=True)
            udp_server.close(next_tick=True)

        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)

        def int_handler(signum, _):
            sys.exit(1)

        signal.signal(signal.SIGINT, int_handler)

        daemon.set_user(config.get('user', None))
        loop.run()
    except Exception as e:
        shell.print_exception(e)
        sys.exit(1)
예제 #5
0
 def add_port(self, config):
     port = int(config['server_port'])
     servers = self._relays.get(port, None)
     if servers:
         logging.error("server already exists at %s:%d" % (config['server'],
                                                           port))
         return
     logging.info("adding server at %s:%d" % (config['server'], port))
     t = tcprelay.TCPRelay(config, self._dns_resolver, False,
                           self.stat_callback)
     u = udprelay.UDPRelay(config, self._dns_resolver, False,
                           self.stat_callback)
     t.add_to_loop(self._loop)
     u.add_to_loop(self._loop)
     self._relays[port] = (t, u)
예제 #6
0
def main():
    loop = eventloop.EventLoop()
    dns_resolver = asyncdns.DNSResolver(loop)
    tcp_server = tcprelay.TCPRelay(dns_resolver, loop)
    udp_server = udprelay.UDPRelay(dns_resolver, loop)

    def handler(signum, _):
        logging.warning('received SIGQUIT, doing graceful shutting down..')
        tcp_server.close()
        udp_server.close()

    signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)

    def int_handler(signum, _):
        sys.exit(1)

    signal.signal(signal.SIGINT, int_handler)

    loop.run()
예제 #7
0
파일: local.py 프로젝트: Sigma-Algebra/ss
def main():
    utils.check_python()

    # fix py2exe
    if hasattr(sys, "frozen") and sys.frozen in \
            ("windows_exe", "console_exe"):
        p = os.path.dirname(os.path.abspath(sys.executable))
        os.chdir(p)

    config = utils.get_config(True)

    utils.print_shadowsocks()

    encrypt.init_table(config['password'], config['method'])

    try:
        logging.info("starting local at %s:%d" %
                     (config['local_address'], config['local_port']))

        dns_resolver = asyncdns.DNSResolver()
        tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)
        udp_server = udprelay.UDPRelay(config, dns_resolver, True)
        loop = eventloop.EventLoop()
        dns_resolver.add_to_loop(loop)
        tcp_server.add_to_loop(loop)
        udp_server.add_to_loop(loop)

        def handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            tcp_server.close(next_tick=True)
            udp_server.close(next_tick=True)

        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)
        loop.run()
    except (KeyboardInterrupt, IOError, OSError) as e:
        logging.error(e)
        if config['verbose']:
            import traceback
            traceback.print_exc()
        os._exit(1)
예제 #8
0
def main():
    import logging
    # -- import from shadowsockesr-v
    import conf
    import exit
    import shell
    import eventloop
    import tcprelay
    import udprelay
    import asyncdns

    # -- init logging --
    conf.logger_init()
    # show version
    logging.info(conf.version())

    # -- starting ssr --
    # get ssr configurations
    ssr_conf = shell.get_ssr_conf(ssr_conf_path=conf.ssr_conf_path())

    if not ssr_conf.get('dns_ipv6', False):
        asyncdns.IPV6_CONNECTION_SUPPORT = False

    password = ssr_conf['password']
    method = ssr_conf['method']
    protocol = ssr_conf['protocol']
    protocol_param = ssr_conf['protocol_param']
    obfs = ssr_conf['obfs']
    obfs_param = ssr_conf['obfs_param']
    udp_enable = ssr_conf['udp_enable']
    dns_list = ssr_conf['dns']

    logging.info(f'Server start with '
                 f'password [{password}] '
                 f'method [{method}] '
                 f'protocol[{protocol}] '
                 f'protocol_param[{protocol_param}] '
                 f'obfs [{obfs}] '
                 f'obfs_param [{obfs_param}]')

    server = ssr_conf['server']
    port = ssr_conf['server_port']
    logging.info(f'Starting server at [{server}]:{port}')

    try:
        ssr_conf['out_bind'] = ''
        ssr_conf['out_bindv6'] = ''

        # create epoll (singleton)
        loop = eventloop.EventLoop()

        # dns server (singleton)
        dns_resolver = asyncdns.DNSResolver(dns_list)
        dns_resolver.add_to_loop(loop)

        stat_counter_dict = {}
        # listen tcp && register socket
        tcp = tcprelay.TCPRelay(ssr_conf, dns_resolver, stat_counter=stat_counter_dict)
        tcp.add_to_loop(loop)

        if udp_enable:
            # listen udp && register socket
            udp = udprelay.UDPRelay(ssr_conf, dns_resolver, False, stat_counter=stat_counter_dict)
            udp.add_to_loop(loop)

        # run epoll to handle socket
        loop.run()
    except Exception as e:
        exit.error(e)
예제 #9
0
def main():
    utils.check_python()

    config = utils.get_config(False)

    utils.print_shadowsocks()

    if config['port_password']:
        if config['server_port'] or config['password']:
            logging.warn('warning: port_password should not be used with '
                         'server_port and password. server_port and password '
                         'will be ignored')
    else:
        config['port_password'] = {}
        config['port_password'][str(
            config['server_port'])] = config['password']

    encrypt.init_table(config['password'], config['method'])
    tcp_servers = []
    udp_servers = []
    for port, password in config['port_password'].items():
        a_config = config.copy()
        a_config['server_port'] = int(port)
        a_config['password'] = password
        logging.info("starting server at %s:%d" %
                     (a_config['server'], int(port)))
        tcp_servers.append(tcprelay.TCPRelay(a_config, False))
        udp_servers.append(udprelay.UDPRelay(a_config, False))

    def run_server():
        try:
            loop = eventloop.EventLoop()
            for tcp_server in tcp_servers:
                tcp_server.add_to_loop(loop)
            for udp_server in udp_servers:
                udp_server.add_to_loop(loop)
            loop.run()
        except (KeyboardInterrupt, IOError, OSError) as e:
            logging.error(e)
            import traceback
            traceback.print_exc()
            os._exit(0)

    if int(config['workers']) > 1:
        if os.name == 'posix':
            children = []
            is_child = False
            for i in xrange(0, int(config['workers'])):
                r = os.fork()
                if r == 0:
                    logging.info('worker started')
                    is_child = True
                    run_server()
                    break
                else:
                    children.append(r)
            if not is_child:

                def handler(signum, _):
                    for pid in children:
                        os.kill(pid, signum)
                        os.waitpid(pid, 0)
                    sys.exit()

                import signal
                signal.signal(signal.SIGTERM, handler)

                # master
                for a_tcp_server in tcp_servers:
                    a_tcp_server.close()
                for a_udp_server in udp_servers:
                    a_udp_server.close()

                for child in children:
                    os.waitpid(child, 0)
        else:
            logging.warn('worker is only available on Unix/Linux')
            run_server()
    else:
        run_server()
예제 #10
0
def main():

    shell.check_python()

    # fix py2exe
    if hasattr(sys, "frozen") and sys.frozen in ("windows_exe", "console_exe"):
        p = os.path.dirname(os.path.abspath(sys.executable))
        os.chdir(p)

    config = shell.get_config(True)

    #added by cloud for local random choose a server and the port and the port_password
    if config['port_password']:
        if config['password']:
            logging.warn(
                'warning: port_password should not be used with server_port and password. server_port and password will be ignored'
            )


#         config['server_port'] = int(random.choice(config['port_password'].items())[0])
        if config.has_key('server_port'):
            if type(config['server_port']) == list and config['server_port']:
                config['server_port'] = random.choice(
                    config.get('server_port', 8388))
            elif config['server_port']:
                config['server_port'] == int(
                    common.to_str(config.get('server_port', 8388)))
            else:
                config['server_port'] = int(
                    random.choice(config['port_password'].items())[0])
        else:
            config['server_port'] = int(
                random.choice(config['port_password'].items())[0])
        if not config['password'] or str(config['password']) == "":
            config['password'] = common.to_str(
                config['port_password']["%s" % config['server_port']])
    else:
        if type(config['server_port']) == list and config['server_port']:
            config['server_port'] = random.choice(
                config.get('server_port', 8388))
        else:
            config['server_port'] == int(
                common.to_str(config.get('server_port', 8388)))
        config["password"] = str(
            config["port_password"]["%s" % config["server_port"]]).strip()

    logging.warn('!' * 30)
    logging.info(
        "OK.. I choose this guy to help me f**k the GFW.. [ %s : %s : %s : %s : %s]"
        % (config['server'], config['server_port'], config['password'],
           config['server_info']["%s" % config['server']], config['method']))
    logging.warn('!' * 30)
    time.sleep(1)

    daemon.daemon_exec(config)

    try:
        logging.info("starting local at %s:%d" %
                     (config['local_address'], config['local_port']))

        dns_resolver = asyncdns.DNSResolver(config)
        tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)
        udp_server = udprelay.UDPRelay(config, dns_resolver, True)
        loop = eventloop.EventLoop(config)
        dns_resolver.add_to_loop(loop)
        tcp_server.add_to_loop(loop)
        udp_server.add_to_loop(loop)

        def handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            tcp_server.close(next_tick=True)
            udp_server.close(next_tick=True)

        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler)

        def int_handler(signum, _):
            sys.exit(1)

        signal.signal(signal.SIGINT, int_handler)

        daemon.set_user(config.get('user', None))
        loop.run()
    except Exception as e:
        shell.print_exception(e)
        sys.exit(1)
예제 #11
0
파일: server.py 프로젝트: Sigma-Algebra/ss
def main():
    utils.check_python()

    config = utils.get_config(False)

    utils.print_shadowsocks()

    if config['port_password']:
        if config['password']:
            logging.warn('warning: port_password should not be used with '
                         'server_port and password. server_port and password '
                         'will be ignored')
    else:
        config['port_password'] = {}
        server_port = config['server_port']
        if type(server_port) == list:
            for a_server_port in server_port:
                config['port_password'][a_server_port] = config['password']
        else:
            config['port_password'][str(server_port)] = config['password']

    encrypt.init_table(config['password'], config['method'])
    tcp_servers = []
    udp_servers = []
    dns_resolver = asyncdns.DNSResolver()
    for port, password in config['port_password'].items():
        a_config = config.copy()
        a_config['server_port'] = int(port)
        a_config['password'] = password
        logging.info("starting server at %s:%d" %
                     (a_config['server'], int(port)))
        tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False))
        udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False))

    def run_server():
        def child_handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            map(lambda s: s.close(next_tick=True), tcp_servers + udp_servers)

        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
                      child_handler)
        try:
            loop = eventloop.EventLoop()
            dns_resolver.add_to_loop(loop)
            map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers)
            loop.run()
        except (KeyboardInterrupt, IOError, OSError) as e:
            logging.error(e)
            if config['verbose']:
                import traceback
                traceback.print_exc()
            os._exit(1)

    if int(config['workers']) > 1:
        if os.name == 'posix':
            children = []
            is_child = False
            for i in xrange(0, int(config['workers'])):
                r = os.fork()
                if r == 0:
                    logging.info('worker started')
                    is_child = True
                    run_server()
                    break
                else:
                    children.append(r)
            if not is_child:

                def handler(signum, _):
                    for pid in children:
                        try:
                            os.kill(pid, signum)
                        except OSError:  # child may already exited
                            pass
                    sys.exit()

                signal.signal(signal.SIGTERM, handler)
                signal.signal(signal.SIGQUIT, handler)

                # master
                for a_tcp_server in tcp_servers:
                    a_tcp_server.close()
                for a_udp_server in udp_servers:
                    a_udp_server.close()
                dns_resolver.close()

                for child in children:
                    os.waitpid(child, 0)
        else:
            logging.warn('worker is only available on Unix/Linux')
            run_server()
    else:
        run_server()
예제 #12
0
def main():
    import sys
    import os
    import signal
    import resource
    # -- import from shadowsockesr-v
    import logger
    import conf
    import exit
    import shell, daemon, eventloop, tcprelay, udprelay, asyncdns, common

    # get ssr configurations
    ssr_conf = shell.get_ssr_conf(is_local=False, ssr_conf_path=conf.configuration_path())

    # start daemon
    daemon.daemon_exec(ssr_conf)

    logger.info('current process open files[cmd\'ulimit -n\'] resource: soft %d hard %d' %
                 resource.getrlimit(resource.RLIMIT_NOFILE))

    # todo Multiport -> Single port
    if not ssr_conf['port_password']:
        ssr_conf['port_password'] = {}

        server_port = ssr_conf['server_port']
        if type(server_port) == list:
            for a_server_port in server_port:
                ssr_conf['port_password'][a_server_port] = ssr_conf['password']
        else:
            ssr_conf['port_password'][str(server_port)] = ssr_conf['password']

    if not ssr_conf.get('dns_ipv6', False):
        asyncdns.IPV6_CONNECTION_SUPPORT = False

    # no used
    # if config.get('manager_address', 0):
    #     logging.info('entering manager mode')
    #     manager.run(config)
    #     return

    tcp_servers = []
    udp_servers = []
    dns_resolver = asyncdns.DNSResolver()
    if int(ssr_conf['workers']) > 1:
        stat_counter_dict = None
    else:
        stat_counter_dict = {}
    port_password = ssr_conf['port_password']
    config_password = ssr_conf.get('password', 'm')
    del ssr_conf['port_password']
    for port, password_obfs in port_password.items():
        method = ssr_conf["method"]
        protocol = ssr_conf.get("protocol", 'origin')
        protocol_param = ssr_conf.get("protocol_param", '')
        obfs = ssr_conf.get("obfs", 'plain')
        obfs_param = ssr_conf.get("obfs_param", '')
        bind = ssr_conf.get("out_bind", '')
        bindv6 = ssr_conf.get("out_bindv6", '')
        if type(password_obfs) == list:
            password = password_obfs[0]
            obfs = common.to_str(password_obfs[1])
            if len(password_obfs) > 2:
                protocol = common.to_str(password_obfs[2])
        elif type(password_obfs) == dict:
            password = password_obfs.get('password', config_password)
            method = common.to_str(password_obfs.get('method', method))
            protocol = common.to_str(password_obfs.get('protocol', protocol))
            protocol_param = common.to_str(password_obfs.get('protocol_param', protocol_param))
            obfs = common.to_str(password_obfs.get('obfs', obfs))
            obfs_param = common.to_str(password_obfs.get('obfs_param', obfs_param))
            bind = password_obfs.get('out_bind', bind)
            bindv6 = password_obfs.get('out_bindv6', bindv6)
        else:
            password = password_obfs
        a_config = ssr_conf.copy()
        ipv6_ok = False
        logger.info("server start with protocol[%s] password [%s] method [%s] obfs [%s] obfs_param [%s]" %
                (protocol, password, method, obfs, obfs_param))
        if 'server_ipv6' in a_config:
            try:
                if len(a_config['server_ipv6']) > 2 and a_config['server_ipv6'][0] == "[" and a_config['server_ipv6'][-1] == "]":
                    a_config['server_ipv6'] = a_config['server_ipv6'][1:-1]
                a_config['server_port'] = int(port)
                a_config['password'] = password
                a_config['method'] = method
                a_config['protocol'] = protocol
                a_config['protocol_param'] = protocol_param
                a_config['obfs'] = obfs
                a_config['obfs_param'] = obfs_param
                a_config['out_bind'] = bind
                a_config['out_bindv6'] = bindv6
                a_config['server'] = a_config['server_ipv6']
                logger.info("starting server at [%s]:%d" %
                             (a_config['server'], int(port)))
                tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict))
                udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict))
                if a_config['server_ipv6'] == '::':
                    ipv6_ok = True
            except Exception as e:
                logger.error(e)

        try:
            a_config = ssr_conf.copy()
            a_config['server_port'] = int(port)
            a_config['password'] = password
            a_config['method'] = method
            a_config['protocol'] = protocol
            a_config['protocol_param'] = protocol_param
            a_config['obfs'] = obfs
            a_config['obfs_param'] = obfs_param
            a_config['out_bind'] = bind
            a_config['out_bindv6'] = bindv6
            logger.info("starting server at %s:%d" %
                         (a_config['server'], int(port)))
            tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict))
            udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False, stat_counter=stat_counter_dict))
        except Exception as e:
            if not ipv6_ok:
                logger.error(e)

    def run_server():
        def child_handler(signum, _):
            logger.warning('received SIGQUIT, doing graceful shutting down..')
            list(map(lambda s: s.close(next_tick=True),
                     tcp_servers + udp_servers))
        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
                      child_handler)

        def int_handler(signum, _):
            sys.exit(1)
        signal.signal(signal.SIGINT, int_handler)

        try:
            loop = eventloop.EventLoop()
            dns_resolver.add_to_loop(loop)
            list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers))

            daemon.set_user(ssr_conf.get('user', None))
            loop.run()
        except Exception as e:
            exit.error(e)

    if int(ssr_conf['workers']) > 1:
        if os.name == 'posix':
            children = []
            is_child = False
            for i in range(0, int(ssr_conf['workers'])):
                r = os.fork()
                if r == 0:
                    logger.info('worker started')
                    is_child = True
                    run_server()
                    break
                else:
                    children.append(r)
            if not is_child:
                def handler(signum, _):
                    for pid in children:
                        try:
                            os.kill(pid, signum)
                            os.waitpid(pid, 0)
                        except OSError:  # child may already exited
                            pass
                    sys.exit()
                signal.signal(signal.SIGTERM, handler)
                signal.signal(signal.SIGQUIT, handler)
                signal.signal(signal.SIGINT, handler)

                # master
                for a_tcp_server in tcp_servers:
                    a_tcp_server.close()
                for a_udp_server in udp_servers:
                    a_udp_server.close()
                dns_resolver.close()

                for child in children:
                    os.waitpid(child, 0)
        else:
            logger.warning('worker is only available on Unix/Linux')
            run_server()
    else:
        run_server()
예제 #13
0
class ServerPool(object):

    instance = None

    def __init__(self):
        utils.check_python()
        self.config = utils.get_config(False)
        utils.print_shadowsocks()
        self.dns_resolver = asyncdns.DNSResolver()
        self.mgr = asyncmgr.ServerMgr()
        self.tcp_servers_pool = {}
        self.tcp_ipv6_servers_pool = {}
        self.udp_servers_pool = {}
        self.udp_ipv6_servers_pool = {}

        self.loop = eventloop.EventLoop()
        thread.start_new_thread(ServerPool._loop,
                                (self.loop, self.dns_resolver, self.mgr))

    @staticmethod
    def get_instance():
        if ServerPool.instance is None:
            ServerPool.instance = ServerPool()
        return ServerPool.instance

    @staticmethod
    def _loop(loop, dns_resolver, mgr):
        try:
            mgr.add_to_loop(loop)
            dns_resolver.add_to_loop(loop)
            loop.run()
        except (KeyboardInterrupt, IOError, OSError) as e:
            logging.error(e)
            import traceback
            traceback.print_exc()
            os.exit(0)

    def server_is_run(self, port):
        port = int(port)
        ret = 0
        if port in self.tcp_servers_pool:
            ret = 1
        if port in self.tcp_ipv6_servers_pool:
            ret |= 2
        return ret

    def server_run_status(self, port):
        if 'server' in self.config:
            if port not in self.tcp_servers_pool:
                return False
        if 'server_ipv6' in self.config:
            if port not in self.tcp_ipv6_servers_pool:
                return False
        return True

    def new_server(self, port, password):
        ret = True
        port = int(port)

        if 'server' in self.config:
            if port in self.tcp_servers_pool:
                logging.info("server already at %s:%d" %
                             (self.config['server'], port))
                return 'this port server is already running'
            else:
                a_config = self.config.copy()
                a_config['server_port'] = port
                a_config['password'] = password
                try:
                    logging.info("starting server at %s:%d" %
                                 (a_config['server'], port))
                    tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver,
                                                   False)
                    tcp_server.add_to_loop(self.loop)
                    self.tcp_servers_pool.update({port: tcp_server})
                    udp_server = udprelay.UDPRelay(a_config, self.dns_resolver,
                                                   False)
                    udp_server.add_to_loop(self.loop)
                    self.udp_servers_pool.update({port: udp_server})
                except Exception, e:
                    logging.warn(e)

        if 'server_ipv6' in self.config:
            if port in self.tcp_ipv6_servers_pool:
                logging.info("server already at %s:%d" %
                             (self.config['server_ipv6'], port))
                return 'this port server is already running'
            else:
                a_config = self.config.copy()
                a_config['server'] = a_config['server_ipv6']
                a_config['server_port'] = port
                a_config['password'] = password
                try:
                    logging.info("starting server at %s:%d" %
                                 (a_config['server'], port))
                    tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver,
                                                   False)
                    tcp_server.add_to_loop(self.loop)
                    self.tcp_ipv6_servers_pool.update({port: tcp_server})
                    udp_server = udprelay.UDPRelay(a_config, self.dns_resolver,
                                                   False)
                    udp_server.add_to_loop(self.loop)
                    self.udp_ipv6_servers_pool.update({port: udp_server})
                except Exception, e:
                    logging.warn(e)
예제 #14
0
def main():
    shell.check_python()

    config = shell.get_config(False)

    daemon.daemon_exec(config)

    if config['port_password']:
        if config['password']:
            logging.warn('warning: port_password should not be used with '
                         'server_port and password. server_port and password '
                         'will be ignored')
    else:
        config['port_password'] = {}
        server_port = config['server_port']
        if type(server_port) == list:
            for a_server_port in server_port:
                config['port_password'][a_server_port] = config['password']
        else:
            config['port_password'][str(server_port)] = config['password']

    if config.get('manager_address', 0):
        logging.info('entering manager mode')
        manager.run(config)
        return

    tcp_servers = []
    udp_servers = []

    if 'dns_server' in config:  # allow override settings in resolv.conf
        dns_resolver = asyncdns.DNSResolver(config['dns_server'],
                                            config['prefer_ipv6'])
    else:
        dns_resolver = asyncdns.DNSResolver(prefer_ipv6=config['prefer_ipv6'])

    port_password = config['port_password']
    del config['port_password']
    for port, password in port_password.items():
        a_config = config.copy()
        a_config['server_port'] = int(port)
        a_config['password'] = password
        logging.info("starting server at %s:%d" %
                     (a_config['server'], int(port)))
        tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False))
        udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False))

    def run_server():
        def child_handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            list(
                map(lambda s: s.close(next_tick=True),
                    tcp_servers + udp_servers))

        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
                      child_handler)

        def int_handler(signum, _):
            sys.exit(1)

        signal.signal(signal.SIGINT, int_handler)

        try:
            loop = eventloop.EventLoop()
            dns_resolver.add_to_loop(loop)
            list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers))

            daemon.set_user(config.get('user', None))
            loop.run()
        except Exception as e:
            shell.print_exception(e)
            sys.exit(1)

    if int(config['workers']) > 1:
        if os.name == 'posix':
            children = []
            is_child = False
            for i in range(0, int(config['workers'])):
                r = os.fork()
                if r == 0:
                    logging.info('worker started')
                    is_child = True
                    run_server()
                    break
                else:
                    children.append(r)
            if not is_child:

                def handler(signum, _):
                    for pid in children:
                        try:
                            os.kill(pid, signum)
                            os.waitpid(pid, 0)
                        except OSError:  # child may already exited
                            pass
                    sys.exit()

                signal.signal(signal.SIGTERM, handler)
                signal.signal(signal.SIGQUIT, handler)
                signal.signal(signal.SIGINT, handler)

                # master
                for a_tcp_server in tcp_servers:
                    a_tcp_server.close()
                for a_udp_server in udp_servers:
                    a_udp_server.close()
                dns_resolver.close()

                for child in children:
                    os.waitpid(child, 0)
        else:
            logging.warn('worker is only available on Unix/Linux')
            run_server()
    else:
        run_server()