Browse Source

not redirect host to chn web

add auth_simple
dev
BreakWa11 9 years ago
parent
commit
0ba76b666d
  1. 217
      shadowsocks/obfsplugin/verify_simple.py
  2. 2
      shadowsocks/tcprelay.py

217
shadowsocks/obfsplugin/verify_simple.py

@ -23,7 +23,9 @@ import hashlib
import logging import logging
import binascii import binascii
import base64 import base64
import time
import datetime import datetime
import random
import struct import struct
import zlib import zlib
@ -38,9 +40,13 @@ def create_verify_obfs(method):
def create_verify_deflate(method): def create_verify_deflate(method):
return verify_deflate(method) return verify_deflate(method)
def create_auth_obfs(method):
return auth_simple(method)
obfs_map = { obfs_map = {
'verify_simple': (create_verify_obfs,), 'verify_simple': (create_verify_obfs,),
'verify_deflate': (create_verify_deflate,), 'verify_deflate': (create_verify_deflate,),
'auth_simple': (create_auth_obfs,),
} }
def match_begin(str1, str2): def match_begin(str1, str2):
@ -49,7 +55,7 @@ def match_begin(str1, str2):
return True return True
return False return False
class sub_encode_obfs(object): class obfs_verify_data(object):
def __init__(self): def __init__(self):
self.sub_obfs = None self.sub_obfs = None
@ -60,7 +66,7 @@ class verify_base(plain.plain):
self.sub_obfs = None self.sub_obfs = None
def init_data(self): def init_data(self):
return sub_encode_obfs() return obfs_verify_data()
def set_server_info(self, server_info): def set_server_info(self, server_info):
try: try:
@ -283,3 +289,210 @@ class verify_deflate(verify_base):
self.decrypt_packet_num += 1 self.decrypt_packet_num += 1
return out_buf return out_buf
class client_queue(object):
def __init__(self, begin_id):
self.front = begin_id
self.back = begin_id
self.alloc = {}
self.enable = True
self.last_update = time.time()
def update(self):
self.last_update = time.time()
def is_active(self):
return time.time() - self.last_update < 60 * 3
def re_enable(self, connection_id):
self.enable = True
self.alloc = {}
self.front = connection_id
self.back = connection_id
def insert(self, connection_id):
self.update()
if not self.enable:
return False
if connection_id < self.front:
return False
if not self.is_active():
self.re_enable(connection_id)
if connection_id > self.front + 0x4000:
return False
if connection_id in self.alloc:
return False
if self.back <= connection_id:
self.back = connection_id + 1
self.alloc[connection_id] = 1
while (self.front in self.alloc) or self.front + 0x1000 < self.back:
if self.front in self.alloc:
del self.alloc[self.front]
self.front += 1
return True
class obfs_auth_data(object):
def __init__(self):
self.sub_obfs = None
self.client_id = {}
def update(self, client_id, connection_id):
if client_id in self.client_id:
self.client_id[client_id].update()
def insert(self, client_id, connection_id):
max_client = 16
if client_id not in self.client_id or not self.client_id[client_id].enable:
active = 0
for c_id in self.client_id:
if self.client_id[c_id].is_active():
active += 1
if active >= max_client:
return False
if len(self.client_id) < max_client:
if client_id not in self.client_id:
self.client_id[client_id] = client_queue(connection_id)
else:
self.client_id[client_id].re_enable(connection_id)
return self.client_id[client_id].insert(connection_id)
keys = self.client_id.keys()
random.shuffle(keys)
for c_id in keys:
if not self.client_id[c_id].is_active() and self.client_id[c_id].enable:
if len(self.client_id) >= 256:
del self.client_id[c_id]
else:
self.client_id[c_id].enable = False
if client_id not in self.client_id:
self.client_id[client_id] = client_queue(connection_id)
else:
self.client_id[client_id].re_enable(connection_id)
return self.client_id[client_id].insert(connection_id)
return False
else:
return self.client_id[client_id].insert(connection_id)
class auth_simple(verify_base):
def __init__(self, method):
super(auth_simple, self).__init__(method)
self.recv_buf = b''
self.unit_len = 8100
self.decrypt_packet_num = 0
self.raw_trans = False
self.has_sent_header = False
self.has_recv_header = False
self.client_id = 0
self.connection_id = 0
def init_data(self):
return obfs_auth_data()
def pack_data(self, buf):
if len(buf) == 0:
return b''
rnd_data = os.urandom(common.ord(os.urandom(1)[0]) % 16)
data = common.chr(len(rnd_data) + 1) + rnd_data + buf
data = struct.pack('>H', len(data) + 6) + data
crc = (0xffffffff - binascii.crc32(data)) & 0xffffffff
data += struct.pack('<I', crc)
return data
def client_pre_encrypt(self, buf):
ret = b''
while len(buf) > self.unit_len:
ret += self.pack_data(buf[:self.unit_len])
buf = buf[self.unit_len:]
ret += self.pack_data(buf)
return ret
def client_post_decrypt(self, buf):
if self.raw_trans:
return buf
self.recv_buf += buf
out_buf = b''
while len(self.recv_buf) > 2:
length = struct.unpack('>H', self.recv_buf[:2])[0]
if length >= 8192:
self.raw_trans = True
self.recv_buf = b''
if self.decrypt_packet_num == 0:
return None
else:
raise Exception('server_post_decrype data error')
if length > len(self.recv_buf):
break
if (binascii.crc32(self.recv_buf[:length]) & 0xffffffff) != 0xffffffff:
self.raw_trans = True
self.recv_buf = b''
if self.decrypt_packet_num == 0:
return None
else:
raise Exception('server_post_decrype data uncorrect CRC32')
pos = common.ord(self.recv_buf[2]) + 2
out_buf += self.recv_buf[pos:length - 4]
self.recv_buf = self.recv_buf[length:]
if out_buf:
self.decrypt_packet_num += 1
return out_buf
def server_pre_encrypt(self, buf):
ret = b''
while len(buf) > self.unit_len:
ret += self.pack_data(buf[:self.unit_len])
buf = buf[self.unit_len:]
ret += self.pack_data(buf)
return ret
def server_post_decrypt(self, buf):
if self.raw_trans:
return buf
self.recv_buf += buf
out_buf = b''
while len(self.recv_buf) > 2:
length = struct.unpack('>H', self.recv_buf[:2])[0]
if length >= 8192:
self.raw_trans = True
self.recv_buf = b''
if self.decrypt_packet_num == 0:
return b'E'
else:
raise Exception('server_post_decrype data error')
if length > len(self.recv_buf):
break
if (binascii.crc32(self.recv_buf[:length]) & 0xffffffff) != 0xffffffff:
self.raw_trans = True
self.recv_buf = b''
if self.decrypt_packet_num == 0:
return b'E'
else:
raise Exception('server_post_decrype data uncorrect CRC32')
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:
self.raw_trans = True
self.recv_buf = b''
return b'E'
client_id = struct.unpack('<I', out_buf[:4])[0]
connection_id = struct.unpack('<I', out_buf[4:8])[0]
if self.server_info.data.insert(client_id, connection_id):
self.has_recv_header = True
out_buf = out_buf[8:]
self.client_id = client_id
self.connection_id = connection_id
else:
self.raw_trans = True
self.recv_buf = b''
return b'E'
self.recv_buf = self.recv_buf[length:]
if out_buf:
self.server_info.data.update(self.client_id, self.connection_id)
self.decrypt_packet_num += 1
return out_buf

2
shadowsocks/tcprelay.py

@ -307,7 +307,7 @@ class TCPRelayHandler(object):
def _get_redirect_host(self, client_address, ogn_data): def _get_redirect_host(self, client_address, ogn_data):
# test # test
host_list = [(b"www.bing.com", 80), (b"www.microsoft.com", 80), (b"www.baidu.com", 443), (b"www.qq.com", 80), (b"www.csdn.net", 80), (b"1.2.3.4", 1000)] host_list = [(b"www.bing.com", 80), (b"www.microsoft.com", 80), (b"cloudfront.com", 80), (b"cloudflare.com", 80), (b"1.2.3.4", 1000), (b"0.0.0.0", 0)]
hash_code = binascii.crc32(ogn_data) hash_code = binascii.crc32(ogn_data)
addrs = socket.getaddrinfo(client_address[0], client_address[1], 0, socket.SOCK_STREAM, socket.SOL_TCP) addrs = socket.getaddrinfo(client_address[0], client_address[1], 0, socket.SOCK_STREAM, socket.SOL_TCP)
af, socktype, proto, canonname, sa = addrs[0] af, socktype, proto, canonname, sa = addrs[0]

Loading…
Cancel
Save