python 3 support; not stable yet
This commit is contained in:
parent
0814888ba5
commit
2a53b67c65
17 changed files with 204 additions and 115 deletions
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue