async def PacketEncoder( manager: ManagerAPI, outbound_packet_receive_channel: ReceiveChannel[OutboundPacket], outbound_datagram_send_channel: SendChannel[OutboundDatagram], ) -> None: """Encodes outbound packets to datagrams.""" logger = logging.getLogger("ddht.v5.channel_services.PacketEncoder") async with outbound_packet_receive_channel, outbound_datagram_send_channel: async for packet, endpoint in outbound_packet_receive_channel: outbound_datagram = OutboundDatagram(packet.to_wire_bytes(), endpoint) logger.debug(f"Encoded {packet.__class__.__name__} for {endpoint}") await outbound_datagram_send_channel.send(outbound_datagram)
async def test_client_handles_malformed_datagrams(tester, datagram_bytes): bob = tester.node() async with bob.client() as bob_client: alice = tester.node() alice.enr_db.set_enr(bob.enr) bob.enr_db.set_enr(alice.enr) async with alice.client(): async with alice.events.ping_received.subscribe() as subscription: await bob_client._outbound_datagram_send_channel.send( OutboundDatagram(datagram_bytes, alice.endpoint)) request_id = await bob_client.send_ping( alice.endpoint, alice.node_id) ping = await subscription.receive() assert ping.message.request_id == request_id
async def test_datagram_sender(socket_pair): sending_socket, receiving_socket = socket_pair receiver_endpoint = receiving_socket.getsockname() sender_endpoint = sending_socket.getsockname() send_channel, receive_channel = trio.open_memory_channel(1) async with background_trio_service( DatagramSender(receive_channel, sending_socket)): outbound_datagram = OutboundDatagram( b"some packet", Endpoint(inet_aton(receiver_endpoint[0]), receiver_endpoint[1]), ) await send_channel.send(outbound_datagram) with trio.fail_after(0.5): data, sender = await receiving_socket.recvfrom(1024) assert data == outbound_datagram.datagram assert sender == sender_endpoint
async def run(self) -> None: async with self._outbound_envelope_receive_channel: async with self._outbound_datagram_send_channel: async for packet, endpoint in self._outbound_envelope_receive_channel: outbound_datagram = OutboundDatagram( packet.to_wire_bytes(), endpoint) self.logger.debug2( "Encoded %s for %s", packet.__class__.__name__, endpoint, ) try: await self._outbound_datagram_send_channel.send( outbound_datagram) except trio.BrokenResourceError: self.logger.debug( "EnvelopeEncoder exiting due to `trio.BrokenResourceError`" ) self.manager.cancel() return
async def test_client_handles_malformed_datagrams(tester, datagram_bytes): bob = tester.node() async with bob.client() as bob_client: alice = tester.node() alice.enr_db.set_enr(bob.enr) bob.enr_db.set_enr(alice.enr) async with alice.client(): async with alice.events.ping_received.subscribe() as subscription: await bob_client._outbound_datagram_send_channel.send( OutboundDatagram(datagram_bytes, alice.endpoint) ) # Give the node a minute to crash if it's going to crash for _ in range(100): await trio.lowlevel.checkpoint() request_id = await bob_client.send_ping(alice.node_id, alice.endpoint) # Now fetch the ping message that still should have come through. with trio.fail_after(1): ping = await subscription.receive() assert ping.message.request_id == request_id