def sendto(self, data, target_addr): try: ipaddress.IPv4Address(target_addr[0]) except ipaddress.AddressValueError: target_addr = DomainAddress(*target_addr) packet = socks5_serializer.pack_serializable(UdpPacket(0, 0, target_addr, data)) self.transport.sendto(packet, self.proxy_udp_addr)
def unpack(self, data, offset, unpack_list): address_type, = struct.unpack_from('>B', data, offset) offset += 1 if address_type == ADDRESS_TYPE_IPV4: host = socket.inet_ntoa(data[offset:offset + 4]) port, = struct.unpack_from('>H', data, offset + 4) offset += 6 address = UDPv4Address(host, port) elif address_type == ADDRESS_TYPE_DOMAIN_NAME: domain_length, = struct.unpack_from('>B', data, offset) offset += 1 try: host = data[offset:offset + domain_length] host = host.decode() except UnicodeDecodeError as e: raise InvalidAddressException( f'Invalid address: {host}') from e port, = struct.unpack_from('>H', data, offset + domain_length) offset += domain_length + 2 address = DomainAddress(host, port) elif address_type == ADDRESS_TYPE_IPV6: raise IPV6AddrError() else: raise InvalidAddressException('Invalid address type') unpack_list.append(address) return offset
def test_encode_decode_udp_packet(): rsv = 0 frag = 0 address = DomainAddress('tracker1.good-tracker.com', 8084) data = b'0x000' encoded = socks5_serializer.pack_serializable( UdpPacket(rsv, frag, address, data)) decoded, _ = socks5_serializer.unpack_serializable(UdpPacket, encoded) assert rsv == decoded.rsv assert frag == decoded.frag assert address == decoded.destination address = DomainAddress('tracker1.unicode-tracker\xc4\xe95\x11$\x00', 8084) encoded = socks5_serializer.pack_serializable( UdpPacket(rsv, frag, address, data)) decoded, _ = socks5_serializer.unpack_serializable(UdpPacket, encoded) assert rsv == decoded.rsv assert frag == decoded.frag assert address == decoded.destination
def test_encode_decode_command_request(): rsv = 0 address = DomainAddress('tracker1.good-tracker.com', 8084) rep = 0 version = 5 encoded = socks5_serializer.pack_serializable( CommandRequest(version, rep, rsv, address)) decoded, _ = socks5_serializer.unpack_serializable(CommandRequest, encoded) assert version == decoded.version assert rsv == decoded.rsv assert address == decoded.destination address = DomainAddress('tracker1.unicode-tracker\xc4\xe95\x11$\x00', 8084) encoded = socks5_serializer.pack_serializable( CommandResponse(version, rep, rsv, address)) decoded, _ = socks5_serializer.unpack_serializable(CommandResponse, encoded) assert version == decoded.version assert rsv == decoded.rsv assert address == decoded.bind
async def _connect_tcp(self, target_addr): try: socket.inet_aton(target_addr[0]) except (ValueError, OSError): target_addr = DomainAddress(*target_addr) request = CommandRequest(SOCKS_VERSION, REQ_CMD_CONNECT, 0, target_addr) data = await self._send(socks5_serializer.pack_serializable(request)) response, _ = socks5_serializer.unpack_serializable(CommandResponse, data) if response.version != SOCKS_VERSION: raise Socks5Error('Unsupported proxy server') if response.reply > 0: raise Socks5Error('TCP connect failed') self.connected_to = target_addr