fn maybe_probe()

in neqo-transport/src/connection/mod.rs [2251:2297]


    fn maybe_probe(
        &mut self,
        path: &PathRef,
        force_probe: bool,
        builder: &mut PacketBuilder,
        ack_end: usize,
        tokens: &mut Vec<RecoveryToken>,
        now: Instant,
    ) -> bool {
        let untracked = self.received_untracked && !self.state.connected();
        self.received_untracked = false;

        // Anything written after an ACK already elicits acknowledgment.
        // If we need to probe and nothing has been written, send a PING.
        if builder.len() > ack_end {
            return true;
        }

        let pto = path.borrow().rtt().pto(self.confirmed());
        let mut probe = if untracked && builder.packet_empty() || force_probe {
            // If we received an untracked packet and we aren't probing already
            // or the PTO timer fired: probe.
            true
        } else if !builder.packet_empty() {
            // The packet only contains an ACK.  Check whether we want to
            // force an ACK with a PING so we can stop tracking packets.
            self.loss_recovery.should_probe(pto, now)
        } else {
            false
        };

        if self.streams.need_keep_alive() {
            // We need to keep the connection alive, including sending a PING
            // again. If a PING is already scheduled (i.e. `probe` is `true`)
            // piggy back on it. If not, schedule one.
            probe |= self.idle_timeout.send_keep_alive(now, pto, tokens);
        }

        if probe {
            // Nothing ack-eliciting and we need to probe; send PING.
            debug_assert_ne!(builder.remaining(), 0);
            builder.encode_varint(FrameType::Ping);
            let stats = &mut self.stats.borrow_mut().frame_tx;
            stats.ping += 1;
        }
        probe
    }