From 685b62532eb52586d9c805a3d981cc3636983a9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=B4=E5=A8=83=E9=85=B1?= Date: Sun, 16 Oct 2016 21:55:06 +0800 Subject: [PATCH] 2.9.5.1 UDP bind address (set out_bind and out_bindv6) UDP over TCP auto bind return a long enough err string --- shadowsocks/obfsplugin/auth.py | 32 ++++++++++----------- shadowsocks/obfsplugin/http_simple.py | 6 ++-- shadowsocks/obfsplugin/obfs_tls.py | 2 +- shadowsocks/obfsplugin/verify.py | 8 +++--- shadowsocks/tcprelay.py | 40 +++++++++++++++------------ shadowsocks/udprelay.py | 23 ++++++++++++++- shadowsocks/version.py | 2 +- 7 files changed, 70 insertions(+), 43 deletions(-) diff --git a/shadowsocks/obfsplugin/auth.py b/shadowsocks/obfsplugin/auth.py index dad22aa..19e8755 100644 --- a/shadowsocks/obfsplugin/auth.py +++ b/shadowsocks/obfsplugin/auth.py @@ -110,7 +110,7 @@ class auth_base(plain.plain): def not_match_return(self, buf): self.raw_trans = True if self.method == self.no_compatible_method: - return (b'E'*64, False) + return (b'E'*2048, False) return (buf, False) class client_queue(object): @@ -367,7 +367,7 @@ class auth_sha1(auth_base): self.recv_buf = b'' if self.decrypt_packet_num == 0: logging.info('auth_sha1: over size') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): @@ -378,7 +378,7 @@ class auth_sha1(auth_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect checksum') @@ -601,7 +601,7 @@ class auth_sha1_v2(auth_base): self.recv_buf = b'' if self.decrypt_packet_num == 0: logging.info('auth_sha1_v2: over size') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): @@ -612,7 +612,7 @@ class auth_sha1_v2(auth_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect checksum') @@ -810,7 +810,7 @@ class auth_sha1_v3(auth_base): self.recv_buf = b'' if self.decrypt_packet_num == 0: logging.info('auth_sha1_v3: over size') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): @@ -821,7 +821,7 @@ class auth_sha1_v3(auth_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect checksum') @@ -1027,7 +1027,7 @@ class auth_sha1_v4(auth_base): logging.info('auth_sha1_v4: wrong crc') if self.decrypt_packet_num == 0: logging.info('auth_sha1_v4: wrong crc') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') length = struct.unpack('>H', self.recv_buf[:2])[0] @@ -1036,7 +1036,7 @@ class auth_sha1_v4(auth_base): self.recv_buf = b'' if self.decrypt_packet_num == 0: logging.info('auth_sha1_v4: over size') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): @@ -1047,7 +1047,7 @@ class auth_sha1_v4(auth_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect checksum') @@ -1263,7 +1263,7 @@ class auth_aes128(auth_base): logging.info('auth_aes128: wrong crc') if self.recv_id == 0: logging.info('auth_aes128: wrong crc') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') length = struct.unpack(' len(self.recv_buf): @@ -1283,7 +1283,7 @@ class auth_aes128(auth_base): self.raw_trans = True self.recv_buf = b'' if self.recv_id == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect checksum') @@ -1539,7 +1539,7 @@ class auth_aes128_sha1(auth_base): logging.info(self.no_compatible_method + ': wrong crc') if self.recv_id == 0: logging.info(self.no_compatible_method + ': wrong crc') - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') length = struct.unpack(' len(self.recv_buf): @@ -1559,7 +1559,7 @@ class auth_aes128_sha1(auth_base): self.raw_trans = True self.recv_buf = b'' if self.recv_id == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect checksum') diff --git a/shadowsocks/obfsplugin/http_simple.py b/shadowsocks/obfsplugin/http_simple.py index 3dfc071..37831eb 100644 --- a/shadowsocks/obfsplugin/http_simple.py +++ b/shadowsocks/obfsplugin/http_simple.py @@ -165,7 +165,7 @@ class http_simple(plain.plain): self.has_sent_header = True self.has_recv_header = True if self.method == 'http_simple': - return (b'E'*64, False, False) + return (b'E'*2048, False, False) return (buf, True, False) def server_decode(self, buf): @@ -251,7 +251,7 @@ class http_post(http_simple): self.has_sent_header = True self.has_recv_header = True if self.method == 'http_post': - return (b'E'*64, False, False) + return (b'E'*2048, False, False) return (buf, True, False) class random_head(plain.plain): @@ -300,7 +300,7 @@ class random_head(plain.plain): if crc != 0xffffffff: self.has_sent_header = True if self.method == 'random_head': - return (b'E'*64, False, False) + return (b'E'*2048, False, False) return (buf, True, False) # (buffer_to_recv, is_need_decrypt, is_need_to_encode_and_send_back) return (b'', False, True) diff --git a/shadowsocks/obfsplugin/obfs_tls.py b/shadowsocks/obfsplugin/obfs_tls.py index cc7183e..9912c92 100644 --- a/shadowsocks/obfsplugin/obfs_tls.py +++ b/shadowsocks/obfsplugin/obfs_tls.py @@ -167,7 +167,7 @@ class tls_ticket_auth(plain.plain): def decode_error_return(self, buf): self.handshake_status = -1 if self.method == 'tls1.2_ticket_auth': - return (b'E'*64, False, False) + return (b'E'*2048, False, False) return (buf, True, False) def server_decode(self, buf): diff --git a/shadowsocks/obfsplugin/verify.py b/shadowsocks/obfsplugin/verify.py index 674652f..e896fba 100644 --- a/shadowsocks/obfsplugin/verify.py +++ b/shadowsocks/obfsplugin/verify.py @@ -160,7 +160,7 @@ class verify_simple(verify_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): @@ -170,7 +170,7 @@ class verify_simple(verify_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E', False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data uncorrect CRC32') @@ -245,7 +245,7 @@ class verify_deflate(verify_base): self.raw_trans = True self.recv_buf = b'' if self.decrypt_packet_num == 0: - return (b'E'*64, False) + return (b'E'*2048, False) else: raise Exception('server_post_decrype data error') if length > len(self.recv_buf): @@ -304,7 +304,7 @@ class verify_sha1(verify_base): def not_match_return(self, buf): self.raw_trans = True if self.method == 'verify_sha1': - return (b'E'*64, False) + return (b'E'*2048, False) return (buf, False) def server_post_decrypt(self, buf): diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index 19a4af8..d65833c 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -532,6 +532,24 @@ class TCPRelayHandler(object): traceback.print_exc() self.destroy() + def _socket_bind_addr(self, sock, af): + bind_addr = '' + if self._bind and af == socket.AF_INET: + bind_addr = self._bind + elif self._bindv6 and af == socket.AF_INET6: + bind_addr = self._bindv6 + else: + bind_addr = self._accept_address[0] + + bind_addr = bind_addr.replace("::ffff:", "") + if bind_addr in self._ignore_bind_list: + bind_addr = None + if bind_addr: + local_addrs = socket.getaddrinfo(bind_addr, 0, 0, socket.SOCK_STREAM, socket.SOL_TCP) + if local_addrs[0][0] == af: + logging.debug("bind %s" % (bind_addr,)) + sock.bind((bind_addr, 0)) + def _create_remote_socket(self, ip, port): if self._remote_udp: addrs_v6 = socket.getaddrinfo("::", 0, 0, socket.SOCK_DGRAM, socket.SOL_UDP) @@ -568,26 +586,14 @@ class TCPRelayHandler(object): remote_sock.setblocking(False) if self._remote_udp: remote_sock_v6.setblocking(False) + + if not self._is_local: + self._socket_bind_addr(remote_sock, af) + self._socket_bind_addr(remote_sock_v6, af) else: remote_sock.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1) - if not self._is_local: - bind_addr = '' - if self._bind and af == socket.AF_INET: - bind_addr = self._bind - elif self._bindv6 and af == socket.AF_INET6: - bind_addr = self._bindv6 - else: - bind_addr = self._accept_address[0] - - bind_addr = bind_addr.replace("::ffff:", "") - if bind_addr in self._ignore_bind_list: - bind_addr = None - if bind_addr: - local_addrs = socket.getaddrinfo(bind_addr, port, 0, socket.SOCK_STREAM, socket.SOL_TCP) - if local_addrs[0][0] == af: - logging.debug("bind %s" % (bind_addr,)) - remote_sock.bind((bind_addr, 0)) + self._socket_bind_addr(remote_sock, af) return remote_sock def _handle_dns_resolved(self, result, error): diff --git a/shadowsocks/udprelay.py b/shadowsocks/udprelay.py index 5e49ff4..30649a6 100644 --- a/shadowsocks/udprelay.py +++ b/shadowsocks/udprelay.py @@ -923,6 +923,10 @@ class UDPRelay(object): self._timeout_offset = 0 # last checked position for timeout self._handler_to_timeouts = {} # key: handler value: index in timeouts + self._bind = config.get('out_bind', '') + self._bindv6 = config.get('out_bindv6', '') + self._ignore_bind_list = config.get('ignore_bind', []) + if 'forbidden_ip' in config: self._forbidden_iplist = config['forbidden_ip'] else: @@ -1010,6 +1014,22 @@ class UDPRelay(object): #raise Exception('can not parse header') logging.warn("Protocol ERROR, UDP ogn data %s from %s:%d" % (binascii.hexlify(ogn_data), client_address[0], client_address[1])) + def _socket_bind_addr(self, sock, af): + bind_addr = '' + if self._bind and af == socket.AF_INET: + bind_addr = self._bind + elif self._bindv6 and af == socket.AF_INET6: + bind_addr = self._bindv6 + + bind_addr = bind_addr.replace("::ffff:", "") + if bind_addr in self._ignore_bind_list: + bind_addr = None + if bind_addr: + local_addrs = socket.getaddrinfo(bind_addr, 0, 0, socket.SOCK_STREAM, socket.SOL_TCP) + if local_addrs[0][0] == af: + logging.debug("bind %s" % (bind_addr,)) + sock.bind((bind_addr, 0)) + def _handle_server(self): server = self._server_socket data, r_addr = server.recvfrom(BUF_SIZE) @@ -1045,7 +1065,7 @@ class UDPRelay(object): if type(data) is tuple: return - return self._handle_tcp_over_udp(data, r_addr) + #return self._handle_tcp_over_udp(data, r_addr) try: header_result = parse_header(data) @@ -1094,6 +1114,7 @@ class UDPRelay(object): return client = socket.socket(af, socktype, proto) client.setblocking(False) + self._socket_bind_addr(client, af) is_dns = False if len(data) > 20 and data[11:19] == b"\x00\x01\x00\x00\x00\x00\x00\x00": is_dns = True diff --git a/shadowsocks/version.py b/shadowsocks/version.py index 73fcd12..e783755 100644 --- a/shadowsocks/version.py +++ b/shadowsocks/version.py @@ -16,5 +16,5 @@ # under the License. def version(): - return '2.9.5 2016-10-13' + return '2.9.5.1 2016-10-16'