fn on_transmit_impl()

in quic/s2n-quic-transport/src/sync/data_sender.rs [380:464]


    fn on_transmit_impl<W: WriteContext>(
        &mut self,
        writer_context: Writer::Context,
        context: &mut W,
    ) -> Result<(), OnTransmitError> {
        let constraint = context.transmission_constraint();

        let mut transmitted_lost = false;
        // try to retransmit any lost ranges first
        if constraint.can_retransmit() {
            transmitted_lost = self.transmissions.transmit_set(
                &self.buffer,
                &mut self.lost,
                &mut self.state,
                writer_context,
                context,
            )?;
        }

        let is_blocked = self.flow_controller().is_blocked();

        // try to transmit the enqueued ranges
        let total_len = self.buffer.total_len();

        let starting_transmission_offset = self.transmission_offset;

        if !is_blocked && constraint.can_transmit() && self.transmission_offset < total_len {
            let mut viewer = self.buffer.viewer();
            self.transmission_offset = self
                .transmissions
                .transmit_interval(
                    &mut viewer,
                    (self.transmission_offset..total_len).into(),
                    &mut self.state,
                    writer_context,
                    context,
                )?
                .end_exclusive();
        }

        if Writer::WRITES_FIN && self.state.can_transmit_fin(constraint, is_blocked) {
            self.transmissions.transmit_fin(
                &self.buffer,
                &mut self.state,
                writer_context,
                context,
            )?;
        }

        // If the current transmission is a loss recovery probe, we can include some already
        // transmitted, unacknowledged data in the probe packet since there is a higher likelihood
        // this data has been lost. If lost data has already been written to the packet, we
        // skip this feature as an optimization to avoid having to filter out already written
        // lost data. Since it is unlikely there is lost data requiring retransmission at the
        // same time as a probe transmission is being sent, this optimization does not have
        // much impact on the effectiveness of this feature.
        let retransmit_unacked_data_in_probe = Writer::RETRANSMIT_IN_PROBE
            && context.transmission_mode().is_loss_recovery_probing()
            && !transmitted_lost;

        if retransmit_unacked_data_in_probe {
            let mut viewer = self.buffer.viewer();

            for interval in self.pending.intervals() {
                if interval.start_inclusive() >= starting_transmission_offset {
                    // Don't write data we've already written to this packet
                    break;
                }

                let interval_end = interval.end_exclusive().min(starting_transmission_offset);

                self.transmissions.transmit_interval(
                    &mut viewer,
                    (interval.start_inclusive()..interval_end).into(),
                    &mut self.state,
                    writer_context,
                    context,
                )?;
            }
        }

        self.check_integrity();

        Ok(())
    }