Beispiel #1
0
 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)
Beispiel #2
0
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
Beispiel #3
0
    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)
Beispiel #4
0
    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)