fn on_timeout()

in quic/s2n-quic-transport/src/connection/connection_impl.rs [1026:1127]


    fn on_timeout(
        &mut self,
        connection_id_mapper: &mut ConnectionIdMapper,
        timestamp: Timestamp,
        supervisor_context: &supervisor::Context,
        random_generator: &mut Config::RandomGenerator,
        subscriber: &mut Config::EventSubscriber,
    ) -> Result<(), connection::Error> {
        if self.close_sender.on_timeout(timestamp).is_ready() {
            //= https://www.rfc-editor.org/rfc/rfc9000#section-10.2
            //# Once its closing or draining state ends, an endpoint SHOULD discard
            //# all connection state.
            self.state = ConnectionState::Finished;
        }

        // Poll the pacing timer to cancel it if it is ready and unblock transmission interest
        let _ = self.timers.pacing_timer.poll_expiration(timestamp);

        if self
            .timers
            .initial_id_expiration_timer
            .poll_expiration(timestamp)
            .is_ready()
        {
            connection_id_mapper.remove_initial_id(&self.event_context.internal_connection_id);
        }

        let mut publisher = self.event_context.publisher(timestamp, subscriber);

        let amplification_outcome =
            self.path_manager
                .on_timeout(timestamp, random_generator, &mut publisher)?;
        if amplification_outcome.is_active_path_unblocked() {
            self.space_manager
                .on_amplification_unblocked(&self.path_manager, timestamp);
        }
        self.local_id_registry.on_timeout(timestamp);
        self.space_manager.on_timeout(
            &mut self.local_id_registry,
            &mut self.path_manager,
            random_generator,
            timestamp,
            &mut publisher,
        )?;

        if self
            .timers
            .max_handshake_duration_timer
            .poll_expiration(timestamp)
            .is_ready()
        {
            debug_assert_eq!(ConnectionState::Handshaking, self.state);
            return Err(connection::Error::max_handshake_duration_exceeded(
                self.limits.max_handshake_duration(),
            ));
        }

        if self
            .timers
            .peer_idle_timer
            .poll_expiration(timestamp)
            .is_ready()
        {
            return Err(connection::Error::idle_timer_expired());
        }

        if self
            .timers
            .supervisor_timer
            .poll_expiration(timestamp)
            .is_ready()
        {
            self.on_supervisor_timeout(timestamp, subscriber, supervisor_context)?;
        }

        // check to see if we're flushing the connection
        if self.poll_flush().is_ready() {
            return self.error;
        }

        // TODO: enable this check once all of the component timers are fixed
        /*
        if cfg!(debug_assertions) {
            use timer::Provider;

            // make sure that all of the components have been updated and no longer expire
            // with the current timestamp

            (&self, &shared_state).for_each_timer(|timer| {
                assert!(
                    !timer.is_expired(timestamp),
                    "timer has not been reset on timeout; now: {}, timer: {:?}",
                    timestamp,
                    timer,
                );
                Ok(())
            });
        }
        */

        Ok(())
    }