fn process_new_acked_packets, Pub: event::ConnectionPublisher>()

in quic/s2n-quic-transport/src/recovery/manager.rs [622:731]


    fn process_new_acked_packets<Ctx: Context<Config>, Pub: event::ConnectionPublisher>(
        &mut self,
        newly_acked_packets: &SmallVec<
            [PacketDetails<packet_info_type!()>; ACKED_PACKETS_INITIAL_CAPACITY],
        >,
        new_largest_packet: bool,
        timestamp: Timestamp,
        ecn_counts: Option<EcnCounts>,
        random_generator: &mut Config::RandomGenerator,
        context: &mut Ctx,
        publisher: &mut Pub,
    ) {
        //= https://www.rfc-editor.org/rfc/rfc9002#section-6.1.2
        //# Once a later packet within the same packet number space has been
        //# acknowledged, an endpoint SHOULD declare an earlier packet lost if it
        //# was sent a threshold amount of time in the past.
        self.detect_and_remove_lost_packets(timestamp, random_generator, context, publisher);

        let current_path_id = context.path_id();
        let is_handshake_confirmed = context.is_handshake_confirmed();
        let mut current_path_acked_bytes = 0;
        let mut current_path_largest_newly_acked = None;
        let mut newly_acked_ecn_counts = EcnCounts::default();

        for (packet_number, acked_packet_info) in newly_acked_packets {
            let path = context.path_mut_by_id(acked_packet_info.path_id);

            let sent_bytes = acked_packet_info.sent_bytes as usize;
            newly_acked_ecn_counts.increment(acked_packet_info.ecn);

            if acked_packet_info.path_id == current_path_id {
                current_path_acked_bytes += sent_bytes;

                if current_path_largest_newly_acked.map_or(true, |(pn, _)| packet_number > pn) {
                    current_path_largest_newly_acked = Some((packet_number, acked_packet_info));
                }
            } else if sent_bytes > 0 {
                path.congestion_controller.on_ack(
                    acked_packet_info.time_sent,
                    sent_bytes,
                    acked_packet_info.cc_packet_info,
                    &path.rtt_estimator,
                    random_generator,
                    timestamp,
                    &mut congestion_controller::PathPublisher::new(
                        publisher,
                        acked_packet_info.path_id,
                    ),
                );
            }

            //= https://www.rfc-editor.org/rfc/rfc9002#section-6.2.1
            //# The PTO backoff factor is reset when an acknowledgment is received,
            //# except in the following case.  A server might take longer to respond
            //# to packets during the handshake than otherwise.  To protect such a
            //# server from repeated client probes, the PTO backoff is not reset at a
            //# client that is not yet certain that the server has finished
            //# validating the client's address.  That is, a client does not reset
            //# the PTO backoff factor on receiving acknowledgments in Initial
            //# packets.
            if path.is_peer_validated() {
                path.reset_pto_backoff();
            }
        }

        //= https://www.rfc-editor.org/rfc/rfc9002#section-6.2.1
        //# A sender SHOULD restart its PTO timer every time an ack-eliciting
        //# packet is sent or acknowledged,

        // The pseudocode in https://www.rfc-editor.org/rfc/rfc9002.html#section-a.7 does
        // not distinguish between ack-eliciting packets for determining if the PTO timer should
        // be restarted. This behavior is preferred, as detect_and_remove_lost_packets() will
        // cancel the loss timer, and there may still be ack eliciting packets pending that
        // require a PTO timer for recovery.
        self.update_pto_timer(context.active_path(), timestamp, is_handshake_confirmed);

        debug_assert!(
            !newly_acked_packets.is_empty(),
            "this method assumes there was at least one newly-acked packet"
        );

        //= https://www.rfc-editor.org/rfc/rfc9000#section-13.4.2.1
        //# Validating ECN counts from reordered ACK frames can result in failure.
        //# An endpoint MUST NOT fail ECN validation as a result of processing an
        //# ACK frame that does not increase the largest acknowledged packet number.
        if new_largest_packet {
            self.process_ecn(
                newly_acked_ecn_counts,
                ecn_counts,
                timestamp,
                context,
                publisher,
            );
        }

        if current_path_acked_bytes > 0 {
            let (_, largest_newly_acked) = current_path_largest_newly_acked
                .expect("At least some bytes were acknowledged on the current path");
            let path = context.path_mut();
            path.congestion_controller.on_ack(
                largest_newly_acked.time_sent,
                current_path_acked_bytes,
                largest_newly_acked.cc_packet_info,
                &path.rtt_estimator,
                random_generator,
                timestamp,
                &mut congestion_controller::PathPublisher::new(publisher, current_path_id),
            );
        }
    }