|
|
@ -27,6 +27,7 @@ import binascii |
|
|
|
import traceback |
|
|
|
import random |
|
|
|
import platform |
|
|
|
import threading |
|
|
|
|
|
|
|
from shadowsocks import encrypt, obfs, eventloop, shell, common, lru_cache |
|
|
|
from shadowsocks.common import pre_parse_header, parse_header |
|
|
@ -900,6 +901,9 @@ class TCPRelayHandler(object): |
|
|
|
if self._stage == STAGE_DESTROYED: |
|
|
|
logging.debug('ignore handle_event: destroyed') |
|
|
|
return |
|
|
|
if self._user is not None and self._user not in self._server.server_users: |
|
|
|
self.destroy() |
|
|
|
return |
|
|
|
# order is important |
|
|
|
if sock == self._remote_sock or sock == self._remote_sock_v6: |
|
|
|
if event & eventloop.POLL_ERR: |
|
|
@ -1000,6 +1004,8 @@ class TCPRelay(object): |
|
|
|
self.server_users = {} |
|
|
|
self.server_user_transfer_ul = {} |
|
|
|
self.server_user_transfer_dl = {} |
|
|
|
self.update_users_protocol_param = None |
|
|
|
self.update_users_acl = None |
|
|
|
self.server_connections = 0 |
|
|
|
self.protocol_data = obfs.obfs(config['protocol']).init_data() |
|
|
|
self.obfs_data = obfs.obfs(config['obfs']).init_data() |
|
|
@ -1020,16 +1026,7 @@ class TCPRelay(object): |
|
|
|
self._listen_port = listen_port |
|
|
|
|
|
|
|
if common.to_bytes(config['protocol']) in [b"auth_aes128_md5", b"auth_aes128_sha1"]: |
|
|
|
param = common.to_bytes(config['protocol_param']).split(b'#') |
|
|
|
if len(param) == 2: |
|
|
|
user_list = param[1].split(b',') |
|
|
|
if user_list: |
|
|
|
for user in user_list: |
|
|
|
items = user.split(b':') |
|
|
|
if len(items) == 2: |
|
|
|
uid = struct.pack('<I', int(items[0])) |
|
|
|
passwd = items[1] |
|
|
|
self.add_user(uid, passwd) |
|
|
|
self._update_users(None, None) |
|
|
|
|
|
|
|
addrs = socket.getaddrinfo(listen_addr, listen_port, 0, |
|
|
|
socket.SOCK_STREAM, socket.SOL_TCP) |
|
|
@ -1070,10 +1067,38 @@ class TCPRelay(object): |
|
|
|
self.server_connections += val |
|
|
|
logging.debug('server port %5d connections = %d' % (self._listen_port, self.server_connections,)) |
|
|
|
|
|
|
|
def get_ud(self): |
|
|
|
return (self.server_transfer_ul, self.server_transfer_dl) |
|
|
|
|
|
|
|
def get_users_ud(self): |
|
|
|
return (self.server_user_transfer_ul.copy(), self.server_user_transfer_dl.copy()) |
|
|
|
|
|
|
|
def _update_users(self, protocol_param, acl): |
|
|
|
if protocol_param is None: |
|
|
|
protocol_param = self._config['protocol_param'] |
|
|
|
param = common.to_bytes(protocol_param).split(b'#') |
|
|
|
if len(param) == 2: |
|
|
|
user_list = param[1].split(b',') |
|
|
|
if user_list: |
|
|
|
for user in user_list: |
|
|
|
items = user.split(b':') |
|
|
|
if len(items) == 2: |
|
|
|
user_int_id = int(items[0]) |
|
|
|
uid = struct.pack('<I', user_int_id) |
|
|
|
if acl is not None and user_int_id not in acl: |
|
|
|
self.del_user(uid) |
|
|
|
else: |
|
|
|
passwd = items[1] |
|
|
|
self.add_user(uid, passwd) |
|
|
|
|
|
|
|
def update_users(self, protocol_param, acl): |
|
|
|
self.update_users_protocol_param = protocol_param |
|
|
|
self.update_users_acl = acl |
|
|
|
|
|
|
|
def add_user(self, user, passwd): # user: binstr[4], passwd: str |
|
|
|
self.server_users[user] = common.to_bytes(passwd) |
|
|
|
|
|
|
|
def del_user(self, user, passwd): |
|
|
|
def del_user(self, user): |
|
|
|
if user in self.server_users: |
|
|
|
del self.server_users[user] |
|
|
|
|
|
|
@ -1189,6 +1214,10 @@ class TCPRelay(object): |
|
|
|
logging.info('closed TCP port %d', self._listen_port) |
|
|
|
for handler in list(self._fd_to_handlers.values()): |
|
|
|
handler.destroy() |
|
|
|
elif self.update_users_protocol_param is not None or self.update_users_acl is not None: |
|
|
|
self._update_users(self.update_users_protocol_param, self.update_users_acl) |
|
|
|
self.update_users_protocol_param = None |
|
|
|
self.update_users_acl = None |
|
|
|
self._sweep_timeout() |
|
|
|
|
|
|
|
def close(self, next_tick=False): |
|
|
|