diff --git a/shadowsocks/common.py b/shadowsocks/common.py index 2b11b9f..7f306ea 100644 --- a/shadowsocks/common.py +++ b/shadowsocks/common.py @@ -54,6 +54,16 @@ def to_str(s): return s.decode('utf-8') return s +def int32(x): + if x > 0xFFFFFFFF or x < 0: + x &= 0xFFFFFFFF + if x > 0x7FFFFFFF: + x = int(0x100000000 - x) + if x < 0x80000000: + return -x + else: + return -2147483648 + return x def inet_ntop(family, ipstr): if family == socket.AF_INET: diff --git a/shadowsocks/obfsplugin/http_simple.py b/shadowsocks/obfsplugin/http_simple.py index 75e9294..637015f 100644 --- a/shadowsocks/obfsplugin/http_simple.py +++ b/shadowsocks/obfsplugin/http_simple.py @@ -110,17 +110,19 @@ class http_simple(plain.plain): if self.has_recv_header: return (buf, True, False) - buf = self.recv_buffer + buf + self.recv_buffer += buf + buf = self.recv_buffer if len(buf) > 10: if match_begin(buf, b'GET /') or match_begin(buf, b'POST /'): if len(buf) > 65536: self.recv_buffer = None + logging.warn('http_simple: over size') return self.not_match_return(buf) else: #not http header, run on original protocol self.recv_buffer = None + logging.debug('http_simple: not match begin') return self.not_match_return(buf) else: - self.recv_buffer = buf return (b'', True, False) datas = buf.split(b'\r\n\r\n', 1) @@ -130,12 +132,9 @@ class http_simple(plain.plain): if len(ret_buf) >= 15: self.has_recv_header = True return (ret_buf, True, False) - self.recv_buffer = buf return (b'', True, False) else: - self.recv_buffer = buf return (b'', True, False) - return self.not_match_return(buf) class http2_simple(plain.plain): def __init__(self, method): @@ -173,7 +172,8 @@ class http2_simple(plain.plain): if self.has_recv_header: return (buf, True, False) - buf = self.recv_buffer + buf + self.recv_buffer += buf + buf = self.recv_buffer if len(buf) > 10: if match_begin(buf, b'GET /'): pass @@ -181,7 +181,6 @@ class http2_simple(plain.plain): self.recv_buffer = None return self.not_match_return(buf) else: - self.recv_buffer = buf return (b'', True, False) datas = buf.split(b'\r\n\r\n', 1) @@ -193,10 +192,8 @@ class http2_simple(plain.plain): ret_buf += datas[1] self.has_recv_header = True return (ret_buf, True, False) - self.recv_buffer = buf return (b'', True, False) else: - self.recv_buffer = buf return (b'', True, False) return self.not_match_return(buf) diff --git a/shadowsocks/obfsplugin/verify_simple.py b/shadowsocks/obfsplugin/verify_simple.py index fde73fa..c162c06 100644 --- a/shadowsocks/obfsplugin/verify_simple.py +++ b/shadowsocks/obfsplugin/verify_simple.py @@ -312,14 +312,18 @@ class client_queue(object): def insert(self, connection_id): self.update() if not self.enable: + logging.warn('auth_simple: not enable') return False if connection_id < self.front: + logging.warn('auth_simple: duplicate id') return False if not self.is_active(): self.re_enable(connection_id) if connection_id > self.front + 0x4000: + logging.warn('auth_simple: wrong id') return False if connection_id in self.alloc: + logging.warn('auth_simple: duplicate id 2') return False if self.back <= connection_id: self.back = connection_id + 1 @@ -347,6 +351,7 @@ class obfs_auth_data(object): if self.client_id[c_id].is_active(): active += 1 if active >= max_client: + logging.warn('auth_simple: max active clients exceeded') return False if len(self.client_id) < max_client: @@ -368,6 +373,7 @@ class obfs_auth_data(object): else: self.client_id[client_id].re_enable(connection_id) return self.client_id[client_id].insert(connection_id) + logging.warn('auth_simple: no inactive client [assert]') return False else: return self.client_id[client_id].insert(connection_id) @@ -457,6 +463,7 @@ class auth_simple(verify_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: + logging.info('auth_simple: over size') return b'E' else: raise Exception('server_post_decrype data error') @@ -464,6 +471,7 @@ class auth_simple(verify_base): break if (binascii.crc32(self.recv_buf[:length]) & 0xffffffff) != 0xffffffff: + logging.info('auth_simple: crc32 error, data %s' % (binascii.hexlify(self.recv_buf[:length]),)) self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: @@ -474,20 +482,29 @@ class auth_simple(verify_base): pos = common.ord(self.recv_buf[2]) + 2 out_buf += self.recv_buf[pos:length - 4] if not self.has_recv_header: - if len(out_buf) < 8: + if len(out_buf) < 12: self.raw_trans = True self.recv_buf = b'' + logging.info('auth_simple: too short') return b'E' - client_id = struct.unpack(' 60 * 3: + self.raw_trans = True + self.recv_buf = b'' + logging.info('auth_simple: wrong timestamp, time_dif %d, data %s' % (time_dif, binascii.hexlify(out_buf),)) + return b'E' + elif self.server_info.data.insert(client_id, connection_id): self.has_recv_header = True - out_buf = out_buf[8:] + out_buf = out_buf[12:] self.client_id = client_id self.connection_id = connection_id else: self.raw_trans = True self.recv_buf = b'' + logging.info('auth_simple: auth fail, data %s' % (binascii.hexlify(out_buf),)) return b'E' self.recv_buf = self.recv_buf[length:] diff --git a/shadowsocks/server.py b/shadowsocks/server.py index 006a372..9734382 100755 --- a/shadowsocks/server.py +++ b/shadowsocks/server.py @@ -68,7 +68,8 @@ def main(): obfs = config["obfs"] a_config = config.copy() ipv6_ok = False - logging.info("server start with password [%s] obfs [%s] method [%s]" % (password, obfs, a_config['method'])) + logging.info("server start with password [%s] method [%s] obfs [%s] obfs_param [%s]" % + (password, a_config['method'], obfs, a_config['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] == "]": @@ -77,7 +78,7 @@ def main(): a_config['password'] = password a_config['obfs'] = obfs a_config['server'] = a_config['server_ipv6'] - logging.info("starting server at %s:%d" % + 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))