fn write_pkt_type(&self) -> Result<packet::Type> {
        // On error send packet in the latest epoch available, but only send
        // 1-RTT ones when the handshake is completed.
        if self
            .local_error
            .as_ref()
            .map_or(false, |conn_err| !conn_err.is_app)
        {
            let epoch = match self.handshake.lock().unwrap().write_level() {
                crypto::Level::Initial => packet::EPOCH_INITIAL,
                crypto::Level::ZeroRTT => unreachable!(),
                crypto::Level::Handshake => packet::EPOCH_HANDSHAKE,
                crypto::Level::OneRTT => packet::EPOCH_APPLICATION,
            };

            if epoch == packet::EPOCH_APPLICATION && !self.is_established() {
                // Downgrade the epoch to handshake as the handshake is not
                // completed yet.
                return Ok(packet::Type::Handshake);
            }

            return Ok(packet::Type::from_epoch(epoch));
        }

        for epoch in packet::EPOCH_INITIAL..packet::EPOCH_COUNT {
            // Only send packets in a space when we have the send keys for it.
            if self.pkt_num_spaces[epoch].crypto_seal.is_none() {
                continue;
            }

            // We are ready to send data for this packet number space.
            if self.pkt_num_spaces[epoch].ready() {
                return Ok(packet::Type::from_epoch(epoch));
            }

            // There are lost frames in this packet number space.
            if !self.recovery.lost[epoch].is_empty() {
                return Ok(packet::Type::from_epoch(epoch));
            }

            // We need to send PTO probe packets.
            if self.recovery.loss_probes[epoch] > 0 {
                return Ok(packet::Type::from_epoch(epoch));
            }
        }

        // If there are flushable, almost full or blocked streams, use the
        // Application epoch.
        if (self.is_established() || self.is_in_early_data()) &&
            ((self.is_server && !self.handshake_done_sent) ||
                self.almost_full ||
                self.blocked_limit.is_some() ||
                self.dgram_send_queue.has_pending() ||
                self.local_error
                    .as_ref()
                    .map_or(false, |conn_err| conn_err.is_app) ||
                self.streams.should_update_max_streams_bidi() ||
                self.streams.should_update_max_streams_uni() ||
                self.streams.has_flushable() ||
                self.streams.has_almost_full() ||
                self.streams.has_blocked() ||
                self.streams.has_reset() ||
                self.streams.has_stopped())
        {
            if self.is_in_early_data() && !self.is_server {
                return Ok(packet::Type::ZeroRTT);
            }

            return Ok(packet::Type::Short);
        }

        Err(Error::Done)
    }
/// Selects the packet type for the next outgoing packet.
Selects the packet type for the next outgoing packet.
Selects the packet type for the next outgoing packet .
fn write_pkt_type(&self) -> Result<packet::Type> {
        // On error send packet in the latest epoch available, but only send
        // 1-RTT ones when the handshake is completed.
        if self
            .local_error
            .as_ref()
            .map_or(false, |conn_err| !conn_err.is_app)
        {
            let epoch = match self.handshake.lock().unwrap().write_level() {
                crypto::Level::Initial => packet::EPOCH_INITIAL,
                crypto::Level::ZeroRTT => unreachable!(),
                crypto::Level::Handshake => packet::EPOCH_HANDSHAKE,
                crypto::Level::OneRTT => packet::EPOCH_APPLICATION,
            };
            if epoch == packet::EPOCH_APPLICATION && !self.is_established() {
                // Downgrade the epoch to handshake as the handshake is not
                // completed yet.
                return Ok(packet::Type::Handshake);
            }
            return Ok(packet::Type::from_epoch(epoch));
        }
        for epoch in packet::EPOCH_INITIAL..packet::EPOCH_COUNT {
            // Only send packets in a space when we have the send keys for it.
            if self.pkt_num_spaces[epoch].crypto_seal.is_none() {
                continue;
            }
            // We are ready to send data for this packet number space.
            if self.pkt_num_spaces[epoch].ready() {
                return Ok(packet::Type::from_epoch(epoch));
            }
            // There are lost frames in this packet number space.
            if !self.recovery.lost[epoch].is_empty() {
                return Ok(packet::Type::from_epoch(epoch));
            }
            // We need to send PTO probe packets.
            if self.recovery.loss_probes[epoch] > 0 {
                return Ok(packet::Type::from_epoch(epoch));
            }
        }
        // If there are flushable, almost full or blocked streams, use the
        // Application epoch.
        if (self.is_established() || self.is_in_early_data()) &&
            ((self.is_server && !self.handshake_done_sent) ||
                self.almost_full ||
                self.blocked_limit.is_some() ||
                self.dgram_send_queue.has_pending() ||
                self.local_error
                    .as_ref()
                    .map_or(false, |conn_err| conn_err.is_app) ||
                self.streams.should_update_max_streams_bidi() ||
                self.streams.should_update_max_streams_uni() ||
                self.streams.has_flushable() ||
                self.streams.has_almost_full() ||
                self.streams.has_blocked() ||
                self.streams.has_reset() ||
                self.streams.has_stopped())
        {
            if self.is_in_early_data() && !self.is_server {
                return Ok(packet::Type::ZeroRTT);
            }
            return Ok(packet::Type::Short);
        }
        Err(Error::Done)
    }
