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(())
}