async def send_first_handshake_packet(self, receiver_endpoint: Endpoint) -> None: outgoing_packet = OutgoingPacket( self.handshake_participant.first_packet_to_send, receiver_endpoint, ) await self.outgoing_packet_send_channel.send(outgoing_packet)
async def test_packet_encoder(): packet_send_channel, packet_receive_channel = trio.open_memory_channel(1) datagram_send_channel, datagram_receive_channel = trio.open_memory_channel(1) service = PacketEncoder(packet_receive_channel, datagram_send_channel) async with background_trio_service(service): receiver_endpoint = EndpointFactory() outgoing_packet = OutgoingPacket( packet=AuthTagPacketFactory(), receiver_endpoint=receiver_endpoint, ) await packet_send_channel.send(outgoing_packet) with trio.fail_after(0.5): outgoing_datagram = await datagram_receive_channel.receive() assert outgoing_datagram.datagram == outgoing_packet.packet.to_wire_bytes() assert outgoing_datagram.receiver_endpoint.ip_address == receiver_endpoint.ip_address assert outgoing_datagram.receiver_endpoint.port == receiver_endpoint.port
async def handle_outgoing_message_post_handshake(self, outgoing_message: OutgoingMessage, ) -> None: if not self.is_post_handshake: raise ValueError("Can only handle message post handshake") if self.session_keys is None: raise TypeError("session_keys are None even though handshake has been completed") packet = AuthTagPacket.prepare( tag=compute_tag(self.local_node_id, self.remote_node_id), auth_tag=get_random_auth_tag(), message=outgoing_message.message, key=self.session_keys.encryption_key, ) outgoing_packet = OutgoingPacket( packet, outgoing_message.receiver_endpoint, ) self.logger.debug("Sending %s", outgoing_message) await self.outgoing_packet_send_channel.send(outgoing_packet)
async def handle_incoming_packet_during_handshake(self, incoming_packet: IncomingPacket, ) -> None: if not self.is_during_handshake: raise ValueError("Can only handle packets during handshake") if self.handshake_participant is None: raise TypeError("handshake_participant is None even though handshake is in progress") packet = incoming_packet.packet if self.handshake_participant.is_response_packet(packet): self.logger.debug("Received %s as handshake response", packet.__class__.__name__) else: self.logger.debug("Dropping %s unexpectedly received during handshake", incoming_packet) return try: handshake_result = self.handshake_participant.complete_handshake(packet) except HandshakeFailure as handshake_failure: self.logger.warning( "Handshake with %s has failed: %s", encode_hex(self.remote_node_id), handshake_failure, ) raise # let the service fail else: self.logger.info("Handshake with %s was successful", encode_hex(self.remote_node_id)) self.handshake_successful_event.set() # copy message backlog before we reset it outgoing_message_backlog = tuple(self.outgoing_message_backlog) self.reset_handshake_state() self.session_keys = handshake_result.session_keys if not self.is_post_handshake: raise Exception( "Invariant: As session_keys are set now, peer packer is in post handshake state" ) if handshake_result.enr is not None: self.logger.debug("Updating ENR in DB with %r", handshake_result.enr) await self.enr_db.insert_or_update(handshake_result.enr) if handshake_result.auth_header_packet is not None: outgoing_packet = OutgoingPacket( handshake_result.auth_header_packet, incoming_packet.sender_endpoint, ) self.logger.debug( "Sending %s packet to let peer complete handshake", outgoing_packet, ) await self.outgoing_packet_send_channel.send(outgoing_packet) if handshake_result.message: incoming_message = IncomingMessage( handshake_result.message, incoming_packet.sender_endpoint, self.remote_node_id, ) self.logger.debug("Received %s during handshake", incoming_message) await self.incoming_message_send_channel.send(incoming_message) self.logger.debug("Sending %d messages from backlog", len(outgoing_message_backlog)) for outgoing_message in outgoing_message_backlog: await self.handle_outgoing_message(outgoing_message)