Example #1
0
	def new_server(self, port, user_config):
		ret = True
		port = int(port)
		ipv6_ok = False

		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.update(user_config)
				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'] = a_config['server_ipv6']
				a_config['server_port'] = port
				a_config['max_connect'] = 128
				a_config['method'] = common.to_str(a_config['method'])
				try:
					logging.info("starting server at [%s]:%d" % (common.to_str(a_config['server']), port))

					tcp_server = tcprelay.TCPRelay(a_config, self.dns_resolver, False, stat_counter=self.stat_counter)
					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, stat_counter=self.stat_counter)
					udp_server.add_to_loop(self.loop)
					self.udp_ipv6_servers_pool.update({port: udp_server})

					if common.to_str(a_config['server_ipv6']) == "::":
						ipv6_ok = True
				except Exception as e:
					logging.warn("IPV6 %s " % (e,))

		if 'server' in self.config:
			if port in self.tcp_servers_pool:
				logging.info("server already at %s:%d" % (common.to_str(self.config['server']), port))
				return 'this port server is already running'
			else:
				a_config = self.config.copy()
				a_config.update(user_config)
				a_config['server_port'] = port
				a_config['max_connect'] = 128
				a_config['method'] = common.to_str(a_config['method'])
				try:
					logging.info("starting server at %s:%d" % (common.to_str(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 as e:
					if not ipv6_ok:
						logging.warn("IPV4 %s " % (e,))

		return True
Example #2
0
 def new_server(self, port, user_config):
     port = int(port)
     if 'server' in self.config:
         if port in self.tcp_servers_pool:
             logging.info("server already at %s:%d" %
                          (common.to_str(self.config['server']), port))
             return 'this port server is already running'
         else:
             a_config = self.config.copy()
             a_config.update(user_config)
             a_config['server_port'] = port
             a_config['max_connect'] = 128
             a_config['method'] = common.to_str(a_config['method'])
             try:
                 logging.info("starting server at %s:%d" %
                              (common.to_str(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 as e:
                 logging.warn("IPV4 %s " % (e, ))
     return True
Example #3
0
    def handler():
        config = {
            "password": password,
            "method": crypt_name,
            "server_port": port,
            "timeout": 60,
            "server": "::",
            "fast_open": False
        }

        try:
            loop = eventloop.EventLoop()

            dns_resolver = asyncdns.DNSResolver()
            tcp_server = tcprelay.TCPRelay(config,
                                           dns_resolver,
                                           False,
                                           stat_callback=call_back)
            udp_server = udprelay.UDPRelay(config, dns_resolver, False)

            dns_resolver.add_to_loop(loop)
            tcp_server.add_to_loop(loop)
            udp_server.add_to_loop(loop)

            loop.run()
        except IOError as e:
            if e.errno == 98:
                sys.exit(1)
        except Exception as e:
            shell.print_exception(e)
            sys.exit(1)
Example #4
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']

    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..')
            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)

    run_server()
Example #5
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()
def deployProxy(configs, index):
    config = configs[index]
    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:
        raise
Example #7
0
 def __init__(self, ssconfig, thread_num=0, timeout=1.0):
     super(SSThread, self).__init__()
     self.ssconfig = ssconfig
     self.loop = eventloop.EventLoop()
     self.dns_resolver = asyncdns.DNSResolver()
     self.tcp_server = tcprelay.TCPRelay(self.ssconfig, self.dns_resolver,
                                         True)
     self.udp_server = udprelay.UDPRelay(self.ssconfig, self.dns_resolver,
                                         True)
Example #8
0
def main():
    # Python 2.6+ or Python3.3+
    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

    # only
    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分解器
        dns_resolver = asyncdns.DNSResolver()
        # TCP服务
        tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)
        # UDP服务
        udp_server = udprelay.UDPRelay(config, dns_resolver, True)

        # 将DNS服务、TCP服务、UDP服务加入事件循环
        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)

        # SIGINT是键盘ctrl + c
        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)
Example #9
0
def main():
    global loop
    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)

    daemon.daemon_exec(config)

    utils.print_shadowsocks()

    encrypt.try_cipher(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)

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

        # signal.signal(signal.SIGINT, int_handler)

        loop.run()
        try:
            tcp_server.close(next_tick=True)
            udp_server.close(next_tick=True)
        except:
            pass
    except (KeyboardInterrupt, IOError, OSError) as e:
        import traceback
        traceback.print_exc()
        logging.error(e)
        if config['verbose']:
            import traceback
            traceback.print_exc()
        os._exit(1)
Example #10
0
    def _start_ss(self):
        logging.info("starting local at %s:%d" %
                     (self.config['local_address'], self.config['local_port']))
        print("starting local at %s:%d" %
              (self.config['local_address'], self.config['local_port']))
        dns_resolver = asyncdns.DNSResolver()
        tcp_server = tcprelay.TCPRelay(self.config, dns_resolver, True)
        udp_server = udprelay.UDPRelay(self.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)

        loop.run()
Example #11
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)
Example #12
0
def main():
    shell.check_python()  # 判断python版本

    # fix py2exe
    # hasattr(object, name) 判断一个对象里面是否有name属性或者name方法,返回BOOL值,有name特性返回True, 否则返回False。
    if hasattr(sys, "frozen") and sys.frozen in \
            ("windows_exe", "console_exe"):
        # sys.executable python可执行文件的绝对路径
        # os.path.abspath(path) 返回绝对路径
        # os.path.dirname(path) 返回文件路径
        # os.chdir() 用于改变当前工作目录到指定的路径
        p = os.path.dirname(os.path.abspath(sys.executable))
        os.chdir(p)

    # 获取配置字典,包含每个配置项的具体配置值
    config = shell.get_config(True)
    # 根据配置文件当中的关键字daemon决定程序是启动/停止/重启
    daemon.daemon_exec(config)

    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)
