python 3 support; not stable yet

This commit is contained in:
clowwindy 2014-10-31 18:28:22 +08:00
parent 0814888ba5
commit 2a53b67c65
17 changed files with 204 additions and 115 deletions

View file

@ -21,6 +21,9 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
from __future__ import absolute_import, division, print_function, \
with_statement
import time
import os
import socket
@ -33,7 +36,7 @@ from shadowsocks import common, lru_cache, eventloop
CACHE_SWEEP_INTERVAL = 30
VALID_HOSTNAME = re.compile(r"(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
VALID_HOSTNAME = re.compile(br"(?!-)[A-Z\d-]{1,63}(?<!-)$", re.IGNORECASE)
common.patch_socket()
@ -77,17 +80,17 @@ QCLASS_IN = 1
def build_address(address):
address = address.strip('.')
labels = address.split('.')
address = address.strip(b'.')
labels = address.split(b'.')
results = []
for label in labels:
l = len(label)
if l > 63:
return None
results.append(chr(l))
results.append(common.chr(l))
results.append(label)
results.append('\0')
return ''.join(results)
results.append(b'\0')
return b''.join(results)
def build_request(address, qtype, request_id):
@ -111,7 +114,7 @@ def parse_ip(addrtype, data, length, offset):
def parse_name(data, offset):
p = offset
labels = []
l = ord(data[p])
l = common.ord(data[p])
while l > 0:
if (l & (128 + 64)) == (128 + 64):
# pointer
@ -121,12 +124,12 @@ def parse_name(data, offset):
labels.append(r[1])
p += 2
# pointer is the end
return p - offset, '.'.join(labels)
return p - offset, b'.'.join(labels)
else:
labels.append(data[p + 1:p + 1 + l])
p += 1 + l
l = ord(data[p])
return p - offset + 1, '.'.join(labels)
l = common.ord(data[p])
return p - offset + 1, b'.'.join(labels)
# rfc1035
@ -198,20 +201,20 @@ def parse_response(data):
qds = []
ans = []
offset = 12
for i in xrange(0, res_qdcount):
for i in range(0, res_qdcount):
l, r = parse_record(data, offset, True)
offset += l
if r:
qds.append(r)
for i in xrange(0, res_ancount):
for i in range(0, res_ancount):
l, r = parse_record(data, offset)
offset += l
if r:
ans.append(r)
for i in xrange(0, res_nscount):
for i in range(0, res_nscount):
l, r = parse_record(data, offset)
offset += l
for i in xrange(0, res_arcount):
for i in range(0, res_arcount):
l, r = parse_record(data, offset)
offset += l
response = DNSResponse()
@ -232,6 +235,8 @@ def parse_response(data):
def is_ip(address):
for family in (socket.AF_INET, socket.AF_INET6):
try:
if type(address) != str:
address = address.decode('utf8')
socket.inet_pton(family, address)
return family
except (TypeError, ValueError, OSError, IOError):
@ -242,9 +247,9 @@ def is_ip(address):
def is_valid_hostname(hostname):
if len(hostname) > 255:
return False
if hostname[-1] == ".":
if hostname[-1] == b'.':
hostname = hostname[:-1]
return all(VALID_HOSTNAME.match(x) for x in hostname.split("."))
return all(VALID_HOSTNAME.match(x) for x in hostname.split(b'.'))
class DNSResponse(object):
@ -287,11 +292,13 @@ class DNSResolver(object):
for line in content:
line = line.strip()
if line:
if line.startswith('nameserver'):
if line.startswith(b'nameserver'):
parts = line.split()
if len(parts) >= 2:
server = parts[1]
if is_ip(server) == socket.AF_INET:
if type(server) != str:
server = server.decode('utf8')
self._servers.append(server)
except IOError:
pass
@ -310,7 +317,7 @@ class DNSResolver(object):
if len(parts) >= 2:
ip = parts[0]
if is_ip(ip):
for i in xrange(1, len(parts)):
for i in range(1, len(parts)):
hostname = parts[i]
if hostname:
self._hosts[hostname] = ip