Skip to content

Commit 1b0504a

Browse files
committed
merge manyuser branch
1 parent e5b4a80 commit 1b0504a

File tree

4 files changed

+61
-16
lines changed

4 files changed

+61
-16
lines changed

shadowsocks/common.py

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,20 @@ def pack_addr(address):
138138
address = address[:255] # TODO
139139
return b'\x03' + chr(len(address)) + address
140140

141+
def pre_parse_header(data):
142+
datatype = ord(data[0])
143+
if datatype == 0x80 :
144+
if len(data) <= 2:
145+
return None
146+
rand_data_size = ord(data[1])
147+
if rand_data_size + 2 >= len(data):
148+
logging.warn('header too short, maybe wrong password or '
149+
'encryption method')
150+
return None
151+
data = data[rand_data_size + 2:]
152+
elif datatype == 0x81:
153+
data = data[1:]
154+
return data
141155

142156
def parse_header(data):
143157
addrtype = ord(data[0])
@@ -173,8 +187,8 @@ def parse_header(data):
173187
else:
174188
logging.warn('header is too short')
175189
else:
176-
logging.warn('unsupported addrtype %d, maybe wrong password' %
177-
addrtype)
190+
logging.warn('unsupported addrtype %d, maybe wrong password or '
191+
'encryption method' % addrtype)
178192
if dest_addr is None:
179193
return None
180194
return connecttype, to_bytes(dest_addr), dest_port, header_length

shadowsocks/encrypt_test.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from __future__ import absolute_import, division, print_function, \
2+
with_statement
3+
4+
import sys
5+
import os
6+
7+
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../'))
8+
9+
10+
from crypto import rc4_md5
11+
from crypto import openssl
12+
from crypto import sodium
13+
from crypto import table
14+
15+
def main():
16+
print("\n""rc4_md5")
17+
rc4_md5.test()
18+
print("\n""aes-256-cfb")
19+
openssl.test_aes_256_cfb()
20+
print("\n""aes-128-cfb")
21+
openssl.test_aes_128_cfb()
22+
print("\n""rc4")
23+
openssl.test_rc4()
24+
print("\n""salsa20")
25+
sodium.test_salsa20()
26+
print("\n""chacha20")
27+
sodium.test_chacha20()
28+
print("\n""table")
29+
table.test_encryption()
30+
31+
if __name__ == '__main__':
32+
main()
33+

shadowsocks/tcprelay.py

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import random
2828

2929
from shadowsocks import encrypt, eventloop, shell, common
30-
from shadowsocks.common import parse_header
30+
from shadowsocks.common import pre_parse_header, parse_header
3131

3232
# we clear at most TIMEOUTS_CLEAN_SIZE timeouts each time
3333
TIMEOUTS_CLEAN_SIZE = 512
@@ -320,12 +320,15 @@ def _handle_stage_addr(self, data):
320320
logging.error('unknown command %d', cmd)
321321
self.destroy()
322322
return
323+
data = pre_parse_header(data)
324+
if data is None:
325+
raise Exception('can not parse header')
323326
header_result = parse_header(data)
324327
if header_result is None:
325328
raise Exception('can not parse header')
326329
connecttype, remote_addr, remote_port, header_length = header_result
327330
logging.info('%s connecting %s:%d from %s:%d' %
328-
((connecttype == 0) and 'tcp' or 'udp',
331+
((connecttype == 0) and 'TCP' or 'UDP',
329332
common.to_str(remote_addr), remote_port,
330333
self._client_address[0], self._client_address[1]))
331334
self._remote_address = (common.to_str(remote_addr), remote_port)
@@ -356,15 +359,6 @@ def _handle_stage_addr(self, data):
356359
# TODO use logging when debug completed
357360
self.destroy()
358361

359-
def _has_ipv6_addr(self, addr_list):
360-
for item in addr_list:
361-
if type(item) is list:
362-
if self._has_ipv6_addr(item):
363-
return True
364-
elif ':' in item:
365-
return True
366-
return False
367-
368362
def _create_remote_socket(self, ip, port):
369363
if self._remote_udp:
370364
addrs_v6 = socket.getaddrinfo("::", 0, 0, socket.SOCK_DGRAM, socket.SOL_UDP)
@@ -505,7 +499,7 @@ def _on_remote_read(self, is_remote_sock):
505499
except Exception as e:
506500
ip = socket.inet_pton(socket.AF_INET6, addr[0])
507501
data = '\x00\x00\x00\x04' + ip + port + data
508-
logging.info('udp recvfrom %s:%d %d bytes to %s:%d' % (addr[0], addr[1], len(data), self._client_address[0], self._client_address[1]))
502+
logging.info('UDP recvfrom %s:%d %d bytes to %s:%d' % (addr[0], addr[1], len(data), self._client_address[0], self._client_address[1]))
509503
else:
510504
data = self._remote_sock.recv(BUF_SIZE)
511505
except (OSError, IOError) as e:

shadowsocks/udprelay.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
import random
7171

7272
from shadowsocks import encrypt, eventloop, lru_cache, common, shell
73-
from shadowsocks.common import parse_header, pack_addr
73+
from shadowsocks.common import pre_parse_header, parse_header, pack_addr
7474

7575

7676
BUF_SIZE = 65536
@@ -159,6 +159,10 @@ def _handle_server(self):
159159
if not data:
160160
logging.debug('UDP handle_server: data is empty after decrypt')
161161
return
162+
data = pre_parse_header(data)
163+
if data is None:
164+
return
165+
162166
header_result = parse_header(data)
163167
if header_result is None:
164168
return
@@ -173,7 +177,7 @@ def _handle_server(self):
173177
client = self._cache.get(key, None)
174178
if not client:
175179
# TODO async getaddrinfo
176-
logging.info('UDP handle_server %s:%d from %s:%d' % (common.to_str(server_addr), server_port, self._listen_addr, self._listen_port))
180+
#logging.info('UDP handle_server %s:%d from %s:%d' % (common.to_str(server_addr), server_port, self._listen_addr, self._listen_port))
177181
addrs = socket.getaddrinfo(server_addr, server_port, 0,
178182
socket.SOCK_DGRAM, socket.SOL_UDP)
179183
if addrs:

0 commit comments

Comments
 (0)