add config "udp_timeout"
drop TCP over UDP query
This commit is contained in:
parent
4e43a4932d
commit
d47b0d47ea
2 changed files with 70 additions and 65 deletions
|
@ -236,6 +236,7 @@ def get_config(is_local):
|
||||||
config['obfs_param'] = to_str(config.get('obfs_param', ''))
|
config['obfs_param'] = to_str(config.get('obfs_param', ''))
|
||||||
config['port_password'] = config.get('port_password', None)
|
config['port_password'] = config.get('port_password', None)
|
||||||
config['timeout'] = int(config.get('timeout', 300))
|
config['timeout'] = int(config.get('timeout', 300))
|
||||||
|
config['udp_timeout'] = int(config.get('udp_timeout', config['timeout']))
|
||||||
config['fast_open'] = config.get('fast_open', False)
|
config['fast_open'] = config.get('fast_open', False)
|
||||||
config['workers'] = config.get('workers', 1)
|
config['workers'] = config.get('workers', 1)
|
||||||
config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid')
|
config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid')
|
||||||
|
|
|
@ -880,7 +880,7 @@ class UDPRelay(object):
|
||||||
self._method = config['method']
|
self._method = config['method']
|
||||||
self._timeout = config['timeout']
|
self._timeout = config['timeout']
|
||||||
self._is_local = is_local
|
self._is_local = is_local
|
||||||
self._cache = lru_cache.LRUCache(timeout=config['timeout'],
|
self._cache = lru_cache.LRUCache(timeout=config['udp_timeout'],
|
||||||
close_callback=self._close_client)
|
close_callback=self._close_client)
|
||||||
self._client_fd_to_server_addr = {}
|
self._client_fd_to_server_addr = {}
|
||||||
self._dns_cache = lru_cache.LRUCache(timeout=300)
|
self._dns_cache = lru_cache.LRUCache(timeout=300)
|
||||||
|
@ -1023,69 +1023,8 @@ class UDPRelay(object):
|
||||||
return
|
return
|
||||||
|
|
||||||
if type(data) is tuple:
|
if type(data) is tuple:
|
||||||
#(cmd, request_id, data)
|
return
|
||||||
#logging.info("UDP data %d %d %s" % (data[0], data[1], binascii.hexlify(data[2])))
|
return self._handle_tcp_over_udp(data, r_addr)
|
||||||
try:
|
|
||||||
self.server_transfer_ul += len(data[2])
|
|
||||||
if data[0] == 0:
|
|
||||||
if len(data[2]) >= 4:
|
|
||||||
for i in range(64):
|
|
||||||
req_id = random.randint(1, 65535)
|
|
||||||
if req_id not in self._reqid_to_hd:
|
|
||||||
break
|
|
||||||
if req_id in self._reqid_to_hd:
|
|
||||||
for i in range(64):
|
|
||||||
req_id = random.randint(1, 65535)
|
|
||||||
if type(self._reqid_to_hd[req_id]) is tuple:
|
|
||||||
break
|
|
||||||
# return req id
|
|
||||||
self._reqid_to_hd[req_id] = (data[2][0:4], None)
|
|
||||||
rsp_data = self._pack_rsp_data(CMD_RSP_CONNECT, req_id, RSP_STATE_CONNECTED)
|
|
||||||
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
|
||||||
self.write_to_server_socket(data_to_send, r_addr)
|
|
||||||
elif data[0] == CMD_CONNECT_REMOTE:
|
|
||||||
if len(data[2]) > 4 and data[1] in self._reqid_to_hd:
|
|
||||||
# create
|
|
||||||
if type(self._reqid_to_hd[data[1]]) is tuple:
|
|
||||||
if data[2][0:4] == self._reqid_to_hd[data[1]][0]:
|
|
||||||
handle = TCPRelayHandler(self, self._reqid_to_hd, self._fd_to_handlers,
|
|
||||||
self._eventloop, self._server_socket,
|
|
||||||
self._reqid_to_hd[data[1]][0], self._reqid_to_hd[data[1]][1],
|
|
||||||
self._config, self._dns_resolver, self._is_local)
|
|
||||||
self._reqid_to_hd[data[1]] = handle
|
|
||||||
handle.handle_client(r_addr, CMD_CONNECT, data[1], data[2])
|
|
||||||
handle.handle_client(r_addr, *data)
|
|
||||||
self.update_activity(handle)
|
|
||||||
else:
|
|
||||||
# disconnect
|
|
||||||
rsp_data = self._pack_rsp_data(CMD_DISCONNECT, data[1], RSP_STATE_EMPTY)
|
|
||||||
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
|
||||||
self.write_to_server_socket(data_to_send, r_addr)
|
|
||||||
else:
|
|
||||||
self.update_activity(self._reqid_to_hd[data[1]])
|
|
||||||
self._reqid_to_hd[data[1]].handle_client(r_addr, *data)
|
|
||||||
else:
|
|
||||||
# disconnect
|
|
||||||
rsp_data = self._pack_rsp_data(CMD_DISCONNECT, data[1], RSP_STATE_EMPTY)
|
|
||||||
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
|
||||||
self.write_to_server_socket(data_to_send, r_addr)
|
|
||||||
elif data[0] > CMD_CONNECT_REMOTE and data[0] <= CMD_DISCONNECT:
|
|
||||||
if data[1] in self._reqid_to_hd:
|
|
||||||
if type(self._reqid_to_hd[data[1]]) is tuple:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.update_activity(self._reqid_to_hd[data[1]])
|
|
||||||
self._reqid_to_hd[data[1]].handle_client(r_addr, *data)
|
|
||||||
else:
|
|
||||||
# disconnect
|
|
||||||
rsp_data = self._pack_rsp_data(CMD_DISCONNECT, data[1], RSP_STATE_EMPTY)
|
|
||||||
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
|
||||||
self.write_to_server_socket(data_to_send, r_addr)
|
|
||||||
return
|
|
||||||
except Exception as e:
|
|
||||||
trace = traceback.format_exc()
|
|
||||||
logging.error(trace)
|
|
||||||
return
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
header_result = parse_header(data)
|
header_result = parse_header(data)
|
||||||
|
@ -1105,6 +1044,7 @@ class UDPRelay(object):
|
||||||
|
|
||||||
addrs = self._dns_cache.get(server_addr, None)
|
addrs = self._dns_cache.get(server_addr, None)
|
||||||
if addrs is None:
|
if addrs is None:
|
||||||
|
# TODO async getaddrinfo
|
||||||
addrs = socket.getaddrinfo(server_addr, server_port, 0,
|
addrs = socket.getaddrinfo(server_addr, server_port, 0,
|
||||||
socket.SOCK_DGRAM, socket.SOL_UDP)
|
socket.SOCK_DGRAM, socket.SOL_UDP)
|
||||||
if not addrs:
|
if not addrs:
|
||||||
|
@ -1117,7 +1057,6 @@ class UDPRelay(object):
|
||||||
key = client_key(r_addr, af)
|
key = client_key(r_addr, af)
|
||||||
client = self._cache.get(key, None)
|
client = self._cache.get(key, None)
|
||||||
if not client:
|
if not client:
|
||||||
# TODO async getaddrinfo
|
|
||||||
if self._forbidden_iplist:
|
if self._forbidden_iplist:
|
||||||
if common.to_str(sa[0]) in self._forbidden_iplist:
|
if common.to_str(sa[0]) in self._forbidden_iplist:
|
||||||
logging.debug('IP %s is in forbidden list, drop' %
|
logging.debug('IP %s is in forbidden list, drop' %
|
||||||
|
@ -1163,6 +1102,71 @@ class UDPRelay(object):
|
||||||
else:
|
else:
|
||||||
shell.print_exception(e)
|
shell.print_exception(e)
|
||||||
|
|
||||||
|
def _handle_tcp_over_udp(self, data, r_addr):
|
||||||
|
#(cmd, request_id, data)
|
||||||
|
#logging.info("UDP data %d %d %s" % (data[0], data[1], binascii.hexlify(data[2])))
|
||||||
|
try:
|
||||||
|
self.server_transfer_ul += len(data[2])
|
||||||
|
if data[0] == 0:
|
||||||
|
if len(data[2]) >= 4:
|
||||||
|
for i in range(64):
|
||||||
|
req_id = random.randint(1, 65535)
|
||||||
|
if req_id not in self._reqid_to_hd:
|
||||||
|
break
|
||||||
|
if req_id in self._reqid_to_hd:
|
||||||
|
for i in range(64):
|
||||||
|
req_id = random.randint(1, 65535)
|
||||||
|
if type(self._reqid_to_hd[req_id]) is tuple:
|
||||||
|
break
|
||||||
|
# return req id
|
||||||
|
self._reqid_to_hd[req_id] = (data[2][0:4], None)
|
||||||
|
rsp_data = self._pack_rsp_data(CMD_RSP_CONNECT, req_id, RSP_STATE_CONNECTED)
|
||||||
|
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
||||||
|
self.write_to_server_socket(data_to_send, r_addr)
|
||||||
|
elif data[0] == CMD_CONNECT_REMOTE:
|
||||||
|
if len(data[2]) > 4 and data[1] in self._reqid_to_hd:
|
||||||
|
# create
|
||||||
|
if type(self._reqid_to_hd[data[1]]) is tuple:
|
||||||
|
if data[2][0:4] == self._reqid_to_hd[data[1]][0]:
|
||||||
|
handle = TCPRelayHandler(self, self._reqid_to_hd, self._fd_to_handlers,
|
||||||
|
self._eventloop, self._server_socket,
|
||||||
|
self._reqid_to_hd[data[1]][0], self._reqid_to_hd[data[1]][1],
|
||||||
|
self._config, self._dns_resolver, self._is_local)
|
||||||
|
self._reqid_to_hd[data[1]] = handle
|
||||||
|
handle.handle_client(r_addr, CMD_CONNECT, data[1], data[2])
|
||||||
|
handle.handle_client(r_addr, *data)
|
||||||
|
self.update_activity(handle)
|
||||||
|
else:
|
||||||
|
# disconnect
|
||||||
|
rsp_data = self._pack_rsp_data(CMD_DISCONNECT, data[1], RSP_STATE_EMPTY)
|
||||||
|
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
||||||
|
self.write_to_server_socket(data_to_send, r_addr)
|
||||||
|
else:
|
||||||
|
self.update_activity(self._reqid_to_hd[data[1]])
|
||||||
|
self._reqid_to_hd[data[1]].handle_client(r_addr, *data)
|
||||||
|
else:
|
||||||
|
# disconnect
|
||||||
|
rsp_data = self._pack_rsp_data(CMD_DISCONNECT, data[1], RSP_STATE_EMPTY)
|
||||||
|
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
||||||
|
self.write_to_server_socket(data_to_send, r_addr)
|
||||||
|
elif data[0] > CMD_CONNECT_REMOTE and data[0] <= CMD_DISCONNECT:
|
||||||
|
if data[1] in self._reqid_to_hd:
|
||||||
|
if type(self._reqid_to_hd[data[1]]) is tuple:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
self.update_activity(self._reqid_to_hd[data[1]])
|
||||||
|
self._reqid_to_hd[data[1]].handle_client(r_addr, *data)
|
||||||
|
else:
|
||||||
|
# disconnect
|
||||||
|
rsp_data = self._pack_rsp_data(CMD_DISCONNECT, data[1], RSP_STATE_EMPTY)
|
||||||
|
data_to_send = encrypt.encrypt_all(self._password, self._method, 1, rsp_data)
|
||||||
|
self.write_to_server_socket(data_to_send, r_addr)
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
trace = traceback.format_exc()
|
||||||
|
logging.error(trace)
|
||||||
|
return
|
||||||
|
|
||||||
def _handle_client(self, sock):
|
def _handle_client(self, sock):
|
||||||
data, r_addr = sock.recvfrom(BUF_SIZE)
|
data, r_addr = sock.recvfrom(BUF_SIZE)
|
||||||
if not data:
|
if not data:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue