From 6ef66f53c6c44224eec79c2897efc14b9bc878c6 Mon Sep 17 00:00:00 2001 From: Jason Lai Date: Sat, 24 Jun 2017 01:30:22 +0800 Subject: [PATCH 1/2] fix `TypeError: a bytes-like object is required, not "str"` error when handling manager_address argument in the Manager.__init__ method of the manager module --- shadowsocks/manager.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shadowsocks/manager.py b/shadowsocks/manager.py index 62f187e..12816be 100644 --- a/shadowsocks/manager.py +++ b/shadowsocks/manager.py @@ -45,6 +45,8 @@ class Manager(object): self._control_client_addr = None try: manager_address = config['manager_address'] + if hasattr(manager_address, 'decode'): + manager_address = manager_address.decode('utf-8') if ':' in manager_address: addr = manager_address.rsplit(':', 1) addr = addr[0], int(addr[1]) From 06803f3b8082336b9063f44b253d814d4fc08d9b Mon Sep 17 00:00:00 2001 From: Jason Lai Date: Sat, 24 Jun 2017 12:23:18 +0800 Subject: [PATCH 2/2] add `list` command to the manager module --- shadowsocks/manager.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) mode change 100644 => 100755 shadowsocks/manager.py diff --git a/shadowsocks/manager.py b/shadowsocks/manager.py old mode 100644 new mode 100755 index 12816be..3014e33 --- a/shadowsocks/manager.py +++ b/shadowsocks/manager.py @@ -109,6 +109,14 @@ class Manager(object): logging.error("server not exist at %s:%d" % (config['server'], port)) + def list_port(self): + data_list = list(self._relays.keys()) + # use compact JSON format (without space) + data = common.to_bytes(json.dumps(data_list, + separators=(',', ':'))) + rv = b'ports: ' + data + return rv + def handle_event(self, sock, fd, event): if sock == self._control_socket and event == eventloop.POLL_IN: data, self._control_client_addr = sock.recvfrom(BUF_SIZE) @@ -128,6 +136,9 @@ class Manager(object): elif command == 'remove': self.remove_port(a_config) self._send_control_data(b'ok') + elif command == 'list': + msg = self.list_port() + self._send_control_data(msg) elif command == 'ping': self._send_control_data(b'pong') else: @@ -216,6 +227,7 @@ def test(): def run_server(): config = { 'server': '127.0.0.1', + 'server_port': 33379, 'local_port': 1081, 'port_password': { '8381': 'foobar1', @@ -238,7 +250,7 @@ def test(): cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cli.connect(('127.0.0.1', 6001)) - # test add and remove + # test list, add and remove time.sleep(1) cli.send(b'add: {"server_port":7001, "password":"asdfadsfasdf"}') time.sleep(1) @@ -246,6 +258,13 @@ def test(): data, addr = cli.recvfrom(1506) assert b'ok' in data + cli.send(b'list') + time.sleep(1) + data, addr = cli.recvfrom(1506) + assert b'7001' in data + assert b'8381' in data + assert b'8382' in data + cli.send(b'remove: {"server_port":8381}') time.sleep(1) assert 8381 not in manager._relays @@ -253,8 +272,15 @@ def test(): assert b'ok' in data logging.info('add and remove test passed') + cli.send(b'list') + time.sleep(1) + data, addr = cli.recvfrom(1506) + assert b'7001' in data + assert b'8381' not in data + assert b'8382' in data + # test statistics for TCP - header = common.pack_addr(b'google.com') + struct.pack('>H', 80) + header = common.pack_addr(b'baidu.com') + struct.pack('>H', 80) data = cryptor.encrypt_all(b'asdfadsfasdf', 'aes-256-cfb', header + b'GET /\r\n\r\n') tcp_cli = socket.socket()