예제 #1
0
 def add(self):
     if self.args.L:
         link = self.args.L
     elif self.extra_args and ssrlink.is_valide_ssrlink(self.extra_args[0]):
         link = self.extra_args[0]
     else:
         config = shell.parse_config(True)
         link = encode_to_link(config)
         print(link)
     self.target.config.add_server(link)
예제 #2
0
 def random_switch_ssr(self):
     import random
     ssrs = self.get_server_list()
     ssr = random.choice(ssrs)
     config_from_link = decode_ssrlink(ssr)
     local_address = self.config['local_address']
     local_port = self.config['local_port']
     self.config = shell.parse_config(True, config_from_link)
     self.config['local_address'] = local_address
     self.config['local_port'] = local_port
     print_server_info(self.config, verbose=True, hightlight=True)
     self.network.switch(self.config)
예제 #3
0
 def run_server():
     shell.parse_args()
     config = shell.parse_config(True)
     config = config.copy()
     a_config = {
         'server': '127.0.0.1',
         'local_port': 1081,
         'port_password': {
             '8381': 'foobar1',
             '8382': 'foobar2'
         },
         'method': 'aes-256-cfb',
         'manager_address': '127.0.0.1:6001',
         'timeout': 60,
         'fast_open': False,
         'verbose': 2
     }
     config.update(a_config)
     manager = Manager(config)
     enc.append(manager)
     manager.run()
예제 #4
0
 def connect(self):
     target = self.target
     if self.extra_args:
         try:
             ssr = target.get_server_list()[int(self.extra_args[0]) - 1]
         except ValueError as e:
             print(e)
             return
     else:
         ssr = target.get_server_list()[0]
     config_from_link = decode_ssrlink(ssr)
     config = shell.parse_config(True, config_from_link)
     target.config = config
     target.server_link = ssr
     print_server_info(target.config, verbose=True, hightlight=True)
     if target.network is None:
         print('creating ClientNetwork')
         target.network = network.ClientNetwork(target.config)
         target.network.start()
     else:
         print('ClientNetwork already exists')
         target.network.add(target.config)
예제 #5
0
    def start(self):
        self.connect_to_service()
        # FIXME: clear exception (SystemExit) when using ctrl-c to exit
        args, extra_args = shell.parse_args()
        if args.command:
            cmd = ' '.join(s for s in sys.argv[1:])
            self.execute(cmd)
            if not args.i:
                time.sleep(1)  # waiting for result to show
                return
            while True:
                time.sleep(0.5)
                cmd = input(">>> ")
                if cmd == '':
                    continue
                if cmd == 'quit' or cmd == 'exit':
                    break
                self.execute(cmd)

        else:  # backward compatibility
            config = shell.parse_config(True)
            self.network = network.ClientNetwork(config)
            self.network.start()
예제 #6
0
def main():
    shell.check_python()

    shell.parse_args()
    config = shell.parse_config(False)

    shell.log_shadowsocks_version()

    daemon.daemon_exec(config)

    try:
        import resource
        logging.info(
            'current process RLIMIT_NOFILE resource: soft %d hard %d' %
            resource.getrlimit(resource.RLIMIT_NOFILE))
    except ImportError:
        pass

    if config['port_password']:
        pass
    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 not config.get('dns_ipv6', False):
        asyncdns.IPV6_CONNECTION_SUPPORT = False

    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(config['workers']) > 1:
        stat_counter_dict = None
    else:
        stat_counter_dict = {}
    port_password = config['port_password']
    config_password = config.get('password', 'm')
    del config['port_password']
    for port, password_obfs in port_password.items():
        method = config["method"]
        protocol = config.get("protocol", 'origin')
        protocol_param = config.get("protocol_param", '')
        obfs = config.get("obfs", 'plain')
        obfs_param = config.get("obfs_param", '')
        bind = config.get("out_bind", '')
        bindv6 = config.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 = config.copy()
        ipv6_ok = False
        logging.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']
                logging.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'] == b"::":
                    ipv6_ok = True
            except Exception as e:
                shell.print_exception(e)

        try:
            a_config = config.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
            logging.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:
                shell.print_exception(e)

    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()