fn write_frames()

in neqo-transport/src/connection/mod.rs [2302:2393]


    fn write_frames(
        &mut self,
        path: &PathRef,
        space: PacketNumberSpace,
        profile: &SendProfile,
        builder: &mut PacketBuilder,
        coalesced: bool, // Whether this packet is coalesced behind another one.
        now: Instant,
    ) -> (Vec<RecoveryToken>, bool, bool) {
        let mut tokens = Vec::new();
        let primary = path.borrow().is_primary();
        let mut ack_eliciting = false;

        if primary {
            let stats = &mut self.stats.borrow_mut().frame_tx;
            self.acks.write_frame(
                space,
                now,
                path.borrow().rtt().estimate(),
                builder,
                &mut tokens,
                stats,
            );
        }
        let ack_end = builder.len();

        // Avoid sending path validation probes until the handshake completes,
        // but send them even when we don't have space.
        let full_mtu = profile.limit() == path.borrow().plpmtu();
        if space == PacketNumberSpace::ApplicationData && self.state.connected() {
            // Path validation probes should only be padded if the full MTU is available.
            // The probing code needs to know so it can track that.
            if path.borrow_mut().write_frames(
                builder,
                &mut self.stats.borrow_mut().frame_tx,
                full_mtu,
                now,
            ) {
                builder.enable_padding(true);
            }
        }

        if profile.ack_only(space) {
            // If we are CC limited we can only send ACKs!
            return (tokens, false, false);
        }

        if primary {
            if space == PacketNumberSpace::ApplicationData {
                if self.state.connected()
                    && path.borrow().pmtud().needs_probe()
                    && !coalesced // Only send PMTUD probes using non-coalesced packets.
                    && full_mtu
                {
                    path.borrow_mut()
                        .pmtud_mut()
                        .send_probe(builder, &mut self.stats.borrow_mut());
                    ack_eliciting = true;
                }
                self.write_appdata_frames(builder, &mut tokens, now);
            } else {
                let stats = &mut self.stats.borrow_mut().frame_tx;
                self.crypto.write_frame(
                    space,
                    self.conn_params.sni_slicing_enabled(),
                    builder,
                    &mut tokens,
                    stats,
                );
            }
        }

        // Maybe send a probe now, either to probe for losses or to keep the connection live.
        let force_probe = profile.should_probe(space);
        ack_eliciting |= self.maybe_probe(path, force_probe, builder, ack_end, &mut tokens, now);
        // If this is not the primary path, this should be ack-eliciting.
        debug_assert!(primary || ack_eliciting);

        // Add padding.  Only pad 1-RTT packets so that we don't prevent coalescing.
        // And avoid padding packets that otherwise only contain ACK because adding PADDING
        // causes those packets to consume congestion window, which is not tracked (yet).
        // And avoid padding if we don't have a full MTU available.
        let stats = &mut self.stats.borrow_mut().frame_tx;
        let padded = if ack_eliciting && full_mtu && builder.pad() {
            stats.padding += 1;
            true
        } else {
            false
        };

        (tokens, ack_eliciting, padded)
    }