fn new()

in quic/s2n-quic-transport/src/connection/connection_trait.rs [49:377]


    fn new(parameters: ConnectionParameters<Self::Config>) -> Result<Self, connection::Error>;

    /// Returns the Connections internal ID
    fn internal_connection_id(&self) -> InternalConnectionId;

    /// Returns whether the connection is in the handshake state
    fn is_handshaking(&self) -> bool;

    /// Returns true if the handshake has completed and the connection
    /// has been handed off to the application
    fn is_accepted(&self) -> bool;

    /// Initiates closing the connection as described in
    /// https://www.rfc-editor.org/rfc/rfc9000#section-10
    fn close(
        &mut self,
        error: connection::Error,
        close_formatter: &<Self::Config as endpoint::Config>::ConnectionCloseFormatter,
        packet_buffer: &mut endpoint::PacketBuffer,
        timestamp: Timestamp,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
    );

    /// Marks a connection which advertised itself as having completed the handshake
    /// (via [`ConnectionInterests`]) as accepted. After this call the `accept` interest should
    /// no longer be signalled.
    fn mark_as_accepted(&mut self);

    /// Generates and registers new connection IDs using the given `ConnectionIdFormat` and
    /// `StatelessResetTokenGenerator`
    fn on_new_connection_id(
        &mut self,
        connection_id_format: &mut <Self::Config as endpoint::Config>::ConnectionIdFormat,
        stateless_reset_token_generator: &mut <Self::Config as endpoint::Config>::StatelessResetTokenGenerator,
        timestamp: Timestamp,
    ) -> Result<(), LocalIdRegistrationError>;

    /// Queries the connection for outgoing packets
    fn on_transmit<Tx>(
        &mut self,
        queue: &mut Tx,
        timestamp: Timestamp,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
    ) -> Result<(), ConnectionOnTransmitError>
    where
        Tx: tx::Queue<Handle = <Self::Config as endpoint::Config>::PathHandle>;

    /// Handles all timeouts on the `Connection`.
    ///
    /// `timestamp` passes the current time.
    fn on_timeout(
        &mut self,
        connection_id_mapper: &mut ConnectionIdMapper,
        timestamp: Timestamp,
        supervisor_context: &supervisor::Context,
        random_generator: &mut <Self::Config as endpoint::Config>::RandomGenerator,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
    ) -> Result<(), connection::Error>;

    /// Handles all external wakeups on the [`Connection`].
    fn on_wakeup(
        &mut self,
        timestamp: Timestamp,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        datagram: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut <Self::Config as endpoint::Config>::DcEndpoint,
        conn_limits: &mut <Self::Config as endpoint::Config>::ConnectionLimits,
    ) -> Result<(), connection::Error>;

    // Packet handling

    /// Is called when an initial packet had been received
    fn handle_initial_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedInitial,
        random_generator: &mut <Self::Config as endpoint::Config>::RandomGenerator,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
        datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut <Self::Config as endpoint::Config>::DcEndpoint,
        connection_limits_endpoint: &mut <Self::Config as endpoint::Config>::ConnectionLimits,
    ) -> Result<(), ProcessingError>;

    /// Is called when an unprotected initial packet had been received
    fn handle_cleartext_initial_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: CleartextInitial,
        random_generator: &mut <Self::Config as endpoint::Config>::RandomGenerator,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
        datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut <Self::Config as endpoint::Config>::DcEndpoint,
        connection_limits_endpoint: &mut <Self::Config as endpoint::Config>::ConnectionLimits,
    ) -> Result<(), ProcessingError>;

    /// Is called when a handshake packet had been received
    fn handle_handshake_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedHandshake,
        random_generator: &mut <Self::Config as endpoint::Config>::RandomGenerator,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
        datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut <Self::Config as endpoint::Config>::DcEndpoint,
        connection_limits_endpoint: &mut <Self::Config as endpoint::Config>::ConnectionLimits,
    ) -> Result<(), ProcessingError>;

    /// Is called when a short packet had been received
    fn handle_short_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedShort,
        random_generator: &mut <Self::Config as endpoint::Config>::RandomGenerator,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
        datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut <Self::Config as endpoint::Config>::DcEndpoint,
        limits_endpoint: &mut <Self::Config as endpoint::Config>::ConnectionLimits,
    ) -> Result<(), ProcessingError>;

    /// Is called when a version negotiation packet had been received
    fn handle_version_negotiation_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedVersionNegotiation,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
    ) -> Result<(), ProcessingError>;

    /// Is called when a zero rtt packet had been received
    fn handle_zero_rtt_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedZeroRtt,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
    ) -> Result<(), ProcessingError>;

    /// Is called when a retry packet had been received
    fn handle_retry_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedRetry,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
    ) -> Result<(), ProcessingError>;

    /// Notifies a connection it has received a datagram from a peer
    fn on_datagram_received(
        &mut self,
        path_handle: &<Self::Config as endpoint::Config>::PathHandle,
        datagram: &DatagramInfo,
        congestion_controller_endpoint: &mut <Self::Config as endpoint::Config>::CongestionControllerEndpoint,
        migration_validator: &mut <Self::Config as endpoint::Config>::PathMigrationValidator,
        mtu: &mut mtu::Manager<<Self::Config as endpoint::Config>::Mtu>,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
    ) -> Result<path::Id, DatagramDropReason>;

    /// Returns the Connections interests
    fn interests(&self) -> ConnectionInterests;

    /// Returns the QUIC version selected for the current connection
    fn quic_version(&self) -> u32;

    /// Handles reception of a single QUIC packet
    fn handle_packet(
        &mut self,
        datagram: &DatagramInfo,
        path_id: path::Id,
        packet: ProtectedPacket,
        random_generator: &mut <Self::Config as endpoint::Config>::RandomGenerator,
        subscriber: &mut <Self::Config as endpoint::Config>::EventSubscriber,
        packet_interceptor: &mut <Self::Config as endpoint::Config>::PacketInterceptor,
        datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
        dc_endpoint: &mut <Self::Config as endpoint::Config>::DcEndpoint,
        connection_limits_endpoint: &mut <Self::Config as endpoint::Config>::ConnectionLimits,
        check_for_stateless_reset: &mut bool,
    ) -> Result<(), connection::Error> {
        macro_rules! emit_drop_reason {
            (| $path:ident | $reason:expr) => {
                self.with_event_publisher(
                    datagram.timestamp,
                    Some(path_id),
                    subscriber,
                    |publisher, $path| {
                        publisher
                            .on_packet_dropped(event::builder::PacketDropped { reason: $reason })
                    },
                );
            };
        }

        //= https://www.rfc-editor.org/rfc/rfc9000#section-5.2.1
        //# If a client receives a packet that uses a different version than it
        //# initially selected, it MUST discard that packet.
        if let Some(version) = packet.version() {
            if version != self.quic_version() {
                emit_drop_reason!(|path| event::builder::PacketDropReason::VersionMismatch {
                    version,
                    path: path_event!(path, path_id),
                });
                return Ok(());
            }
        }

        //= https://www.rfc-editor.org/rfc/rfc9000#section-12.2
        //# Senders MUST NOT coalesce QUIC packets
        //# with different connection IDs into a single UDP datagram.  Receivers
        //# SHOULD ignore any subsequent packets with a different Destination
        //# Connection ID than the first packet in the datagram.
        if datagram.destination_connection_id.as_bytes() != packet.destination_connection_id() {
            emit_drop_reason!(
                |path| event::builder::PacketDropReason::ConnectionIdMismatch {
                    packet_cid: packet.destination_connection_id(),
                    path: path_event!(path, path_id),
                }
            );
            return Ok(());
        }

        //= https://www.rfc-editor.org/rfc/rfc9001#section-4.1.4
        //# An endpoint SHOULD continue
        //# to respond to packets that can be processed during this time.
        // We make a best effort to process all of the packet spaces we have available. There isn't
        // any special logic required to meet this requirement as each packet is handled
        // independently.

        let result = match packet {
            ProtectedPacket::Short(packet) => self.handle_short_packet(
                datagram,
                path_id,
                packet,
                random_generator,
                subscriber,
                packet_interceptor,
                datagram_endpoint,
                dc_endpoint,
                connection_limits_endpoint,
            ),
            ProtectedPacket::VersionNegotiation(packet) => self.handle_version_negotiation_packet(
                datagram,
                path_id,
                packet,
                subscriber,
                packet_interceptor,
            ),
            ProtectedPacket::Initial(packet) => self.handle_initial_packet(
                datagram,
                path_id,
                packet,
                random_generator,
                subscriber,
                packet_interceptor,
                datagram_endpoint,
                dc_endpoint,
                connection_limits_endpoint,
            ),
            ProtectedPacket::ZeroRtt(packet) => self.handle_zero_rtt_packet(
                datagram,
                path_id,
                packet,
                subscriber,
                packet_interceptor,
            ),
            ProtectedPacket::Handshake(packet) => self.handle_handshake_packet(
                datagram,
                path_id,
                packet,
                random_generator,
                subscriber,
                packet_interceptor,
                datagram_endpoint,
                dc_endpoint,
                connection_limits_endpoint,
            ),
            ProtectedPacket::Retry(packet) => {
                self.handle_retry_packet(datagram, path_id, packet, subscriber, packet_interceptor)
            }
        };

        match result {
            Ok(()) => {}
            Err(ProcessingError::ConnectionError(error)) => {
                //= https://www.rfc-editor.org/rfc/rfc9000#section-10.2.1
                //# An endpoint
                //# that is closing is not required to process any received frame.
                return Err(error);
            }
            Err(ProcessingError::DecryptError) => {
                // NOTE: this reason is emitted by the connection implementation

                // DecryptErrors returned as a result of a packet failing decryption
                // will be silently discarded, but are a potential indication of a
                // stateless reset from the peer

                //= https://www.rfc-editor.org/rfc/rfc9000#section-5.2.1
                //# Due to packet reordering or loss, a client might receive packets for
                //# a connection that are encrypted with a key it has not yet computed.
                //# The client MAY drop these packets, or it MAY buffer them in
                //# anticipation of later packets that allow it to compute the key.
                //
                // Packets that fail decryption are discarded rather than buffered.

                //= https://www.rfc-editor.org/rfc/rfc9000#section-10.3.1
                //# Endpoints MAY skip this check if any packet from a datagram is
                //# successfully processed.  However, the comparison MUST be performed
                //# when the first packet in an incoming datagram either cannot be
                //# associated with a connection, or cannot be decrypted.
                *check_for_stateless_reset = true;
            }
            Err(ProcessingError::Other) => {
                // All other processing errors are handled by the connection implementation
            }
        };

        Ok(())
    }