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['port_password'] = config.get('port_password', None) | ||||
|     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['workers'] = config.get('workers', 1) | ||||
|     config['pid-file'] = config.get('pid-file', '/var/run/shadowsocks.pid') | ||||
|  |  | |||
|  | @ -880,7 +880,7 @@ class UDPRelay(object): | |||
|         self._method = config['method'] | ||||
|         self._timeout = config['timeout'] | ||||
|         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) | ||||
|         self._client_fd_to_server_addr = {} | ||||
|         self._dns_cache = lru_cache.LRUCache(timeout=300) | ||||
|  | @ -1023,69 +1023,8 @@ class UDPRelay(object): | |||
|                 return | ||||
| 
 | ||||
|             if type(data) is tuple: | ||||
|                 #(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 | ||||
|                 return | ||||
|                 return self._handle_tcp_over_udp(data, r_addr) | ||||
| 
 | ||||
|         try: | ||||
|             header_result = parse_header(data) | ||||
|  | @ -1105,6 +1044,7 @@ class UDPRelay(object): | |||
| 
 | ||||
|         addrs = self._dns_cache.get(server_addr, None) | ||||
|         if addrs is None: | ||||
|             # TODO async getaddrinfo | ||||
|             addrs = socket.getaddrinfo(server_addr, server_port, 0, | ||||
|                                        socket.SOCK_DGRAM, socket.SOL_UDP) | ||||
|             if not addrs: | ||||
|  | @ -1117,7 +1057,6 @@ class UDPRelay(object): | |||
|         key = client_key(r_addr, af) | ||||
|         client = self._cache.get(key, None) | ||||
|         if not client: | ||||
|             # TODO async getaddrinfo | ||||
|             if self._forbidden_iplist: | ||||
|                 if common.to_str(sa[0]) in self._forbidden_iplist: | ||||
|                     logging.debug('IP %s is in forbidden list, drop' % | ||||
|  | @ -1163,6 +1102,71 @@ class UDPRelay(object): | |||
|             else: | ||||
|                 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): | ||||
|         data, r_addr = sock.recvfrom(BUF_SIZE) | ||||
|         if not data: | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue