def test_error_datagram(self): serialized = ErrorDatagram(ERROR_TYPE, b'1' * 20, b'1' * 48, b'FakeErrorType', b'more info').bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, ERROR_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.exception_type, 'FakeErrorType') self.assertEqual(decoded.response, 'more info')
def test_ping_response(self): serialized = ResponseDatagram(RESPONSE_TYPE, b'1' * 20, b'1' * 48, b'pong').bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, RESPONSE_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.response, b'pong')
def test_find_value_response(self): found_value_response = {b'2' * 48: [b'\x7f\x00\x00\x01']} serialized = ResponseDatagram(RESPONSE_TYPE, b'1' * 20, b'1' * 48, found_value_response).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, RESPONSE_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertDictEqual(decoded.response, found_value_response)
def test_ping_request_datagram(self): serialized = RequestDatagram(REQUEST_TYPE, b'1' * 20, b'1' * 48, b'ping', []).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, REQUEST_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.method, b'ping') self.assertListEqual(decoded.args, [{b'protocolVersion': 1}])
def test_find_node_response(self): closest_response = [(b'3' * 48, '1.2.3.4', 1234)] expected = [[b'3' * 48, b'1.2.3.4', 1234]] serialized = ResponseDatagram(RESPONSE_TYPE, b'1' * 20, b'1' * 48, closest_response).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, RESPONSE_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.response, expected)
def test_ping_request_datagram(self): self.assertRaises(ValueError, RequestDatagram.make_ping, b'1' * 48, b'1' * 21) self.assertRaises(ValueError, RequestDatagram.make_ping, b'1' * 47, b'1' * 20) self.assertEqual(20, len(RequestDatagram.make_ping(b'1' * 48).rpc_id)) serialized = RequestDatagram.make_ping(b'1' * 48, b'1' * 20).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, REQUEST_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.method, b'ping') self.assertListEqual(decoded.args, [{b'protocolVersion': 1}])
def test_find_value_request(self): serialized = RequestDatagram(REQUEST_TYPE, b'1' * 20, b'1' * 48, b'findValue', [b'2' * 48]).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, REQUEST_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.method, b'findValue') self.assertListEqual(decoded.args, [b'2' * 48, { b'protocolVersion': 1 }])
def test_store_request(self): self.assertRaises(ValueError, RequestDatagram.make_store, b'1' * 47, b'2' * 48, b'3' * 48, 3333, b'1' * 20) self.assertRaises(ValueError, RequestDatagram.make_store, b'1' * 48, b'2' * 49, b'3' * 48, 3333, b'1' * 20) self.assertRaises(ValueError, RequestDatagram.make_store, b'1' * 48, b'2' * 48, b'3' * 47, 3333, b'1' * 20) self.assertRaises(ValueError, RequestDatagram.make_store, b'1' * 48, b'2' * 48, b'3' * 48, -3333, b'1' * 20) self.assertRaises(ValueError, RequestDatagram.make_store, b'1' * 48, b'2' * 48, b'3' * 48, 3333, b'1' * 21) serialized = RequestDatagram.make_store(b'1' * 48, b'2' * 48, b'3' * 48, 3333, b'1' * 20).bencode() decoded = decode_datagram(serialized) self.assertEqual(decoded.packet_type, REQUEST_TYPE) self.assertEqual(decoded.rpc_id, b'1' * 20) self.assertEqual(decoded.node_id, b'1' * 48) self.assertEqual(decoded.method, b'store')
def datagram_received(self, datagram: bytes, address: typing.Tuple[str, int]) -> None: try: message = decode_datagram(datagram) except (ValueError, TypeError): self.peer_manager.report_failure(address[0], address[1]) log.warning("Couldn't decode dht datagram from %s: %s", address, binascii.hexlify(datagram).decode()) return if isinstance(message, RequestDatagram): self.handle_request_datagram(address, message) elif isinstance(message, ErrorDatagram): self.handle_error_datagram(address, message) else: assert isinstance(message, ResponseDatagram), "sanity" self.handle_response_datagram(address, message)