fn write_pkt_type ( & self ) -> Result < packet :: Type > { // On error send packet in the latest epoch available, but only send // 1-RTT ones when the handshake is completed. if self . local_error . as_ref ( ) . map_or ( false , | conn_err | ! conn_err . is_app ) { let epoch = match self . handshake . lock ( ) . unwrap ( ) . write_level ( ) { crypto :: Level :: Initial => packet :: EPOCH_INITIAL , crypto :: Level :: ZeroRTT => unreachable ! ( ) , crypto :: Level :: Handshake => packet :: EPOCH_HANDSHAKE , crypto :: Level :: OneRTT => packet :: EPOCH_APPLICATION , } ; if epoch == packet :: EPOCH_APPLICATION && ! self . is_established ( ) { // Downgrade the epoch to handshake as the handshake is not // completed yet. return Ok ( packet :: Type :: Handshake ) ; } return Ok ( packet :: Type :: from_epoch ( epoch ) ) ; } for epoch in packet :: EPOCH_INITIAL .. packet :: EPOCH_COUNT { // Only send packets in a space when we have the send keys for it. if self . pkt_num_spaces [ epoch ] . crypto_seal . is_none ( ) { continue ; } // We are ready to send data for this packet number space. if self . pkt_num_spaces [ epoch ] . ready ( ) { return Ok ( packet :: Type :: from_epoch ( epoch ) ) ; } // There are lost frames in this packet number space. if ! self . recovery . lost [ epoch ] . is_empty ( ) { return Ok ( packet :: Type :: from_epoch ( epoch ) ) ; } // We need to send PTO probe packets. if self . recovery . loss_probes [ epoch ] > 0 { return Ok ( packet :: Type :: from_epoch ( epoch ) ) ; } } // If there are flushable, almost full or blocked streams, use the // Application epoch. if ( self . is_established ( ) || self . is_in_early_data ( ) ) && ( ( self . is_server && ! self . handshake_done_sent ) || self . almost_full || self . blocked_limit . is_some ( ) || self . dgram_send_queue . has_pending ( ) || self . local_error . as_ref ( ) . map_or ( false , | conn_err | conn_err . is_app ) || self . streams . should_update_max_streams_bidi ( ) || self . streams . should_update_max_streams_uni ( ) || self . streams . has_flushable ( ) || self . streams . has_almost_full ( ) || self . streams . has_blocked ( ) || self . streams . has_reset ( ) || self . streams . has_stopped ( ) ) { if self . is_in_early_data ( ) && ! self . is_server { return Ok ( packet :: Type :: ZeroRTT ) ; } return Ok ( packet :: Type :: Short ) ; } Err ( Error :: Done ) }
Selects the packet type for the next outgoing packet.
Selects the packet type for the next outgoing packet .
&self
&self