in quic/s2n-quic-transport/src/connection/connection_impl.rs [1502:1626]
fn handle_short_packet(
&mut self,
datagram: &DatagramInfo,
path_id: path::Id,
packet: ProtectedShort,
random_generator: &mut Config::RandomGenerator,
subscriber: &mut Config::EventSubscriber,
packet_interceptor: &mut Config::PacketInterceptor,
datagram_endpoint: &mut <Self::Config as endpoint::Config>::DatagramEndpoint,
dc_endpoint: &mut Config::DcEndpoint,
limits_endpoint: &mut Config::ConnectionLimits,
) -> Result<(), ProcessingError> {
let mut publisher = self.event_context.publisher(datagram.timestamp, subscriber);
//= https://www.rfc-editor.org/rfc/rfc9001#section-5.7
//# Endpoints in either role MUST NOT decrypt 1-RTT packets from
//# their peer prior to completing the handshake.
//= https://www.rfc-editor.org/rfc/rfc9001#section-5.7
//# A server MUST NOT process
//# incoming 1-RTT protected packets before the TLS handshake is
//# complete.
//= https://www.rfc-editor.org/rfc/rfc9001#section-5.7
//# Even if it has 1-RTT secrets, a client MUST NOT
//# process incoming 1-RTT protected packets before the TLS handshake is
//# complete.
if !self.space_manager.is_handshake_complete() {
let path = &self.path_manager[path_id];
publisher.on_packet_dropped(event::builder::PacketDropped {
reason: event::builder::PacketDropReason::HandshakeNotComplete {
path: path_event!(path, path_id),
},
});
return Ok(());
}
//= https://www.rfc-editor.org/rfc/rfc9000#section-21.2
//# Except for Initial and Stateless Resets, an endpoint only accepts
//# packets that include a Destination Connection ID field that matches
//# a value the endpoint previously chose.
if datagram
.destination_connection_id_classification
.is_initial()
{
let path = &self.path_manager[path_id];
publisher.on_packet_dropped(event::builder::PacketDropped {
reason: event::builder::PacketDropReason::InitialConnectionIdInvalidSpace {
path: path_event!(path, path_id),
packet_type: event::builder::PacketType::OneRtt,
},
});
return Err(ProcessingError::Other);
}
if let Some((space, handshake_status)) = self.space_manager.application_mut() {
let packet = space.validate_and_decrypt_packet(
packet,
datagram,
path_id,
&self.path_manager[path_id],
&mut publisher,
)?;
publisher.on_packet_received(event::builder::PacketReceived {
packet_header: event::builder::PacketHeader::new(
packet.packet_number,
publisher.quic_version(),
),
});
// Connection Ids are issued to the peer after the handshake is
// confirmed and the handshake space is discarded. Therefore only
// short packets need to be processed for local_connection_id changes.
self.path_manager[path_id].on_process_local_connection_id(
path_id,
&packet,
&datagram.destination_connection_id,
&mut publisher,
);
let processed_packet = space.handle_cleartext_payload(
packet.packet_number,
packet.payload,
datagram,
path_id,
&mut self.path_manager,
handshake_status,
&mut self.local_id_registry,
random_generator,
&mut publisher,
packet_interceptor,
)?;
// try to process any post-handshake messages
if Config::ENDPOINT_TYPE.is_client() && processed_packet.contains_crypto {
let space_manager = &mut self.space_manager;
space_manager.post_handshake_crypto(
&mut self.path_manager,
&mut self.local_id_registry,
&mut self.limits,
datagram.timestamp,
&self.waker,
&mut publisher,
datagram_endpoint,
dc_endpoint,
limits_endpoint,
)?;
}
// notify the connection a packet was processed
self.on_processed_packet(&processed_packet, subscriber)?;
} else {
let path = &self.path_manager[path_id];
publisher.on_packet_dropped(event::builder::PacketDropped {
reason: event::builder::PacketDropReason::PacketSpaceDoesNotExist {
path: path_event!(path, path_id),
packet_type: event::builder::PacketType::OneRtt,
},
});
}
Ok(())
}