From e6d7a12afea37ec6f4fa3779a40693f6fef896f1 Mon Sep 17 00:00:00 2001 From: BreakWa11 Date: Wed, 28 Oct 2015 22:28:24 +0800 Subject: [PATCH] fix bugs dns working in both v4 & v6 connecting problem in windows --- shadowsocks/asyncdns.py | 41 +++++++++++++++++++-------- shadowsocks/obfsplugin/http_simple.py | 3 ++ shadowsocks/tcprelay.py | 4 +-- shadowsocks/udprelay.py | 3 +- 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/shadowsocks/asyncdns.py b/shadowsocks/asyncdns.py index e64895c..d958752 100644 --- a/shadowsocks/asyncdns.py +++ b/shadowsocks/asyncdns.py @@ -83,9 +83,11 @@ def detect_ipv6_supprot(): s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) try: s.connect(('ipv6.google.com', 0)) + print('IPv6 support') return True except: pass + print('IPv6 not support') return False IPV6_CONNECTION_SUPPORT = detect_ipv6_supprot() @@ -356,19 +358,34 @@ class DNSResolver(object): answer[2] == QCLASS_IN: ip = answer[0] break - if not ip and self._hostname_status.get(hostname, STATUS_IPV4) \ - == STATUS_IPV6: - self._hostname_status[hostname] = STATUS_IPV4 - self._send_req(hostname, QTYPE_A) + if IPV6_CONNECTION_SUPPORT: + if not ip and self._hostname_status.get(hostname, STATUS_IPV4) \ + == STATUS_IPV6: + self._hostname_status[hostname] = STATUS_IPV4 + self._send_req(hostname, QTYPE_A) + else: + if ip: + self._cache[hostname] = ip + self._call_callback(hostname, ip) + elif self._hostname_status.get(hostname, None) == STATUS_IPV4: + for question in response.questions: + if question[1] == QTYPE_A: + self._call_callback(hostname, None) + break else: - if ip: - self._cache[hostname] = ip - self._call_callback(hostname, ip) - elif self._hostname_status.get(hostname, None) == STATUS_IPV4: - for question in response.questions: - if question[1] == QTYPE_A: - self._call_callback(hostname, None) - break + if not ip and self._hostname_status.get(hostname, STATUS_IPV6) \ + == STATUS_IPV4: + self._hostname_status[hostname] = STATUS_IPV6 + self._send_req(hostname, QTYPE_AAAA) + else: + if ip: + self._cache[hostname] = ip + self._call_callback(hostname, ip) + elif self._hostname_status.get(hostname, None) == STATUS_IPV6: + for question in response.questions: + if question[1] == QTYPE_AAAA: + self._call_callback(hostname, None) + break def handle_event(self, sock, fd, event): if sock != self._sock: diff --git a/shadowsocks/obfsplugin/http_simple.py b/shadowsocks/obfsplugin/http_simple.py index efd7f2a..8144aa8 100644 --- a/shadowsocks/obfsplugin/http_simple.py +++ b/shadowsocks/obfsplugin/http_simple.py @@ -192,6 +192,9 @@ class http2_simple(plain.plain): return buf self.send_buffer += buf if not self.has_sent_header: + port = b'' + if self.server_info.port != 80: + port = b':' + common.to_bytes(str(self.server_info.port)) self.has_sent_header = True http_head = b"GET / HTTP/1.1\r\n" http_head += b"Host: " + (self.server_info.param or self.server_info.host) + port + b"\r\n" diff --git a/shadowsocks/tcprelay.py b/shadowsocks/tcprelay.py index cce6df5..e1ea954 100644 --- a/shadowsocks/tcprelay.py +++ b/shadowsocks/tcprelay.py @@ -523,8 +523,8 @@ class TCPRelayHandler(object): try: remote_sock.connect((remote_addr, remote_port)) except (OSError, IOError) as e: - if eventloop.errno_from_exception(e) == \ - errno.EINPROGRESS: + if eventloop.errno_from_exception(e) in (errno.EINPROGRESS, + errno.EWOULDBLOCK): pass # always goto here else: raise e diff --git a/shadowsocks/udprelay.py b/shadowsocks/udprelay.py index b4fcae3..12676f7 100644 --- a/shadowsocks/udprelay.py +++ b/shadowsocks/udprelay.py @@ -207,7 +207,7 @@ class RecvQueue(object): def set_end(self, end_id): if end_id > self.end_id: eid = self.end_id - while eid < pack_id: + while eid < end_id: self.miss_queue.add(eid) eid += 1 self.end_id = end_id @@ -623,6 +623,7 @@ class TCPRelayHandler(object): for pid in missing: data += struct.pack(">H", pid) rsp_data = self._pack_post_data(CMD_SYN_STATUS, pack_id, data) + addr = self.get_local_address() self._write_to_sock(rsp_data, self._local_sock, addr) def handle_stream_sync_status(self, addr, cmd, request_id, pack_id, max_send_id, data):