fn handle_short_packet()

in quic/s2n-quic-transport/src/connection/connection_impl.rs [1502:1626]


    fn handle_short_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedShort,
        random_generator: &mut Config::RandomGenerator,
        subscriber: &mut Config::EventSubscriber,
        packet_interceptor: &mut Config::PacketInterceptor,
        datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut Config::DcEndpoint,
        limits_endpoint: &mut Config::ConnectionLimits,
    ) -> Result<(), ProcessingError> {
        let mut publisher = self.event_context.publisher(datagram.timestamp, subscriber);

        //= https://www.rfc-editor.org/rfc/rfc9001#section-5.7
        //# Endpoints in either role MUST NOT decrypt 1-RTT packets from
        //# their peer prior to completing the handshake.

        //= https://www.rfc-editor.org/rfc/rfc9001#section-5.7
        //# A server MUST NOT process
        //# incoming 1-RTT protected packets before the TLS handshake is
        //# complete.

        //= https://www.rfc-editor.org/rfc/rfc9001#section-5.7
        //# Even if it has 1-RTT secrets, a client MUST NOT
        //# process incoming 1-RTT protected packets before the TLS handshake is
        //# complete.

        if !self.space_manager.is_handshake_complete() {
            let path = &self.path_manager[path_id];
            publisher.on_packet_dropped(event::builder::PacketDropped {
                reason: event::builder::PacketDropReason::HandshakeNotComplete {
                    path: path_event!(path, path_id),
                },
            });

            return Ok(());
        }

        //= https://www.rfc-editor.org/rfc/rfc9000#section-21.2
        //# Except for Initial and Stateless Resets, an endpoint only accepts
        //# packets that include a Destination Connection ID field that matches
        //# a value the endpoint previously chose.
        if datagram
            .destination_connection_id_classification
            .is_initial()
        {
            let path = &self.path_manager[path_id];
            publisher.on_packet_dropped(event::builder::PacketDropped {
                reason: event::builder::PacketDropReason::InitialConnectionIdInvalidSpace {
                    path: path_event!(path, path_id),
                    packet_type: event::builder::PacketType::OneRtt,
                },
            });
            return Err(ProcessingError::Other);
        }

        if let Some((space, handshake_status)) = self.space_manager.application_mut() {
            let packet = space.validate_and_decrypt_packet(
                packet,
                datagram,
                path_id,
                &self.path_manager[path_id],
                &mut publisher,
            )?;

            publisher.on_packet_received(event::builder::PacketReceived {
                packet_header: event::builder::PacketHeader::new(
                    packet.packet_number,
                    publisher.quic_version(),
                ),
            });

            // Connection Ids are issued to the peer after the handshake is
            // confirmed and the handshake space is discarded. Therefore only
            // short packets need to be processed for local_connection_id changes.
            self.path_manager[path_id].on_process_local_connection_id(
                path_id,
                &packet,
                &datagram.destination_connection_id,
                &mut publisher,
            );

            let processed_packet = space.handle_cleartext_payload(
                packet.packet_number,
                packet.payload,
                datagram,
                path_id,
                &mut self.path_manager,
                handshake_status,
                &mut self.local_id_registry,
                random_generator,
                &mut publisher,
                packet_interceptor,
            )?;

            // try to process any post-handshake messages
            if Config::ENDPOINT_TYPE.is_client() && processed_packet.contains_crypto {
                let space_manager = &mut self.space_manager;
                space_manager.post_handshake_crypto(
                    &mut self.path_manager,
                    &mut self.local_id_registry,
                    &mut self.limits,
                    datagram.timestamp,
                    &self.waker,
                    &mut publisher,
                    datagram_endpoint,
                    dc_endpoint,
                    limits_endpoint,
                )?;
            }
            // notify the connection a packet was processed
            self.on_processed_packet(&processed_packet, subscriber)?;
        } else {
            let path = &self.path_manager[path_id];
            publisher.on_packet_dropped(event::builder::PacketDropped {
                reason: event::builder::PacketDropReason::PacketSpaceDoesNotExist {
                    path: path_event!(path, path_id),
                    packet_type: event::builder::PacketType::OneRtt,
                },
            });
        }

        Ok(())
    }