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 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)
def main(): shell.check_python() config = shell.get_config(False) daemon.daemon_exec(config) daemon.set_user(config.get('user', None)) thread.start_new_thread(db_transfer.DbTransfer.thread_db, ()) while True: time.sleep(99999)
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) 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, stat_callback=stat_handler) a_config = config.copy() if a_config.get('port_password', None): a_config['server_port'] = random.choice( a_config['port_password'].keys()) a_config['password'] = a_config['port_password']\ [a_config['server_port']] udp_server = udprelay.UDPRelay(a_config, dns_resolver, True, stat_callback=stat_handler) 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)) t = threading.Thread(target=monitor, args=(), name='monitor') t.daemon = True t.start() loop.run() except Exception as e: shell.print_exception(e) sys.exit(1)
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) daemon.daemon_exec(config) # # host = config['server']# 测试时候使用 # port = config['server_port'] # s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # s.connect((host, port)) 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 = 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..') 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() except (KeyboardInterrupt, IOError, OSError) as e: logging.error(e) if config['verbose']: import traceback traceback.print_exc() os._exit(1)
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) 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 is only a application on TCP, so it does not has its own bind dns_resolver = asyncdns.DNSResolver() tcp_server = tcprelay.TCPRelay(config, dns_resolver, True) udp_server = udprelay.UDPRelay(config, dns_resolver, True) loop = eventloop.EventLoop() # dns请求报文发出去了之后要监测响应报文 # listen the response after dns query is sent dns_resolver.add_to_loop(loop) # The proxy will find the DNS after the client send the address of dest website tcp_server.add_to_loop(loop) # Send tcp data udp_server.add_to_loop(loop) # Send udp data 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() except (KeyboardInterrupt, IOError, OSError) as e: logging.error(e) if config['verbose']: import traceback traceback.print_exc() os._exit(1)
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) 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() except (KeyboardInterrupt, IOError, OSError) as e: logging.error(e) if config["verbose"]: import traceback traceback.print_exc() os._exit(1)
def main(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) # 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)
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) 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) # 注册信号事件,用于结束 local 程序 signal.signal(getattr(signal, 'SIGQUIT', signal.SIGTERM), handler) def int_handler(signum, _): sys.exit(1) # SIGINT external interrupt, usually initiated by the user 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)
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)
def main(): shell.check_python() config = shell.get_config() daemon.daemon_exec(config) tcp_servers = [] udp_servers = [] dns_resolver = asyncdns.DNSResolver() a_config = config.copy() logging.info("starting bridge at %s:%d" % (a_config['local'], int(a_config['local_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) #add tcp_servers into event loop,when a call is in,it will be invoked. 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()
def new_runSS(): """An effective way to start shadowsocks server with all the outputs of it redirected into a log file named `shadowsocks.log` under `~/.sspy-mgr/logs`. """ import logging fileHandler = createLoggerFile('shadowsocks') logger = logging.getLogger() logger.addHandler(fileHandler) logger.setLevel(logging.INFO) from shadowsocks import shell, daemon, eventloop, manager logger.info('Start running shadowsock server') shell.check_python() logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') config_path = ssConfigFile() logger.info(tr('Loading configuration from {}').format(config_path)) with open(config_path, 'rb') as f: try: config = shell.parse_json_in_str(f.read().decode('utf8')) except ValueError as e: logger.error("found an error in config.json: {}".format(e.message)) sys.exit(1) config['manager_address'] = ssAddr(True) config['port_password'] = {} config['server_port'] = 0 config['verbose'] = 2 config['method'] = 'aes-256-cfb' daemon.daemon_exec(config) 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'] logger.info('entering manager mode') manager.run(config)
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) 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) # 注册信号事件,用于结束 local 程序 signal.signal(getattr(signal, "SIGQUIT", signal.SIGTERM), handler) def int_handler(signum, _): sys.exit(1) # SIGINT external interrupt, usually initiated by the user 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)
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) dns_resolver = asyncdns.DNSResolver() loop = eventloop.EventLoop() dns_resolver.add_to_loop(loop) _config = config.copy() _config["local_port"] = _config["tunnel_port"] logging.info("starting tcp tunnel at %s:%d forward to %s:%d" % (_config['local_address'], _config['local_port'], _config['tunnel_remote'], _config['tunnel_remote_port'])) tunnel_tcp_server = tcprelay.TCPRelay(_config, dns_resolver, True) tunnel_tcp_server._is_tunnel = True tunnel_tcp_server.add_to_loop(loop) logging.info("starting udp tunnel at %s:%d forward to %s:%d" % (_config['local_address'], _config['local_port'], _config['tunnel_remote'], _config['tunnel_remote_port'])) tunnel_udp_server = udprelay.UDPRelay(_config, dns_resolver, True) tunnel_udp_server._is_tunnel = True tunnel_udp_server.add_to_loop(loop) def handler(signum, _): logging.warn('received SIGQUIT, doing graceful shutting down..') tunnel_tcp_server.close(next_tick=True) tunnel_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 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)
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) 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) loop.run() except (KeyboardInterrupt, IOError, OSError) as e: logging.error(e) if config['verbose']: import traceback traceback.print_exc() os._exit(1)
def new_runSS(): import logging fileHandler = createLoggerFile('shadowsocks') logger = logging.getLogger() logger.addHandler(fileHandler) logger.setLevel(logging.INFO) from shadowsocks import shell, daemon, eventloop, manager logger.info('Start running shadowsock server') shell.check_python() logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') config_path = ssConfigFile() logger.info('loading config from %s' % config_path) with open(config_path, 'rb') as f: try: config = shell.parse_json_in_str(f.read().decode('utf8')) except ValueError as e: logger.error('found an error in config.json: %s', e.message) sys.exit(1) config['manager_address'] = ssAddr(True) config['port_password'] = {} config['server_port'] = 0 config['verbose'] = 2 config['method'] = 'aes-256-cfb' daemon.daemon_exec(config) 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'] logger.info('entering manager mode') manager.run(config)
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)
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'])) if 'upstream' in config: RoundRobin.init(config['upstream'][:]) 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 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()
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()
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)
def main(): utils.check_python() 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'] 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) 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)) 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) 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()
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()
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) logging.warn('!' * 30) if config.has_key('server_info'): if config['server_info'].has_key(config['server']): logging.info( "OK.. [ (ip: %s) (server_port: %s) (password: %s) (server_info: %s) (method: %s) ]" % (config['server'], config['server_port'], config['password'], config['server_info']["%s" % config['server']], config['method'])) else: logging.info( "OK.. [ (ip: %s) (server_port: %s) (password: %s) (method: %s) ]" % (config['server'], config['server_port'], config['password'], config['method'])) else: logging.info( "OK.. [ (ip: %s) (server_port: %s) (password: %s) (method: %s) ]" % (config['server'], config['server_port'], config['password'], 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)
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()
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 = [] # 创建一个dns解析对象 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、udp列表 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..') # 关闭所有的socket,lambda表达式一句话搞定 # 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)) 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) # 把所有的监听端口添加到事件循环loop中,lambda表达式一句话搞定 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) # 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()
def main(): """ 启动服务器主函数 :return: None """ 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: # 给每个port赋password for a_server_port in server_port: config['port_password'][a_server_port] = config['password'] else: # 只有1个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 = [] 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(): """ 服务器运行 :return: None """ def child_handler(signum, _): """ 子程序要求关闭 :param signum: 信号值 :param _: 不明 :return: None """ 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, _): """ 强制退出程序,意义不明 :param signum: 信号值 :param _: 不明 :return: None """ sys.exit(1) signal.signal(signal.SIGINT, int_handler) try: loop = eventloop.EventLoop() # 用addtoloop把dnsresolver添加到eventloop里,当DNSResolver对应的socket有dns解析结果可以读取的时候,eventloop会自动调用其handle_event方法将就绪的socket递给DNSResolver,DNSResolver就可以从其中读取dns应答数据了。 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) # workers<=1时开启服务器,>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, _): """ 关闭所有子进程 :param signum: 信号值 :param _: 不明 :return: None :raises OSError: 子进程已经退出 """ 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) # 关闭所有服务器 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()
with_statement import sys import os import time import logging import signal import json sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../')) from shadowsocks import shell, daemon, eventloop, tcprelay, udprelay, \ asyncdns, manager, agent shell.check_python() config = shell.get_config(False) daemon.daemon_exec(config) agent_ = agent.Agent(config) worker_id = 0 workers = 1 tcp_servers = [] udp_servers = [] dns_resolver = 0 #load server config def init_config(): global tcp_servers, udp_servers, dns_resolver, workers, worker_id tcp_servers = [] udp_servers = [] dns_resolver = asyncdns.DNSResolver()
def main(): shell.check_python() 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 = password_obfs[1] if len(password_obfs) > 2: protocol = password_obfs[2] elif type(password_obfs) == dict: password = password_obfs.get('password', config_password) method = password_obfs.get('method', method) protocol = password_obfs.get('protocol', protocol) protocol_param = password_obfs.get('protocol_param', protocol_param) obfs = password_obfs.get('obfs', obfs) obfs_param = password_obfs.get('obfs_param', obfs_param) bind = password_obfs.get('bind', bind) bindv6 = password_obfs.get('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, 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_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()
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()
def main(): utils.check_python() 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'] 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) os.waitpid(pid, 0) 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()
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()
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()
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()
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()
def main(): shell.check_python() # 读取 config = shell.get_config(False) # TODO 临时打印配置信息 print(config) # 根据配置对守护进程进行操作,不开启 daemon 时此处可忽略 daemon.daemon_exec(config) """ port_password 为一个字典,每个端口有不同的密码,用于多用户登录 "port_password": { "8381": "foobar1", "8382": "foobar2", } """ 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'] # TODO 如果获取到 manager_address,则启动管理进程,先跳过不看 if config.get('manager_address', 0): logging.info('entering manager mode') manager.run(config) return tcp_servers = [] udp_servers = [] # 如果设置了 dns 服务器 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 时,也会退化到使用 port_password,此时 port_password 为单元素列表 port_password = config['port_password'] # TODO 为什么要删除 del config['port_password'] # 循环每一对端口和密码 for port, password in port_password.items(): # dict.copy() 创建了一个新的字典对象,内容一样 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) # 如果 workers 为 1 则直接启动 server,否则进行 fork() 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()
def main(): shell.check_python() # 读取配置信息,False 表示这里是服务端运行 config = shell.get_config(False) # TODO 临时打印配置信息 print(config) """ 默认配置信息 { 'log-file': '/var/log/shadowsocks.log', 'verbose': False, 'local_port': 1080, 'workers': 1, 'fast_open': False, 'forbidden_ip': <shadowsocks.common.IPNetwork object at 0x10f4f8a10>, 'server': '0.0.0.0', 'port_password': None, 'server_port': None, 'timeout': 300, 'local_address': '127.0.0.1', 'pid-file': '/var/run/shadowsocks.pid', 'password': '', 必填 'method': 'aes-256-cfb' } """ # 根据配置对守护进程进行操作,不开启 daemon 时此处可忽略 daemon.daemon_exec(config) """ port_password 为一个字典,每个端口有不同的密码,用于多用户登录 "port_password": { "8381": "foobar1", "8382": "foobar2", } """ 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'] = {} # TODO 待确认 # 此处应为 server_port = config.get('server_port', 8388) 以允许默认端口启动 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'] print(config) # 如果获取到 manager_address,则启动管理进程 if config.get('manager_address', 0): logging.info('entering manager mode') manager.run(config) return tcp_servers = [] udp_servers = [] # 如果设置了 dns 服务器 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 时,也会退化到使用 port_password,此时 port_password 为单元素列表 port_password = config['port_password'] # 后面用 port_password 中每一项分别生成一份配置,所以 config['port_password'] 就用不着了 del config['port_password'] # 循环每一对端口和密码 for port, password in port_password.items(): # dict.copy() 创建了一个新的字典对象,内容一样 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 的 Relay 实例 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)) """ getattr(object, name[, default]) 如果 siganl.SIGQUIT 不存在,即注册 SIGTERM 事件 SIGTERM 终止进程,但终止前会允许 handler 被执行,SIGKILL 不会 SIGQUIT 在 SIGTERM 的基础上,还生成了一份 core dump 文件记录了进程信息 http://programmergamer.blogspot.jp/2013/05/clarification-on-sigint-sigterm-sigkill.html """ 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 解析器到事件循环中 dns_resolver.add_to_loop(loop) # 批量地将所有 tcp_server 和 udp_server 加入事件循环中 list(map(lambda s: s.add_to_loop(loop), tcp_servers + udp_servers)) # 使守护进程以设置中 user 的名义执行 daemon.set_user(config.get('user', None)) # 启动事件循环 loop.run() except Exception as e: shell.print_exception(e) sys.exit(1) # 如果 workers 为 1 则直接启动 server,否则进行 fork() if int(config['workers']) > 1: if os.name == 'posix': children = [] is_child = False for i in range(0, int(config['workers'])): r = os.fork() # 如果执行这段代码的进程为子进程,输出启动信息,然后运行 run_server() if r == 0: logging.info('worker started') is_child = True run_server() break else: # 如果为父进程,添加到 pid 到子进程列表中 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() # 当收到中断或者终止信号时,向每个子进程 pid 发出终止信号 signal.signal(signal.SIGTERM, handler) signal.signal(signal.SIGQUIT, handler) signal.signal(signal.SIGINT, handler) # master # 关闭所有 tcp_server,udp_server 和 dns 解析器 # close 方法从 eventloop 中移除了每个注册的事件 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: # TODO 待测试 # 等待子进程结束,当子进程结束时返回 os.waitpid(child, 0) else: logging.warn('worker is only available on Unix/Linux') run_server() else: run_server()