From 285dc407294adfe1d3ce4107530f4259869b0701 Mon Sep 17 00:00:00 2001 From: jsy Date: Mon, 11 Jan 2016 23:47:47 +0800 Subject: [PATCH 01/14] here? --- tests/test_daemon.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_daemon.sh b/tests/test_daemon.sh index 40f35ef..1acddc0 100755 --- a/tests/test_daemon.sh +++ b/tests/test_daemon.sh @@ -18,7 +18,7 @@ function run_test { for module in local server do -command="coverage run -p -a shadowsocks/$module.py" +command="coverage run -a shadowsocks/$module.py" mkdir -p tmp From ab4206258775d494e86aba03a2aa5c990c96a625 Mon Sep 17 00:00:00 2001 From: jsy Date: Mon, 11 Jan 2016 23:57:18 +0800 Subject: [PATCH 02/14] Can't append to data files in parallel mode. --- tests/test_command.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_command.sh b/tests/test_command.sh index be05704..8225740 100755 --- a/tests/test_command.sh +++ b/tests/test_command.sh @@ -2,7 +2,7 @@ . tests/assert.sh -PYTHON="coverage run -a -p" +PYTHON="coverage run -a" LOCAL="$PYTHON shadowsocks/local.py" SERVER="$PYTHON shadowsocks/server.py" From 4786b9c3addd2b16664af20d53f8e08b498d013b Mon Sep 17 00:00:00 2001 From: jsy Date: Tue, 12 Jan 2016 00:03:13 +0800 Subject: [PATCH 03/14] Can't append to data files in parallel mode. --- tests/test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test.py b/tests/test.py index 29b57d4..85bd007 100755 --- a/tests/test.py +++ b/tests/test.py @@ -44,7 +44,7 @@ parser.add_argument('--dns', type=str, default='8.8.8.8') config = parser.parse_args() if config.with_coverage: - python = ['coverage', 'run', '-p', '-a'] + python = ['coverage', 'run', '-a'] client_args = python + ['shadowsocks/local.py', '-v'] server_args = python + ['shadowsocks/server.py', '-v'] From 3788df59bbd629fd4f38e219e6581678d6df276a Mon Sep 17 00:00:00 2001 From: jsy Date: Tue, 12 Jan 2016 00:04:40 +0800 Subject: [PATCH 04/14] Can't append to data files in parallel mode. --- tests/test_graceful_restart.sh | 2 +- tests/test_large_file.sh | 2 +- tests/test_udp_src.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_graceful_restart.sh b/tests/test_graceful_restart.sh index d91ba92..eb4bc0f 100755 --- a/tests/test_graceful_restart.sh +++ b/tests/test_graceful_restart.sh @@ -1,6 +1,6 @@ #!/bin/bash -PYTHON="coverage run -p -a" +PYTHON="coverage run -a" URL=http://127.0.0.1/file diff --git a/tests/test_large_file.sh b/tests/test_large_file.sh index 33bcb59..7a6aec8 100755 --- a/tests/test_large_file.sh +++ b/tests/test_large_file.sh @@ -1,6 +1,6 @@ #!/bin/bash -PYTHON="coverage run -p -a" +PYTHON="coverage run -a" URL=http://127.0.0.1/file mkdir -p tmp diff --git a/tests/test_udp_src.sh b/tests/test_udp_src.sh index d356581..4a07a23 100755 --- a/tests/test_udp_src.sh +++ b/tests/test_udp_src.sh @@ -1,6 +1,6 @@ #!/bin/bash -PYTHON="coverage run -p -a" +PYTHON="coverage run -a" mkdir -p tmp From 9f3641db546121b6e120320871a5e6b9f1f99566 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 00:27:46 +0800 Subject: [PATCH 05/14] url ssl timeout --- tests/jenkins.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/jenkins.sh b/tests/jenkins.sh index 5b53e93..dc583ba 100755 --- a/tests/jenkins.sh +++ b/tests/jenkins.sh @@ -51,7 +51,7 @@ run_test python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 1 run_test python tests/test.py --with-coverage --should-fail --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=127.0.0.1,::1,8.8.8.8" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" # test if DNS works -run_test python tests/test.py --with-coverage -c tests/aes.json --url="https://clients1.google.com/generate_204" +run_test python tests/test.py --with-coverage -c tests/aes.json --url="https://www.google.com/" # test localhost is in the forbidden list by default run_test python tests/test.py --with-coverage --should-fail --tcp-only --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" From d2f1caeb5d3458efe602878a6a94be5792b80629 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 01:03:25 +0800 Subject: [PATCH 06/14] fixbug: when ota disable data not write --- shadowsocks/tcprelay.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index cb3c413..20517c2 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -242,6 +242,8 @@ class TCPRelayHandler(object): if self._ota_enable: self._ota_chunk_data(data, self._data_to_write_to_remote.append) + else: + self._data_to_write_to_remote.append(data) if self._is_local and not self._fastopen_connected and \ self._config['fast_open']: # for sslocal and fastopen, we basically wait for data and use @@ -475,6 +477,8 @@ class TCPRelayHandler(object): else: if self._ota_enable: self._ota_chunk_data(data, self._write_to_sock_remote) + else: + self._write_to_sock(data, self._remote_sock) return def _on_local_read(self): From efad7578375cad323b5704c6827ad482fcc0f437 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 01:44:18 +0800 Subject: [PATCH 07/14] 9001 not idle? --- tests/test_udp_src.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_udp_src.py b/tests/test_udp_src.py index e8fa505..50af385 100644 --- a/tests/test_udp_src.py +++ b/tests/test_udp_src.py @@ -72,8 +72,8 @@ if __name__ == '__main__': sock_in1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.SOL_UDP) - sock_in1.bind(('::1', 9001)) - sock_out.sendto(b'data', ('::1', 9001)) + sock_in1.bind(('::1', 9004)) + sock_out.sendto(b'data', ('::1', 9004)) result3 = sock_in1.recvfrom(8) # make sure they're from different source ports From 288c11c9d9fe5a1389bb1f9e26727be3830e8308 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 01:55:42 +0800 Subject: [PATCH 08/14] CI Try again! --- tests/jenkins.sh | 2 +- tests/test_udp_src.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/jenkins.sh b/tests/jenkins.sh index dc583ba..5b53e93 100755 --- a/tests/jenkins.sh +++ b/tests/jenkins.sh @@ -51,7 +51,7 @@ run_test python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 1 run_test python tests/test.py --with-coverage --should-fail --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=127.0.0.1,::1,8.8.8.8" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" # test if DNS works -run_test python tests/test.py --with-coverage -c tests/aes.json --url="https://www.google.com/" +run_test python tests/test.py --with-coverage -c tests/aes.json --url="https://clients1.google.com/generate_204" # test localhost is in the forbidden list by default run_test python tests/test.py --with-coverage --should-fail --tcp-only --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" diff --git a/tests/test_udp_src.py b/tests/test_udp_src.py index 50af385..dd78ebf 100644 --- a/tests/test_udp_src.py +++ b/tests/test_udp_src.py @@ -48,13 +48,13 @@ if __name__ == '__main__': sock_in2 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.SOL_UDP) - sock_in1.bind(('::1', 9001)) - sock_in2.bind(('::1', 9002)) + sock_in1.bind(('::1', 9005)) + sock_in2.bind(('::1', 9006)) - sock_out.sendto(b'data', ('::1', 9001)) + sock_out.sendto(b'data', ('::1', 9005)) result1 = sock_in1.recvfrom(8) - sock_out.sendto(b'data', ('::1', 9002)) + sock_out.sendto(b'data', ('::1', 9006)) result2 = sock_in2.recvfrom(8) sock_out.close() From 248582c9328b9ec23bbcfada9000ac6131c5bce7 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 10:34:48 +0800 Subject: [PATCH 09/14] remove IPv6 testcase and add ota test --- shadowsocks/rc4-md5-ota.json | 11 +++++++++++ tests/jenkins.sh | 4 +++- tests/rc4-md5-ota.json | 12 ++++++++++++ tests/test_udp_src.py | 14 ++++++++------ 4 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 shadowsocks/rc4-md5-ota.json create mode 100644 tests/rc4-md5-ota.json diff --git a/shadowsocks/rc4-md5-ota.json b/shadowsocks/rc4-md5-ota.json new file mode 100644 index 0000000..164ee5a --- /dev/null +++ b/shadowsocks/rc4-md5-ota.json @@ -0,0 +1,11 @@ +{ + "server":"127.0.0.1", + "server_port":8899, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"rc4-md5", + "local_address":"127.0.0.1", + "fast_open":false, + "one_time_auth":true +} diff --git a/tests/jenkins.sh b/tests/jenkins.sh index 5b53e93..6d0fac8 100755 --- a/tests/jenkins.sh +++ b/tests/jenkins.sh @@ -45,7 +45,9 @@ run_test python tests/test.py --with-coverage -s tests/aes.json -c tests/client- run_test python tests/test.py --with-coverage -s tests/server-dnsserver.json -c tests/client-multi-server-ip.json run_test python tests/test.py --with-coverage -s tests/server-multi-passwd.json -c tests/server-multi-passwd-client-side.json run_test python tests/test.py --with-coverage -c tests/workers.json -run_test python tests/test.py --with-coverage -s tests/ipv6.json -c tests/ipv6-client-side.json +run_test python tests/test.py --with-coverage -c tests/rc4-md5-ota.json +# travis-ci not support IPv6 +# run_test python tests/test.py --with-coverage -s tests/ipv6.json -c tests/ipv6-client-side.json run_test python tests/test.py --with-coverage -b "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -q" -a "-m rc4-md5 -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -vv" run_test python tests/test.py --with-coverage -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --workers 1" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -qq -b 127.0.0.1" run_test python tests/test.py --with-coverage --should-fail --url="http://127.0.0.1/" -b "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 --forbidden-ip=127.0.0.1,::1,8.8.8.8" -a "-m aes-256-cfb -k testrc4 -s 127.0.0.1 -p 8388 -l 1081 -t 30 -b 127.0.0.1" diff --git a/tests/rc4-md5-ota.json b/tests/rc4-md5-ota.json new file mode 100644 index 0000000..ea93226 --- /dev/null +++ b/tests/rc4-md5-ota.json @@ -0,0 +1,12 @@ +{ + "server":"127.0.0.1", + "server_port":8388, + "local_port":1081, + "password":"aes_password", + "timeout":60, + "method":"rc4-md5", + "local_address":"127.0.0.1", + "fast_open":false, + "one_time_auth":true, + "verbose":1 +} diff --git a/tests/test_udp_src.py b/tests/test_udp_src.py index dd78ebf..585606d 100644 --- a/tests/test_udp_src.py +++ b/tests/test_udp_src.py @@ -36,6 +36,7 @@ if __name__ == '__main__': # make sure they're from the same source port assert result1 == result2 + """ # Test 2: same source port IPv6 # try again from the same port but IPv6 sock_out = socks.socksocket(socket.AF_INET, socket.SOCK_DGRAM, @@ -48,13 +49,13 @@ if __name__ == '__main__': sock_in2 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.SOL_UDP) - sock_in1.bind(('::1', 9005)) - sock_in2.bind(('::1', 9006)) + sock_in1.bind(('::1', 9001)) + sock_in2.bind(('::1', 9002)) - sock_out.sendto(b'data', ('::1', 9005)) + sock_out.sendto(b'data', ('::1', 9001)) result1 = sock_in1.recvfrom(8) - sock_out.sendto(b'data', ('::1', 9006)) + sock_out.sendto(b'data', ('::1', 9002)) result2 = sock_in2.recvfrom(8) sock_out.close() @@ -72,8 +73,8 @@ if __name__ == '__main__': sock_in1 = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.SOL_UDP) - sock_in1.bind(('::1', 9004)) - sock_out.sendto(b'data', ('::1', 9004)) + sock_in1.bind(('::1', 9001)) + sock_out.sendto(b'data', ('::1', 9001)) result3 = sock_in1.recvfrom(8) # make sure they're from different source ports @@ -81,3 +82,4 @@ if __name__ == '__main__': sock_out.close() sock_in1.close() + """ From 269e3dd82dd2c670624de83afa6fdd60bfd6b040 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 12:10:40 +0800 Subject: [PATCH 10/14] test pass ota in udp --- shadowsocks/encrypt.py | 48 ++++++++++++++++++++++++++++++++++++ shadowsocks/rc4-md5-ota.json | 11 --------- shadowsocks/udprelay.py | 21 ++++++++-------- tests/rc4-md5-ota.json | 3 +-- 4 files changed, 60 insertions(+), 23 deletions(-) delete mode 100644 shadowsocks/rc4-md5-ota.json diff --git a/shadowsocks/encrypt.py b/shadowsocks/encrypt.py index 54dbb42..ece72ec 100644 --- a/shadowsocks/encrypt.py +++ b/shadowsocks/encrypt.py @@ -133,6 +133,42 @@ class Encryptor(object): return self.decipher.update(buf) +def gen_key_iv(password, method): + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + key = None + if key_len > 0: + key, _ = EVP_BytesToKey(password, key_len, iv_len) + else: + key = password + iv = random_string(iv_len) + return key, iv, m + + +def encrypt_all_m(key, iv, m, method, data): + result = [] + result.append(iv) + cipher = m(method, key, iv, 1) + result.append(cipher.update(data)) + return b''.join(result) + + +def dencrypt_all(password, method, data): + result = [] + method = method.lower() + (key_len, iv_len, m) = method_supported[method] + key = None + if key_len > 0: + key, _ = EVP_BytesToKey(password, key_len, iv_len) + else: + key = password + iv = data[:iv_len] + data = data[iv_len:] + cipher = m(method, key, iv, 0) + result.append(cipher.update(data)) + return b''.join(result), key, iv + + def encrypt_all(password, method, op, data): result = [] method = method.lower() @@ -185,6 +221,18 @@ def test_encrypt_all(): assert plain == plain2 +def test_encrypt_all_m(): + from os import urandom + plain = urandom(10240) + for method in CIPHERS_TO_TEST: + logging.warn(method) + key, iv, m = gen_key_iv(b'key', method) + cipher = encrypt_all_m(key, iv, m, method, plain) + plain2, key, iv = dencrypt_all(b'key', method, cipher) + assert plain == plain2 + + if __name__ == '__main__': test_encrypt_all() test_encryptor() + test_encrypt_all_m() diff --git a/shadowsocks/rc4-md5-ota.json b/shadowsocks/rc4-md5-ota.json deleted file mode 100644 index 164ee5a..0000000 --- a/shadowsocks/rc4-md5-ota.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "server":"127.0.0.1", - "server_port":8899, - "local_port":1081, - "password":"aes_password", - "timeout":60, - "method":"rc4-md5", - "local_address":"127.0.0.1", - "fast_open":false, - "one_time_auth":true -} diff --git a/shadowsocks/udprelay.py b/shadowsocks/udprelay.py index 6d29f63..975906e 100644 --- a/shadowsocks/udprelay.py +++ b/shadowsocks/udprelay.py @@ -150,6 +150,8 @@ class UDPRelay(object): def _handle_server(self): server = self._server_socket data, r_addr = server.recvfrom(BUF_SIZE) + key = None + iv = None if not data: logging.debug('UDP handle_server: data is empty') if self._stat_callback: @@ -162,7 +164,7 @@ class UDPRelay(object): else: data = data[3:] else: - data = encrypt.encrypt_all(self._password, self._method, 0, data) + data, key, iv = encrypt.dencrypt_all(self._password, self._method, data) # decrypt data if not data: logging.debug( @@ -184,13 +186,11 @@ class UDPRelay(object): logging.warn('UDP one time auth header is too short') return _hash = data[-ONETIMEAUTH_BYTES:] - _data = data[header_length: -ONETIMEAUTH_BYTES] - _key = self._encryptor.decipher_iv + self._encryptor.key - if onetimeauth_verify(_hash, _data, _key) is False: + data = data[: -ONETIMEAUTH_BYTES] + _key = iv + key + if onetimeauth_verify(_hash, data, _key) is False: logging.warn('UDP one time auth fail') return - self._one_time_authed = True - header_length += ONETIMEAUTH_BYTES addrs = self._dns_cache.get(server_addr, None) if addrs is None: addrs = socket.getaddrinfo(server_addr, server_port, 0, @@ -221,10 +221,11 @@ class UDPRelay(object): self._eventloop.add(client, eventloop.POLL_IN, self) if self._is_local: + key, iv, m = gen_key_iv(self._password, self._method) # spec https://shadowsocks.org/en/spec/one-time-auth.html if self._one_time_auth_enable: - data = self._one_time_auth_chunk_data_gen(data) - data = encrypt.encrypt_all(self._password, self._method, 1, data) + data = self._ota_chunk_data_gen(key, iv, data) + data = encrypt.encrypt_all_m(key, iv, m, method, data) if not data: return else: @@ -275,9 +276,9 @@ class UDPRelay(object): # simply drop that packet pass - def _one_time_auth_chunk_data_gen(self, data): + def _ota_chunk_data_gen(self, key, iv, data): data = chr(ord(data[0]) | ADDRTYPE_AUTH) + data[1:] - key = self._encryptor.cipher_iv + self._encryptor.key + key = iv + key return data + onetimeauth_gen(data, key) def add_to_loop(self, loop): diff --git a/tests/rc4-md5-ota.json b/tests/rc4-md5-ota.json index ea93226..3566d6d 100644 --- a/tests/rc4-md5-ota.json +++ b/tests/rc4-md5-ota.json @@ -7,6 +7,5 @@ "method":"rc4-md5", "local_address":"127.0.0.1", "fast_open":false, - "one_time_auth":true, - "verbose":1 + "one_time_auth":true } From f163a7b094d4fa6f98f9d595fdd47f6f67f58769 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 12:17:11 +0800 Subject: [PATCH 11/14] add CI --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b61c0db..608a1fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ shadowsocks =========== +|PyPI version| |Build Status| |Coverage Status| + A fast tunnel proxy that helps you bypass firewalls. Features: From 811a0e6eb8f67a4f97a3a6f610df146385fd5786 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 12:17:46 +0800 Subject: [PATCH 12/14] PEP8 and undefined name 'gen_key_iv' --- shadowsocks/udprelay.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/shadowsocks/udprelay.py b/shadowsocks/udprelay.py index 975906e..3fbd9f3 100644 --- a/shadowsocks/udprelay.py +++ b/shadowsocks/udprelay.py @@ -164,7 +164,9 @@ class UDPRelay(object): else: data = data[3:] else: - data, key, iv = encrypt.dencrypt_all(self._password, self._method, data) + data, key, iv = encrypt.dencrypt_all(self._password, + self._method, + data) # decrypt data if not data: logging.debug( @@ -221,11 +223,11 @@ class UDPRelay(object): self._eventloop.add(client, eventloop.POLL_IN, self) if self._is_local: - key, iv, m = gen_key_iv(self._password, self._method) + key, iv, m = encrypt.gen_key_iv(self._password, self._method) # spec https://shadowsocks.org/en/spec/one-time-auth.html if self._one_time_auth_enable: data = self._ota_chunk_data_gen(key, iv, data) - data = encrypt.encrypt_all_m(key, iv, m, method, data) + data = encrypt.encrypt_all_m(key, iv, m, self._method, data) if not data: return else: From a8d116d70a40c32fb234e813943bc09145512893 Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 14:20:46 +0800 Subject: [PATCH 13/14] fix bug with ord in Py3 --- shadowsocks/tcprelay.py | 10 +++++----- shadowsocks/udprelay.py | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 20517c2..6430f26 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -113,8 +113,8 @@ class TCPRelayHandler(object): self._ota_enable = True else: self._ota_enable = False - self._ota_buff_head = '' - self._ota_buff_data = '' + self._ota_buff_head = b'' + self._ota_buff_data = b'' self._ota_len = 0 self._ota_chunk_idx = 0 self._fastopen_connected = False @@ -338,7 +338,7 @@ class TCPRelayHandler(object): # spec https://shadowsocks.org/en/spec/one-time-auth.html # ATYP & 0x10 == 1, then OTA is enabled. if self._ota_enable: - data = chr(ord(data[0]) | ADDRTYPE_AUTH) + data[1:] + data = common.chr(addrtype | ADDRTYPE_AUTH) + data[1:] key = self._encryptor.cipher_iv + self._encryptor.key data += onetimeauth_gen(data, key) data_to_send = self._encryptor.encrypt(data) @@ -455,8 +455,8 @@ class TCPRelayHandler(object): else: data_cb(self._ota_buff_data) self._ota_chunk_idx += 1 - self._ota_buff_head = '' - self._ota_buff_data = '' + self._ota_buff_head = b'' + self._ota_buff_data = b'' self._ota_len = 0 return diff --git a/shadowsocks/udprelay.py b/shadowsocks/udprelay.py index 3fbd9f3..6bf6ce6 100644 --- a/shadowsocks/udprelay.py +++ b/shadowsocks/udprelay.py @@ -279,7 +279,7 @@ class UDPRelay(object): pass def _ota_chunk_data_gen(self, key, iv, data): - data = chr(ord(data[0]) | ADDRTYPE_AUTH) + data[1:] + data = common.chr(common.ord(data[0]) | ADDRTYPE_AUTH) + data[1:] key = iv + key return data + onetimeauth_gen(data, key) From efe39a75f9cfead70f6925b01d447fd9246fbb0b Mon Sep 17 00:00:00 2001 From: mengskysama Date: Tue, 12 Jan 2016 14:22:10 +0800 Subject: [PATCH 14/14] README CI --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 608a1fd..ed06dba 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ shadowsocks =========== -|PyPI version| |Build Status| |Coverage Status| +[![PyPI version]][PyPI] +[![Build Status]][Travis CI] +[![Coverage Status]][Coverage] A fast tunnel proxy that helps you bypass firewalls.