def _handle_client(self, sock): data, r_addr = sock.recvfrom(BUF_SIZE) if not data: logging.debug('UDP handle_client: data is empty') return if not self._is_local: addrlen = len(r_addr[0]) if addrlen > 255: # drop return data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data try: response = cryptor.encrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug("UDP handle_client: encrypt data failed") return if not response: return else: try: data, key, iv = cryptor.decrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug('UDP handle_client: decrypt data failed') return if not data: return header_result = parse_header(data) if header_result is None: return addrtype, dest_addr, dest_port, header_length = header_result if self._is_tunnel: # remove ss header response = data[header_length:] else: response = b'\x00\x00\x00' + data client_addr = self._client_fd_to_server_addr.get(sock.fileno()) if self._stat_callback: activity = { 'remote_address': client_addr, 'local_address': r_addr[0], 'protocal': 'UDP', 'type': 'UP', 'traffic': len(data), 'time': datetime.datetime.today().strftime('%Y-%m-%d %H:%M:%S') } self._stat_callback(self._listen_port, activity) if client_addr: logging.debug("send udp response to %s:%d" % (client_addr[0], client_addr[1])) self._server_socket.sendto(response, client_addr) else: # this packet is from somewhere else we know # simply drop that packet pass
def _handle_client(self, sock): data, r_addr = sock.recvfrom(BUF_SIZE) if not data: logging.debug('UDP handle_client: data is empty') return if self._stat_callback: self._stat_callback(self._listen_port, len(data)) if not self._is_local: addrlen = len(r_addr[0]) # 域名规范:域名不能超过255个字符。其中顶级域名不能超过63字符 if addrlen > 255: # drop return # pack_addr(r_addr[0]):把r_addr[0]打包成shadowvpn的专用的地址header,追加到r_addr[0]头部。 # struct.pack('>H', r_addr[1]):打包成Big-Endian格式 data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data try: response = cryptor.encrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug("UDP handle_client: encrypt data failed") return if not response: return # 本地端收到服务端发来的加密udp else: try: data, key, iv = cryptor.decrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug('UDP handle_client: decrypt data failed') return if not data: return header_result = parse_header(data) if header_result is None: return addrtype, dest_addr, dest_port, header_length = header_result if self._is_tunnel: # remove ss header response = data[header_length:] else: # addrtype, dest_addr, dest_port, header_length = header_result # 还原为标准的udp数据报格式,加上首3个字节 response = b'\x00\x00\x00' + data client_addr = self._client_fd_to_server_addr.get(sock.fileno()) if client_addr: logging.debug("send udp response to %s:%d" % (client_addr[0], client_addr[1])) self._server_socket.sendto(response, client_addr) else: # this packet is from somewhere else we know # simply drop that packet pass
def _handle_client(self, sock): data, r_addr = sock.recvfrom(BUF_SIZE) if not data: logging.debug('U[%d] UDP handle_client: data is empty' % self._config['server_port']) return if self._stat_callback: self._stat_callback(self._listen_port, len(data)) if not self._is_local: addrlen = len(r_addr[0]) if addrlen > 255: # drop return data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data try: response = cryptor.encrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug("UDP handle_client: encrypt data failed") return if not response: return else: try: data, key, iv = cryptor.decrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug('UDP handle_client: decrypt data failed') return if not data: return header_result = parse_header(data) if header_result is None: return addrtype, dest_addr, dest_port, header_length = header_result if self._is_tunnel: # remove ss header response = data[header_length:] else: response = b'\x00\x00\x00' + data client_addr = self._client_fd_to_server_addr.get(sock.fileno()) if client_addr: logging.debug("send udp response to %s:%d" % (client_addr[0], client_addr[1])) self._server_socket.sendto(response, client_addr) else: # this packet is from somewhere else we know # simply drop that packet pass
def _handle_client(self, sock): data, r_addr = sock.recvfrom(BUF_SIZE) if not data: logging.debug('UDP handle_client: data is empty') return if self._stat_callback: self._stat_callback(self._listen_port, len(data)) if not self._is_local: addrlen = len(r_addr[0]) if addrlen > 255: # drop return data = pack_addr(r_addr[0]) + struct.pack('>H', r_addr[1]) + data try: response = cryptor.encrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug("UDP handle_client: encrypt data failed") return if not response: return else: try: data, key, iv = cryptor.decrypt_all(self._password, self._method, data, self._crypto_path) except Exception: logging.debug('UDP handle_client: decrypt data failed') return if not data: return header_result = parse_header(data) if header_result is None: return addrtype, dest_addr, dest_port, header_length = header_result if self._is_tunnel: # remove ss header response = data[header_length:] else: response = b'\x00\x00\x00' + data client_addr = self._client_fd_to_server_addr.get(sock.fileno()) if client_addr: logging.debug("send udp response to %s:%d" % (client_addr[0], client_addr[1])) self._server_socket.sendto(response, client_addr) else: # this packet is from somewhere else we know # simply drop that packet pass
def test(): import time import threading import struct from shadowsocks import cryptor logging.basicConfig(level=5, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') enc = [] eventloop.TIMEOUT_PRECISION = 1 def run_server(): config = { 'server': '127.0.0.1', 'local_port': 1081, 'port_password': { '8381': 'foobar1', '8382': 'foobar2' }, 'method': 'aes-256-cfb', 'manager_address': '127.0.0.1:6001', 'timeout': 60, 'fast_open': False, 'verbose': 2 } manager = Manager(config) enc.append(manager) manager.run() t = threading.Thread(target=run_server) t.start() time.sleep(1) manager = enc[0] cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cli.connect(('127.0.0.1', 6001)) # test add and remove time.sleep(1) cli.send(b'add: {"server_port":7001, "password":"******"}') time.sleep(1) assert 7001 in manager._relays data, addr = cli.recvfrom(1506) assert b'ok' in data cli.send(b'remove: {"server_port":8381}') time.sleep(1) assert 8381 not in manager._relays data, addr = cli.recvfrom(1506) assert b'ok' in data logging.info('add and remove test passed') # test statistics for TCP header = common.pack_addr(b'google.com') + struct.pack('>H', 80) data = cryptor.encrypt_all(b'asdfadsfasdf', 'aes-256-cfb', header + b'GET /\r\n\r\n') tcp_cli = socket.socket() tcp_cli.connect(('127.0.0.1', 7001)) tcp_cli.send(data) tcp_cli.recv(4096) tcp_cli.close() data, addr = cli.recvfrom(1506) data = common.to_str(data) assert data.startswith('stat: ') data = data.split('stat:')[1] stats = shell.parse_json_in_str(data) assert '7001' in stats logging.info('TCP statistics test passed') # test statistics for UDP header = common.pack_addr(b'127.0.0.1') + struct.pack('>H', 80) data = cryptor.encrypt_all(b'foobar2', 'aes-256-cfb', header + b'test') udp_cli = socket.socket(type=socket.SOCK_DGRAM) udp_cli.sendto(data.encode(), ('127.0.0.1', 8382)) tcp_cli.close() data, addr = cli.recvfrom(1506) data = common.to_str(data) assert data.startswith('stat: ') data = data.split('stat:')[1] stats = json.loads(data) assert '8382' in stats logging.info('UDP statistics test passed') manager._loop.stop() t.join()
def test(): import time import threading import struct from shadowsocks import cryptor logging.basicConfig(level=5, format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%Y-%m-%d %H:%M:%S') enc = [] eventloop.TIMEOUT_PRECISION = 1 def run_server(): config = { 'server': '127.0.0.1', 'local_port': 1081, 'port_password': { '8381': 'foobar1', '8382': 'foobar2' }, 'method': 'aes-256-cfb', 'manager_address': '127.0.0.1:6001', 'timeout': 60, 'fast_open': False, 'verbose': 2 } manager = Manager(config) enc.append(manager) manager.run() t = threading.Thread(target=run_server) t.start() time.sleep(1) manager = enc[0] cli = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) cli.connect(('127.0.0.1', 6001)) # test add and remove time.sleep(1) cli.send(b'add: {"server_port":7001, "password":"******"}') time.sleep(1) assert 7001 in manager._relays data, addr = cli.recvfrom(1506) assert b'ok' in data cli.send(b'remove: {"server_port":8381}') time.sleep(1) assert 8381 not in manager._relays data, addr = cli.recvfrom(1506) assert b'ok' in data logging.info('add and remove test passed') # test statistics for TCP header = common.pack_addr(b'google.com') + struct.pack('>H', 80) data = cryptor.encrypt_all(b'asdfadsfasdf', 'aes-256-cfb', header + b'GET /\r\n\r\n') tcp_cli = socket.socket() tcp_cli.connect(('127.0.0.1', 7001)) tcp_cli.send(data) tcp_cli.recv(4096) tcp_cli.close() data, addr = cli.recvfrom(1506) data = common.to_str(data) assert data.startswith('stat: ') data = data.split('stat:')[1] stats = shell.parse_json_in_str(data) assert '7001' in stats logging.info('TCP statistics test passed') # test statistics for UDP header = common.pack_addr(b'127.0.0.1') + struct.pack('>H', 80) data = cryptor.encrypt_all(b'foobar2', 'aes-256-cfb', header + b'test') udp_cli = socket.socket(type=socket.SOCK_DGRAM) udp_cli.sendto(data, ('127.0.0.1', 8382)) tcp_cli.close() data, addr = cli.recvfrom(1506) data = common.to_str(data) assert data.startswith('stat: ') data = data.split('stat:')[1] stats = json.loads(data) assert '8382' in stats logging.info('UDP statistics test passed') manager._loop.stop() t.join()