Example #13
0
 def add_port(self, config):
     port = int(config['server_port'])
     servers = self._relays.get(port, None)
     if servers:
         logging.error("Server Exists:  P[%d], M[%s], E[%s]" %
                       (port, config['method'], config['email']))
         return
     logging.info("Server Added:   P[%d], M[%s], E[%s]" %
                  (port, config['method'], config['email']))
     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)
Example #14
0
    def add_server(self, user_config):
        config = self._config.copy()
        config.update(user_config)
        port = int(config['server_port'])
        if port in self._relays:
            logging.error("server already at %s:%d" % (config['server'], port))
            return False

        logging.info("add 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)
        return True
Example #15
0
    def add_port(self, config):
        a_config = self._config.copy()
        a_config.update(config)
        port = int(a_config['server_port'])
        servers = self._relays.get(port, None)
        if servers:
            logging.error("server already exists at %s:%d" % (a_config['server'],port))
            return False
        logging.info("adding server at %s:%d" % (a_config['server'], port))
        t = tcprelay.TCPRelay(a_config, self._dns_resolver, False,
                              self.stat_callback)
        u = udprelay.UDPRelay(a_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, a_config['username'], a_config['password'], a_config['method'])

        return True
Example #16
0
def main():
    # 检查 python 版本
    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)  # 读取配置文件是否开启进程守护, 仅在UNIX ,Linux 上有效

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

        dns_resolver = asyncdns.DNSResolver()   # 创建dns 查询对象
        tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)  # 创建 TCP 代理转发对象
        udp_server = udprelay.UDPRelay(config, dns_resolver, True)  # 创建 UDP 代理转发对象
        loop = eventloop.EventLoop()    # 创建事件处理对象
        # 将dns查询、tcp代理方式转发、udp代理方式转发绑定到事件循环
        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)  # "Ctrl + C" 中断指令

        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)
Example #17
0
def run(config):
    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)

    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)

    loop.run()
Example #18
0
 def add_port(self, config):
     port = int(config['server_port'])
     servers = self._relays.get(port, None)
     if servers:
         logging.error("Server Exists:  P[%d], M[%s], E[%s]" % (
             port, config['method'], config['email']))
         return
     # Check if AEAD cipher is enforced
     if config['aead_enforcement'] and config['method'] not in aead_ciphers:
         logging.warning("AEAD Cipher Enforced - Rejected Server: P[%d], M[%s], E[%s]" % (
             port, config['method'], config['email']))
         return
     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)
     logging.info("Server Added:   P[%d], M[%s], E[%s]" %
                  (port, config['method'], config['email']))
Example #19
0
    def stopOnUnix(self, ssrDict, *args):
        ssrDict['daemon'] = 'stop'
        ssrDict['local_address'] = args[0]
        ssrDict['local_port'] = args[1]
        ssrDict['timeout'] = args[2]
        ssrDict['workers'] = args[3]
        ssrDict['pid-file'] = args[4]
        ssrDict['log-file'] = args[5]
        if not ssrDict.get('dns_ipv6', False):
            asyncdns.IPV6_CONNECTION_SUPPORT = False
        try:
            daemon.daemon_exec(ssrDict)
            dns_resolver = asyncdns.DNSResolver()
            tcp_server = tcprelay.TCPRelay(ssrDict, dns_resolver, True)
            udp_server = udprelay.UDPRelay(ssrDict, 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, _):
                logger.info('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, _):
                logger.info("ShadowsocksR is stop")
                sys.exit(1)

            signal.signal(signal.SIGINT, int_handler)
            daemon.set_user(ssrDict.get('user', None))
            logger.info('ShadowsocksR is start on {0}:{1}'.format(args[0], args[1]))
            loop.run()
        except Exception as e:
            logger.error(e)
            sys.exit(1)
Example #20
0
    def add_port(self, config):
        """
        添加服务端口,并保持只有一个服务端,同时监听tcp和udp的数据包

        :param config: 配置信息

        :return: 如果已存在服务端则返回
        """

        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)
Example #21
0
def daemon_embeded(config):

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

    daemon.set_user(config.get('user', None))
    loop.run()
Example #22
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.get('server_port', None)
        if 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'])
    else:
        dns_resolver = asyncdns.DNSResolver()

    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()
Example #23
0
def main():
    shell.check_python3()

    config = shell.get_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()
Example #24
0
def main():
    shell.check_python()  #检查python版本

    config = shell.get_config(False)  #从配置文件,命令行等获取参数

    daemon.daemon_exec(config)  #根据'daemon'参数来start,stop或restart ssserver

    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 = []
    # 类DNSResolver初始化时会从/etc/hosts和/etc/resolv.conf中获取hostname和dns
    dns_resolver = asyncdns.DNSResolver()
    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..')
            # map(function, sequence[, sequence, ...]) -> list 将function函数作用到
            # sequence中的每一个元素,也就是关掉上面打开的所有的socket
            list(
                map(lambda s: s.close(next_tick=True),
                    tcp_servers + udp_servers))

        # 注册SIGQUIT或SIGTERM的信号处理函数,Windows不支持SIGQUIT而Linux支持,所以为了
        # 跨平台兼容,此处使用了getattr函数
        # 在调用exec前,子进程会继承父进程注册的信号处理action,这里在子进程中重新注册
        # 了SIGTERM信号的处理action,不出意外,signal函数会返回上一次注册的action
        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
                      child_handler)

        # 为SIGINT注册信号处理函数
        def int_handler(signum, _):
            sys.exit(1)

        signal.signal(signal.SIGINT, int_handler)

        try:
            loop = eventloop.EventLoop()
            # 将dns以及之前tcp, udp的socket都注册到epoll事件表中
            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()
Example #25
0
def main():
    # 检查python版本
    utils.check_python()

    # fix py2exe
    # 应该是专门为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)

    # 形参是is_local=True
    config = utils.get_config(True)

    # linux系统:执行守护进程
    daemon.daemon_exec(config)
    # 显示当前的ss版本号
    utils.print_shadowsocks()
    # 创建加密器类的实例
    encrypt.try_cipher(config['password'], config['method'])

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

        # dns只是tcp上面的一个应用,所以没有自己的bind
        # 新建dns_resolver
        dns_resolver = asyncdns.DNSResolver()
        tcp_server = tcprelay.TCPRelay(config, dns_resolver, True)
        udp_server = udprelay.UDPRelay(config, dns_resolver, True)
        # 创建时间循环的类实例
        loop = eventloop.EventLoop()
        # dns请求报文发出去了之后要监测响应报文
        dns_resolver.add_to_loop(loop)  # client发远程网站地址给proxy,proxy去查找DNS
        tcp_server.add_to_loop(loop)  # 递送tcp数据
        udp_server.add_to_loop(loop)  # 递送udp数据

        # 定义退出信号捕获处理函数
        def handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            #  连带关闭socket(因为next = true)
            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)

        # 运行事件循环,思想还是挺高端的
        loop.run()

    # 按下 Ctrl+c 退出
    except (KeyboardInterrupt, IOError, OSError) as e:
        logging.error(e)
        if config['verbose']:
            import traceback
            traceback.print_exc()
        os._exit(1)
Example #26
0
def main():
    # 检查python版本
    shell.check_python()
   
    config = shell.get_config(False)    # 获取配置文件,其中参数False 是标识符is_local的假值,表示要获取非local配置

    daemon.daemon_exec(config)          # 检查配置是否要开启进程守护,仅在UNIX, Linux 上有效
    # 多用户分配设置处理
    if config['port_password']:
        if config['password']:
            logging.warning('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 = []
    dns_resolver = asyncdns.DNSResolver()   # 创建DNS查询对象
    port_password = config['port_password'] # 获取
    del config['port_password']             # 删除config 字典中的"port_password"键
    # 将多用户配置转换为单用户配置
    for port, password in port_password.items():
        a_config = config.copy()
        a_config['server_port'] = int(port) # 创建"server_port"键
        a_config['password'] = password # 创建"password"键
        logging.info("starting server at %s:%d" % (a_config['server'], int(port)))  # 记录服务开启
        tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False))    # 添加TCP查询对象,TCP代理实现
        udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False))    # 添加UDP查询对象

    # 开启服务
    def run_server():
        def child_handler(signum, _):
            logging.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)  # 将DNS绑定到事件循环
            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()
Example #27
0
def main():
    shell.check_python()
    # 获取配置文件,如果没有配置文件将给与默认的配置,配置如下
    """
    {
    "server": "0.0.0.0",
    "server_ipv6": "::",
    "server_port": 8388,
    "local_address": "127.0.0.1",
    "local_port": 1080,
    "password": "******",
    "timeout": 120,
    "udp_timeout": 60,
    "method": "aes-256-cfb",
    "protocol": "origin",
    "protocol_param": "",
    "obfs": "http_simple_compatible",
    "obfs_param": "",
    "dns_ipv6": false,
    "connect_verbose_info": 0,
    "redirect": "",
    "fast_open": false
    }
    """
    config = shell.get_config(False)

    daemon.daemon_exec(config)

    # 写了port_password的配置
    if config['port_password']:
        # 用了password就不用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:
        # 没有写入port_password配置的情况
        config['port_password'] = {}
        server_port = config['server_port']
        # 判断服务器端口是否为一个数组是的话就,使用password作为密码的放在port_password中
        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']
            # 组装完如下
            # """
            #     port_password:{
            #         port:password
            #     }
            # """
    # 是否启动了dns_ipv6
    if not config.get('dns_ipv6', False):
        asyncdns.IPV6_CONNECTION_SUPPORT = False

    # 使用启用了管理者
    # if config.get('manager', 0):
    #     logging.info('entering manager mode')
    #     # 判断是否使用管理者????这里我也还没有看源码
    #     manager.run(config)
    #     return

    tcp_servers = []
    udp_servers = []
    dns_resolver = asyncdns.DNSResolver()
    port_password = config['port_password']
    # 删除port_password这个数据
    del config['port_password']
    for port, password_obfs in port_password.items():
        # 默认参数
        # 加密方式
        method = config.get("method", 'aes-256-cfb')
        # 用户密码
        password = config.get("password", 'password')
        # 协议加密
        protocol = config.get("protocol", 'origin')
        # 混淆方式
        obfs = config.get("obfs","plain")
        # 获取混淆参数
        obfs_param = config.get("obfs_param", '')
        # 判断是否是一个数组,格式如下
        """ 
        port_password:{
            port:['password','obfs'],
            port:['password','obfs'],
            ....
        }
        """
        if type(password_obfs) == list:
            password = password_obfs[0]
            obfs = password_obfs[1]
        elif type(password_obfs) == dict:
            # 字典的情况下,格式如下
            """ 
            port_password:{
                port:{
                    password:password,
                    protocol:protocol,
                    obfs:obfs,
                    obfs_param:obfs_param
                },
                ....
            }
            """
            # 如果是1的话表示无效的状态0表示正常
            if password_obfs.get("flowMark",0) == 1 or password_obfs.get("dateMark",0) == 1:
                continue
            # 密码
            password = password_obfs.get('password', 'm')
            # 协议
            protocol = password_obfs.get('protocol', 'origin')
            # 协议参数
            protocol_param = password_obfs.get('protocol_param', '')
            # 混淆方式
            obfs = password_obfs.get('obfs', 'plain')
            # 混淆参数
            obfs_param = password_obfs.get('obfs_param', '')
            # 获取加密方式
            method = password_obfs.get("method", 'aes-256-cfb')
        else:
            password = password_obfs
            obfs = config["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, a_config['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'] = a_config['server_ipv6']
                a_config['server_port'] = port
                a_config['password'] = password
                a_config['protocol'] = protocol
                a_config['protocol_param'] = protocol_param
                a_config['obfs'] = obfs
                a_config['obfs_param'] = obfs_param
                a_config['method'] = method
                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))
                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'] = port
            a_config['password'] = password
            a_config['protocol'] = protocol
            a_config['protocol_param'] = protocol_param
            a_config['obfs'] = obfs
            a_config['obfs_param'] = obfs_param
            a_config['method'] = method
            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))
        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()
Example #28
0
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.try_cipher(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..')
            list(
                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)
            list(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 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)
                        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()
Example #29
0
def main():
    utils.check_python()

    # is_local=false
    config = utils.get_config(False)

    daemon.daemon_exec(config)

    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']

    # Create an instance of the cipher class
    encrypt.try_cipher(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、udp列表
        tcp_servers.append(tcprelay.TCPRelay(a_config, dns_resolver, False))
        udp_servers.append(udprelay.UDPRelay(a_config, dns_resolver, False))

    def run_server():
        # 收到退出信号的处理函数,关闭所有socket释放资源。
        def child_handler(signum, _):
            logging.warn('received SIGQUIT, doing graceful shutting down..')
            # 关闭所有的socket,一句话搞定,好厉害,跪拜ing
            # map(function, sequence[, sequence, ...]) -> list
            # Return a list of the results of applying the function to the items of the argument sequence(s).
            list(
                map(lambda s: s.close(next_tick=True),
                    tcp_servers + udp_servers))

        # 收到退出信号,调用child_handler进行自杀。
        signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM),
                      child_handler)

        # 收到退出信号,调用int_handler进行自杀。
        def int_handler(signum, _):
            sys.exit(1)

        signal.signal(signal.SIGINT, int_handler)

        try:
            loop = eventloop.EventLoop()
            dns_resolver.add_to_loop(loop)
            # 把所有的监听端口添加到时间循环中,一句话搞定,好厉害,跪拜ing
            list(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)

    # Shadowsocks supports spawning child processes like nginx.
    # You can use --workers to specify how many workers to use.
    # This argument is only supported on Unix and ssserver.
    # Currently UDP relay does not work well on multiple workers.
    # 支持像nginx多进程,可以在config中指定worker的数量。仅在linux下生效。
    # 目前的bug:worker设为大于1时,udp转发有可能工作不正常
    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()
Example #30
0
def main():
    logging.basicConfig(
        level=logging.DEBUG,
        format=
        '%(levelname)-4s:%(filename)s %(lineno)d %(funcName)s %(message)s')
    logging.info("main exec...")

    # a = "123456"
    # b = []
    # b.append(a)
    #
    # logging.info("a:%s" % a[2:])
    # logging.info("b:%s" % type(b))
    #
    # s = utils.encode(b[0])
    # logging.info(s)
    # b = utils.decode(s)
    # logging.info(b)

    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:
                logging.info('a_server_port:%s' % str(a_server_port))
                config['port_password'][a_server_port] = config['password']
        else:
            logging.info('server_port:%s' % str(server_port))
            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
        logging.info("dns_server in config")
        dns_resolver = asyncdns.DNSResolver(config['dns_server'],
                                            config['prefer_ipv6'])
    else:
        logging.info("dns_server not in config")
        dns_resolver = asyncdns.DNSResolver(prefer_ipv6=config['prefer_ipv6'])

    port_password = config['port_password']
    logging.info("port_password:%s" % str(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))

    logging.info('config type:' + str(type(config)))

    def run_server():
        logging.info("run_server enters")

        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
                    logging.info("run_server enters - 3")
                    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')
            logging.info("call run_server - 1")
            run_server()
    else:
        logging.info("call run_server enters - 2")
        run_server()