From bcc59076623aeded832bc5503e9501942f3d60cf Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Thu, 30 Apr 2026 11:09:26 +0300 Subject: [PATCH 1/3] fix: Does symbol localization actually help? See slides 80+ of https://raw.githubusercontent.com/yugr/rust-slides/main/EN.pdf --- Cargo.toml | 2 + mtu/src/bsd.rs | 3 +- mtu/src/linux.rs | 1 + mtu/src/routesocket.rs | 6 +- neqo-bin/src/client/http09.rs | 6 +- neqo-bin/src/client/http3.rs | 4 +- neqo-bin/src/send_data.rs | 10 +- neqo-common/src/hrtime.rs | 10 +- neqo-common/src/incrdecoder.rs | 2 +- neqo-http3/src/connection.rs | 56 +++--- neqo-http3/src/connection_client.rs | 24 +-- neqo-http3/src/control_stream_local.rs | 14 +- neqo-http3/src/control_stream_remote.rs | 10 +- .../extended_connect/connect_udp_session.rs | 2 +- .../src/features/extended_connect/mod.rs | 10 +- .../tests/webtransport/mod.rs | 38 +++-- .../extended_connect/webtransport_session.rs | 2 +- .../extended_connect/webtransport_streams.rs | 12 +- neqo-http3/src/frames/capsule.rs | 8 +- neqo-http3/src/frames/hframe.rs | 4 +- neqo-http3/src/frames/mod.rs | 16 +- neqo-http3/src/frames/reader.rs | 22 ++- neqo-http3/src/frames/tests/mod.rs | 6 +- neqo-http3/src/frames/tests/reader.rs | 2 +- neqo-http3/src/frames/wtframe.rs | 6 +- neqo-http3/src/headers_checks.rs | 6 +- neqo-http3/src/lib.rs | 4 +- neqo-http3/src/priority.rs | 10 +- neqo-http3/src/push_controller.rs | 48 +++--- neqo-http3/src/qlog.rs | 9 +- neqo-http3/src/qpack_decoder_receiver.rs | 4 +- neqo-http3/src/qpack_encoder_receiver.rs | 4 +- neqo-http3/src/recv_message.rs | 6 +- neqo-http3/src/send_message.rs | 4 +- neqo-http3/src/server.rs | 6 +- neqo-http3/src/server_connection_events.rs | 16 +- neqo-http3/src/server_events.rs | 8 +- neqo-http3/src/settings.rs | 10 +- neqo-http3/src/stream_type_reader.rs | 14 +- neqo-http3/tests/common/mod.rs | 4 +- neqo-qpack/src/decoder_instructions.rs | 9 +- neqo-qpack/src/encoder.rs | 10 +- neqo-qpack/src/encoder_instructions.rs | 8 +- neqo-qpack/src/fuzz.rs | 4 +- neqo-qpack/src/header_block.rs | 12 +- neqo-qpack/src/huffman.rs | 8 +- neqo-qpack/src/huffman_decode_helper.rs | 4 +- neqo-qpack/src/prefix.rs | 6 +- neqo-qpack/src/qlog.rs | 2 +- neqo-qpack/src/qpack_send_buf.rs | 2 +- neqo-qpack/src/reader.rs | 16 +- neqo-qpack/src/static_table.rs | 10 +- neqo-qpack/src/table.rs | 59 ++++--- neqo-transport/src/addr_valid.rs | 48 +++--- neqo-transport/src/cc/classic_cc.rs | 33 ++-- neqo-transport/src/cc/classic_slow_start.rs | 1 + neqo-transport/src/cc/cubic.rs | 21 +-- neqo-transport/src/cc/hystart.rs | 29 ++-- neqo-transport/src/cc/mod.rs | 7 +- neqo-transport/src/cc/new_reno.rs | 1 + neqo-transport/src/cc/tests/mod.rs | 12 +- neqo-transport/src/cid.rs | 16 +- neqo-transport/src/connection/idle.rs | 22 +-- neqo-transport/src/connection/mod.rs | 15 +- neqo-transport/src/connection/params.rs | 3 +- neqo-transport/src/connection/state.rs | 25 +-- neqo-transport/src/connection/tests/ecn.rs | 2 +- .../src/connection/tests/migration.rs | 2 +- neqo-transport/src/connection/tests/mod.rs | 16 +- neqo-transport/src/connection/tests/vn.rs | 4 +- neqo-transport/src/crypto.rs | 161 ++++++++++-------- neqo-transport/src/fc.rs | 26 +-- neqo-transport/src/frame.rs | 2 +- neqo-transport/src/pace.rs | 12 +- neqo-transport/src/packet/mod.rs | 54 +++--- neqo-transport/src/packet/retry.rs | 4 +- neqo-transport/src/path.rs | 58 ++++--- neqo-transport/src/qlog.rs | 50 +++--- neqo-transport/src/quic_datagrams.rs | 20 +-- neqo-transport/src/recovery/mod.rs | 129 ++++++++------ neqo-transport/src/recovery/sent.rs | 16 +- neqo-transport/src/recovery/token.rs | 4 + neqo-transport/src/rtt.rs | 2 +- neqo-transport/src/saved.rs | 16 +- neqo-transport/src/scone.rs | 10 +- neqo-transport/src/sender.rs | 2 +- neqo-transport/src/server.rs | 2 +- neqo-transport/src/stats.rs | 2 +- neqo-transport/src/tparams.rs | 2 +- neqo-transport/src/tracking.rs | 58 +++---- neqo-transport/tests/common/mod.rs | 14 +- test-fixture/src/sim/delay.rs | 8 +- 92 files changed, 815 insertions(+), 673 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 514ce269f8..6c998adf2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -61,6 +61,7 @@ redundant_imports = "warn" redundant_lifetimes = "warn" trivial_numeric_casts = "warn" unit_bindings = "warn" +unreachable_pub = "warn" unexpected_cfgs = { level = "warn", check-cfg = ['cfg(coverage,coverage_nightly,fuzzing)'] } unused_import_braces = "warn" unused_lifetimes = "warn" @@ -111,6 +112,7 @@ precedence_bits = "warn" pub_without_shorthand = "warn" rc_buffer = "warn" rc_mutex = "warn" +redundant_pub_crate = "allow" # Conflicts with `unreachable_pub` (rust lint), which we prefer. redundant_test_prefix = "warn" redundant_type_annotations = "warn" ref_patterns = "warn" diff --git a/mtu/src/bsd.rs b/mtu/src/bsd.rs index 8c1fb91ee7..de67beaf08 100644 --- a/mtu/src/bsd.rs +++ b/mtu/src/bsd.rs @@ -26,6 +26,7 @@ use static_assertions::{const_assert, const_assert_eq}; )] #[expect( non_camel_case_types, + unreachable_pub, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::struct_field_names, @@ -381,7 +382,7 @@ fn if_index_mtu(remote: IpAddr) -> Result<(u16, Option)> { } } -pub fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { +pub(crate) fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { let (if_index, mtu1) = if_index_mtu(remote)?; let (if_name, mtu2) = if_name_mtu(if_index.into())?; Ok((if_name, mtu1.or(mtu2).ok_or_else(default_err)?)) diff --git a/mtu/src/linux.rs b/mtu/src/linux.rs index d31f48cd3f..78c1167820 100644 --- a/mtu/src/linux.rs +++ b/mtu/src/linux.rs @@ -23,6 +23,7 @@ use crate::{aligned_by, default_err, routesocket::RouteSocket, unlikely_err}; #[expect( non_camel_case_types, + unreachable_pub, clippy::allow_attributes, clippy::allow_attributes_without_reason, clippy::struct_field_names, diff --git a/mtu/src/routesocket.rs b/mtu/src/routesocket.rs index e9bb9b74f9..3969513de2 100644 --- a/mtu/src/routesocket.rs +++ b/mtu/src/routesocket.rs @@ -27,10 +27,10 @@ type RouteSocketSeq = i32; static SEQ: AtomicRouteSocketSeq = AtomicRouteSocketSeq::new(0); -pub struct RouteSocket(OwnedFd); +pub(crate) struct RouteSocket(OwnedFd); impl RouteSocket { - pub fn new(domain: libc::c_int, protocol: libc::c_int) -> Result { + pub(crate) fn new(domain: libc::c_int, protocol: libc::c_int) -> Result { let fd = unsafe { socket(domain, SOCK_RAW, protocol) }; if fd == -1 { return Err(Error::last_os_error()); @@ -38,7 +38,7 @@ impl RouteSocket { Ok(Self(unsafe { OwnedFd::from_raw_fd(fd) })) } - pub fn new_seq() -> RouteSocketSeq { + pub(crate) fn new_seq() -> RouteSocketSeq { SEQ.fetch_add(1, Ordering::Relaxed) } } diff --git a/neqo-bin/src/client/http09.rs b/neqo-bin/src/client/http09.rs index 9c6110ff27..765121fccc 100644 --- a/neqo-bin/src/client/http09.rs +++ b/neqo-bin/src/client/http09.rs @@ -31,7 +31,7 @@ use rustc_hash::FxHashMap as HashMap; use super::{Args, CloseState, Res, get_output_file, qlog_new}; use crate::{STREAM_IO_BUFFER_SIZE, now}; -pub struct Handler<'a> { +pub(super) struct Handler<'a> { streams: HashMap>>, url_queue: VecDeque, handled_urls: Vec, @@ -125,7 +125,7 @@ impl super::Handler for Handler<'_> { } } -pub fn create_client( +pub(super) fn create_client( args: &Args, local_addr: SocketAddr, remote_addr: SocketAddr, @@ -229,7 +229,7 @@ impl super::Client for Connection { } impl<'b> Handler<'b> { - pub fn new(url_queue: VecDeque, args: &'b Args) -> Self { + pub(super) fn new(url_queue: VecDeque, args: &'b Args) -> Self { Self { streams: HashMap::default(), url_queue, diff --git a/neqo-bin/src/client/http3.rs b/neqo-bin/src/client/http3.rs index 47a21a54e4..94b22630a9 100644 --- a/neqo-bin/src/client/http3.rs +++ b/neqo-bin/src/client/http3.rs @@ -35,7 +35,7 @@ use crate::{ send_data::{SendData, SendResult}, }; -pub struct Handler { +pub(super) struct Handler { #[expect(clippy::struct_field_names, reason = "This name is more descriptive.")] url_handler: UrlHandler, token: Option, @@ -63,7 +63,7 @@ impl Handler { } } -pub fn create_client( +pub(super) fn create_client( args: &Args, local_addr: SocketAddr, remote_addr: SocketAddr, diff --git a/neqo-bin/src/send_data.rs b/neqo-bin/src/send_data.rs index f8c383a06f..844126712d 100644 --- a/neqo-bin/src/send_data.rs +++ b/neqo-bin/src/send_data.rs @@ -9,7 +9,7 @@ use std::{borrow::Cow, cmp::min}; use crate::STREAM_IO_BUFFER_SIZE; #[derive(Debug, Default)] -pub struct SendData { +pub(crate) struct SendData { data: Cow<'static, [u8]>, offset: usize, remaining: usize, @@ -41,7 +41,7 @@ impl From<&str> for SendData { } impl SendData { - pub const fn zeroes(total: usize) -> Self { + pub(crate) const fn zeroes(total: usize) -> Self { const MESSAGE: &[u8] = &[0; STREAM_IO_BUFFER_SIZE]; Self { data: Cow::Borrowed(MESSAGE), @@ -60,7 +60,7 @@ impl SendData { /// Returns `SendResult::Done` if all data was sent, `SendResult::MoreData` if /// more data remains, or `SendResult::StreamClosed` if the stream was closed /// (e.g., by `STOP_SENDING`). - pub fn send(&mut self, mut f: F) -> SendResult + pub(crate) fn send(&mut self, mut f: F) -> SendResult where F: FnMut(&[u8]) -> Result, { @@ -77,14 +77,14 @@ impl SendData { SendResult::Done } - pub const fn len(&self) -> usize { + pub(crate) const fn len(&self) -> usize { self.total } } /// Result of a graceful send operation. #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum SendResult { +pub(crate) enum SendResult { /// All data was sent successfully. Done, /// More data remains to be sent (stream buffer full). diff --git a/neqo-common/src/hrtime.rs b/neqo-common/src/hrtime.rs index 74881e5168..82ed79fbff 100644 --- a/neqo-common/src/hrtime.rs +++ b/neqo-common/src/hrtime.rs @@ -116,7 +116,7 @@ mod mac { #[repr(C)] #[derive(Debug, Copy, Clone, Default)] - pub struct thread_time_constraint_policy { + pub(super) struct thread_time_constraint_policy { period: u32, computation: u32, constraint: u32, @@ -157,7 +157,7 @@ mod mac { } /// Set a thread time policy. - pub fn set_thread_policy(mut policy: thread_time_constraint_policy) { + pub(super) fn set_thread_policy(mut policy: thread_time_constraint_policy) { _ = unsafe { thread_policy_set( pthread_mach_thread_np(pthread_self()), @@ -168,7 +168,7 @@ mod mac { }; } - pub fn get_scale() -> f64 { + pub(super) fn get_scale() -> f64 { const NANOS_PER_MSEC: f64 = 1_000_000.0; let mut timebase_info = mach_timebase_info_data_t::default(); unsafe { @@ -178,7 +178,7 @@ mod mac { } /// Create a realtime policy and set it. - pub fn set_realtime(base: f64) { + pub(super) fn set_realtime(base: f64) { #[expect( clippy::cast_possible_truncation, clippy::cast_sign_loss, @@ -194,7 +194,7 @@ mod mac { } /// Get the default policy. - pub fn get_default_policy() -> thread_time_constraint_policy { + pub(super) fn get_default_policy() -> thread_time_constraint_policy { let mut policy = thread_time_constraint_policy::default(); let mut count = THREAD_TIME_CONSTRAINT_POLICY_COUNT; let mut get_default = 0; diff --git a/neqo-common/src/incrdecoder.rs b/neqo-common/src/incrdecoder.rs index 5f80f5e572..ecacd0f086 100644 --- a/neqo-common/src/incrdecoder.rs +++ b/neqo-common/src/incrdecoder.rs @@ -162,7 +162,7 @@ mod tests { } impl UintTestCase { - pub fn run(&self) { + pub(crate) fn run(&self) { eprintln!( "IncrementalDecoderUint decoder with {:?} ; expect {:?}", self.b, self.v diff --git a/neqo-http3/src/connection.rs b/neqo-http3/src/connection.rs index e1e79f2172..715fc1afb8 100644 --- a/neqo-http3/src/connection.rs +++ b/neqo-http3/src/connection.rs @@ -48,7 +48,7 @@ use crate::{ stream_type_reader::NewStreamHeadReader, }; -pub struct RequestDescription<'b, T: RequestTarget> { +pub(crate) struct RequestDescription<'b, T: RequestTarget> { pub method: &'b str, pub connect_type: Option, pub target: T, @@ -284,7 +284,7 @@ impl Http3State { /// [`ConnectionEvent::RecvStreamReadable`]: neqo_transport::ConnectionEvent::RecvStreamReadable /// [`ConnectionEvent::NewStream`]: neqo_transport::ConnectionEvent::NewStream #[derive(Debug)] -pub struct Http3Connection { +pub(crate) struct Http3Connection { role: Role, state: Http3State, local_params: Http3Parameters, @@ -307,7 +307,7 @@ impl Display for Http3Connection { impl Http3Connection { /// Create a new connection. - pub fn new(conn_params: Http3Parameters, role: Role) -> Self { + pub(crate) fn new(conn_params: Http3Parameters, role: Role) -> Self { Self { state: Http3State::Initializing, control_stream_local: ControlStreamLocal::default(), @@ -776,7 +776,7 @@ impl Http3Connection { } /// This is called when an application closes the connection. - pub fn close(&mut self, error: AppError) { + pub(crate) fn close(&mut self, error: AppError) { qdebug!("[{self}] Close connection error {error:?}"); self.state = Http3State::Closing(CloseReason::Application(error)); if (!self.send_streams.is_empty() || !self.recv_streams.is_empty()) && (error == 0) { @@ -884,7 +884,7 @@ impl Http3Connection { Ok(headers) } - pub fn request( + pub(crate) fn request( &mut self, conn: &mut Connection, send_events: Box, @@ -1001,7 +1001,7 @@ impl Http3Connection { /// /// It returns an error if a stream does not exist or an error happens while reading a stream, /// e.g. early close, protocol error, etc. - pub fn read_data( + pub(crate) fn read_data( &mut self, conn: &mut Connection, stream_id: StreamId, @@ -1019,7 +1019,7 @@ impl Http3Connection { /// This is called when an application resets a stream. /// The application reset will close both sides. - pub fn stream_reset_send( + pub(crate) fn stream_reset_send( &mut self, conn: &mut Connection, stream_id: StreamId, @@ -1036,7 +1036,7 @@ impl Http3Connection { Ok(()) } - pub fn stream_stop_sending( + pub(crate) fn stream_stop_sending( &mut self, conn: &mut Connection, stream_id: StreamId, @@ -1059,7 +1059,7 @@ impl Http3Connection { /// # Errors /// /// Returns `InvalidStreamId` if the stream id doesn't exist - pub fn stream_set_sendorder( + pub(crate) fn stream_set_sendorder( conn: &mut Connection, stream_id: StreamId, sendorder: Option, @@ -1075,7 +1075,7 @@ impl Http3Connection { /// # Errors /// /// Returns `InvalidStreamId` if the stream id doesn't exist - pub fn stream_set_fairness( + pub(crate) fn stream_set_fairness( conn: &mut Connection, stream_id: StreamId, fairness: bool, @@ -1084,7 +1084,7 @@ impl Http3Connection { .map_err(|_| Error::InvalidStreamId) } - pub fn cancel_fetch( + pub(crate) fn cancel_fetch( &mut self, stream_id: StreamId, error: AppError, @@ -1136,7 +1136,7 @@ impl Http3Connection { } /// This is called when an application wants to close the sending side of a stream. - pub fn stream_close_send( + pub(crate) fn stream_close_send( &mut self, conn: &mut Connection, stream_id: StreamId, @@ -1159,7 +1159,7 @@ impl Http3Connection { Ok(()) } - pub fn webtransport_create_session( + pub(crate) fn webtransport_create_session( &mut self, conn: &mut Connection, events: Box, @@ -1182,7 +1182,7 @@ impl Http3Connection { ) } - pub fn connect_udp_create_session( + pub(crate) fn connect_udp_create_session( &mut self, conn: &mut Connection, events: Box, @@ -1205,7 +1205,7 @@ impl Http3Connection { ) } - pub fn extended_connect_create_session( + pub(crate) fn extended_connect_create_session( &mut self, conn: &mut Connection, events: Box, @@ -1539,7 +1539,7 @@ impl Http3Connection { Ok(()) } - pub fn webtransport_send_datagram>( + pub(crate) fn webtransport_send_datagram>( &mut self, session_id: StreamId, conn: &mut Connection, @@ -1550,7 +1550,7 @@ impl Http3Connection { self.extended_connect_send_datagram(session_id, conn, buf, id, now) } - pub fn connect_udp_send_datagram>( + pub(crate) fn connect_udp_send_datagram>( &mut self, session_id: StreamId, conn: &mut Connection, @@ -1820,55 +1820,55 @@ impl Http3Connection { stream } - pub const fn webtransport_enabled(&self) -> bool { + pub(crate) const fn webtransport_enabled(&self) -> bool { self.webtransport.enabled() } - pub const fn connect_udp_enabled(&self) -> bool { + pub(crate) const fn connect_udp_enabled(&self) -> bool { self.connect_udp.enabled() } #[must_use] - pub const fn state(&self) -> &Http3State { + pub(crate) const fn state(&self) -> &Http3State { &self.state } - pub fn set_state(&mut self, state: Http3State) { + pub(crate) fn set_state(&mut self, state: Http3State) { self.state = state; } #[must_use] - pub const fn state_mut(&mut self) -> &mut Http3State { + pub(crate) const fn state_mut(&mut self) -> &mut Http3State { &mut self.state } #[must_use] - pub const fn qpack_encoder(&self) -> &Rc> { + pub(crate) const fn qpack_encoder(&self) -> &Rc> { &self.qpack_encoder } #[must_use] - pub const fn qpack_decoder(&self) -> &Rc> { + pub(crate) const fn qpack_decoder(&self) -> &Rc> { &self.qpack_decoder } #[must_use] - pub fn send_streams(&self) -> &HashMap> { + pub(crate) fn send_streams(&self) -> &HashMap> { &self.send_streams } #[must_use] - pub fn send_streams_mut(&mut self) -> &mut HashMap> { + pub(crate) fn send_streams_mut(&mut self) -> &mut HashMap> { &mut self.send_streams } #[must_use] - pub fn recv_streams(&self) -> &HashMap> { + pub(crate) fn recv_streams(&self) -> &HashMap> { &self.recv_streams } #[must_use] - pub fn recv_streams_mut(&mut self) -> &mut HashMap> { + pub(crate) fn recv_streams_mut(&mut self) -> &mut HashMap> { &mut self.recv_streams } } diff --git a/neqo-http3/src/connection_client.rs b/neqo-http3/src/connection_client.rs index e3c380f706..0df8053d4e 100644 --- a/neqo-http3/src/connection_client.rs +++ b/neqo-http3/src/connection_client.rs @@ -1421,11 +1421,11 @@ mod tests { } /// Create a http3 client with default configuration. - pub fn default_http3_client() -> Http3Client { + pub(super) fn default_http3_client() -> Http3Client { default_http3_client_param(100) } - pub fn default_http3_client_param(max_table_size: u64) -> Http3Client { + pub(super) fn default_http3_client_param(max_table_size: u64) -> Http3Client { fixture_init(); Http3Client::new( DEFAULT_SERVER_NAME, @@ -1485,7 +1485,7 @@ mod tests { } impl TestServer { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self::new_with_settings(&[ HSetting::new(HSettingType::MaxTableCapacity, 100), HSetting::new(HSettingType::BlockedStreams, 100), @@ -1493,7 +1493,7 @@ mod tests { ]) } - pub fn new_with_settings(server_settings: &[HSetting]) -> Self { + pub(crate) fn new_with_settings(server_settings: &[HSetting]) -> Self { fixture_init(); let max_table_size = server_settings .iter() @@ -1527,7 +1527,7 @@ mod tests { } } - pub fn new_with_conn(conn: Connection) -> Self { + pub(crate) fn new_with_conn(conn: Connection) -> Self { let qpack = Rc::new(RefCell::new(qpack::Encoder::new( &qpack::Settings { max_table_size_encoder: 128, @@ -1549,7 +1549,7 @@ mod tests { } } - pub fn create_qpack_streams(&mut self) { + pub(crate) fn create_qpack_streams(&mut self) { // Create a QPACK encoder stream self.encoder_stream_id = Some(self.conn.stream_create(StreamType::UniDi).unwrap()); self.encoder @@ -1570,7 +1570,7 @@ mod tests { ); } - pub fn create_control_stream(&mut self) { + pub(crate) fn create_control_stream(&mut self) { // Create control stream let control = self.conn.stream_create(StreamType::UniDi).unwrap(); qtrace!("[TestServer] control stream: {control}"); @@ -1594,7 +1594,7 @@ mod tests { ); } - pub fn check_client_control_qpack_streams_no_resumption(&mut self) { + pub(crate) fn check_client_control_qpack_streams_no_resumption(&mut self) { self.check_client_control_qpack_streams( ENCODER_STREAM_DATA, EXPECTED_REQUEST_HEADER_FRAME, @@ -1603,7 +1603,7 @@ mod tests { ); } - pub fn check_control_qpack_request_streams_resumption( + pub(crate) fn check_control_qpack_request_streams_resumption( &mut self, expect_encoder_stream_data: &[u8], expect_request_header: &[u8], @@ -1618,7 +1618,7 @@ mod tests { } // Check that server has received correct settings and qpack streams. - pub fn check_client_control_qpack_streams( + pub(crate) fn check_client_control_qpack_streams( &mut self, expect_encoder_stream_data: &[u8], expect_request_header: &[u8], @@ -1710,7 +1710,7 @@ mod tests { assert!(!fin); } - pub fn read_and_check_stream_data( + pub(crate) fn read_and_check_stream_data( &mut self, stream_id: StreamId, expected_data: &[u8], @@ -1723,7 +1723,7 @@ mod tests { assert_eq!(&buf[..amount], expected_data); } - pub fn encode_headers( + pub(crate) fn encode_headers( &mut self, stream_id: StreamId, headers: &[Header], diff --git a/neqo-http3/src/control_stream_local.rs b/neqo-http3/src/control_stream_local.rs index eae968af02..a335373411 100644 --- a/neqo-http3/src/control_stream_local.rs +++ b/neqo-http3/src/control_stream_local.rs @@ -16,11 +16,11 @@ use rustc_hash::FxHashMap as HashMap; use crate::{BufferedStream, Error, Http3StreamType, RecvStream, Res, frames::HFrame}; -pub const HTTP3_UNI_STREAM_TYPE_CONTROL: u64 = 0x0; +pub(crate) const HTTP3_UNI_STREAM_TYPE_CONTROL: u64 = 0x0; /// The local control stream, responsible for encoding frames and sending them #[derive(Debug, Default)] -pub struct ControlStreamLocal { +pub(crate) struct ControlStreamLocal { stream: BufferedStream, /// `stream_id`s of outstanding request streams outstanding_priority_update: VecDeque, @@ -34,16 +34,16 @@ impl Display for ControlStreamLocal { impl ControlStreamLocal { /// Add a new frame that needs to be send. - pub fn queue_frame(&mut self, f: &HFrame) { + pub(crate) fn queue_frame(&mut self, f: &HFrame) { self.stream.encode_with(|e| f.encode(e)); } - pub fn queue_update_priority(&mut self, stream_id: StreamId) { + pub(crate) fn queue_update_priority(&mut self, stream_id: StreamId) { self.outstanding_priority_update.push_back(stream_id); } /// Send control data if available. - pub fn send( + pub(crate) fn send( &mut self, conn: &mut Connection, recv_conn: &mut HashMap>, @@ -90,7 +90,7 @@ impl ControlStreamLocal { } /// Create a control stream. - pub fn create(&mut self, conn: &mut Connection) -> Res<()> { + pub(crate) fn create(&mut self, conn: &mut Connection) -> Res<()> { qtrace!("[{self}] Create a control stream"); self.stream.init(conn.stream_create(StreamType::UniDi)?); self.stream @@ -99,7 +99,7 @@ impl ControlStreamLocal { } #[must_use] - pub fn stream_id(&self) -> Option { + pub(crate) fn stream_id(&self) -> Option { (&self.stream).into() } } diff --git a/neqo-http3/src/control_stream_remote.rs b/neqo-http3/src/control_stream_remote.rs index 8c3f3979d4..7abda147ce 100644 --- a/neqo-http3/src/control_stream_remote.rs +++ b/neqo-http3/src/control_stream_remote.rs @@ -20,7 +20,7 @@ use crate::{ /// The remote control stream is responsible only for reading frames. The frames are handled by /// `Http3Connection`. #[derive(Debug)] -pub struct ControlStreamRemote { +pub(crate) struct ControlStreamRemote { stream_id: StreamId, frame_reader: FrameReader, } @@ -32,7 +32,7 @@ impl Display for ControlStreamRemote { } impl ControlStreamRemote { - pub fn new(stream_id: StreamId) -> Self { + pub(crate) fn new(stream_id: StreamId) -> Self { Self { stream_id, frame_reader: FrameReader::new(), @@ -40,7 +40,11 @@ impl ControlStreamRemote { } /// Check if a stream is the control stream and read received data. - pub fn receive_single(&mut self, conn: &mut Connection, now: Instant) -> Res> { + pub(crate) fn receive_single( + &mut self, + conn: &mut Connection, + now: Instant, + ) -> Res> { qdebug!("[{self}] Receiving data"); match self.frame_reader.receive( &mut StreamReaderConnectionWrapper::new(conn, self.stream_id), diff --git a/neqo-http3/src/features/extended_connect/connect_udp_session.rs b/neqo-http3/src/features/extended_connect/connect_udp_session.rs index bbbdb0a326..5edfead77a 100644 --- a/neqo-http3/src/features/extended_connect/connect_udp_session.rs +++ b/neqo-http3/src/features/extended_connect/connect_udp_session.rs @@ -22,7 +22,7 @@ use crate::{ }; #[derive(Debug)] -pub struct Session { +pub(crate) struct Session { frame_reader: FrameReader, session_id: StreamId, } diff --git a/neqo-http3/src/features/extended_connect/mod.rs b/neqo-http3/src/features/extended_connect/mod.rs index 5758daedec..e0a49027df 100644 --- a/neqo-http3/src/features/extended_connect/mod.rs +++ b/neqo-http3/src/features/extended_connect/mod.rs @@ -89,22 +89,22 @@ pub(crate) struct ExtendedConnectFeature { impl ExtendedConnectFeature { #[must_use] - pub fn new(connect_type: ExtendedConnectType, enable: bool) -> Self { + pub(crate) fn new(connect_type: ExtendedConnectType, enable: bool) -> Self { Self { feature_negotiation: NegotiationState::new(enable, HSettingType::from(connect_type)), } } - pub fn set_listener(&mut self, new_listener: Http3ClientEvents) { + pub(crate) fn set_listener(&mut self, new_listener: Http3ClientEvents) { self.feature_negotiation.set_listener(new_listener); } - pub fn handle_settings(&mut self, settings: &HSettings) { + pub(crate) fn handle_settings(&mut self, settings: &HSettings) { self.feature_negotiation.handle_settings(settings); } #[must_use] - pub const fn enabled(&self) -> bool { + pub(crate) const fn enabled(&self) -> bool { self.feature_negotiation.enabled() } } @@ -139,7 +139,7 @@ impl HeaderListener { }); } - pub fn get_headers(&mut self) -> Option { + pub(crate) fn get_headers(&mut self) -> Option { mem::take(&mut self.headers) } } diff --git a/neqo-http3/src/features/extended_connect/tests/webtransport/mod.rs b/neqo-http3/src/features/extended_connect/tests/webtransport/mod.rs index 59153d6d0c..69d9b7cb2e 100644 --- a/neqo-http3/src/features/extended_connect/tests/webtransport/mod.rs +++ b/neqo-http3/src/features/extended_connect/tests/webtransport/mod.rs @@ -27,13 +27,13 @@ use crate::{ // Leave space for large QUIC header. const DATAGRAM_SIZE: u64 = Pmtud::default_plpmtu(DEFAULT_ADDR.ip()) as u64 - 40; -pub fn wt_default_parameters() -> Http3Parameters { +pub(super) fn wt_default_parameters() -> Http3Parameters { Http3Parameters::default() .webtransport(true) .connection_parameters(ConnectionParameters::default().datagram_size(DATAGRAM_SIZE)) } -pub fn default_http3_client(client_params: Http3Parameters) -> Http3Client { +pub(super) fn default_http3_client(client_params: Http3Parameters) -> Http3Client { fixture_init(); Http3Client::new( DEFAULT_SERVER_NAME, @@ -46,7 +46,7 @@ pub fn default_http3_client(client_params: Http3Parameters) -> Http3Client { .expect("create a default client") } -pub fn default_http3_server(server_params: Http3Parameters) -> Http3Server { +pub(super) fn default_http3_server(server_params: Http3Parameters) -> Http3Server { Http3Server::new( now(), DEFAULT_KEYS, @@ -59,7 +59,7 @@ pub fn default_http3_server(server_params: Http3Parameters) -> Http3Server { .expect("create a server") } -pub fn assert_wt(headers: &[Header]) { +pub(super) fn assert_wt(headers: &[Header]) { assert!( headers.contains_header(":method", "CONNECT") && headers.contains_header(":protocol", "webtransport") @@ -127,17 +127,20 @@ struct WtTest { } impl WtTest { - pub fn new() -> Self { + pub(crate) fn new() -> Self { let (client, server) = connect(wt_default_parameters(), wt_default_parameters()); Self { client, server } } - pub fn new_with_params(client_params: Http3Parameters, server_params: Http3Parameters) -> Self { + pub(crate) fn new_with_params( + client_params: Http3Parameters, + server_params: Http3Parameters, + ) -> Self { let (client, server) = connect(client_params, server_params); Self { client, server } } - pub fn new_with(mut client: Http3Client, mut server: Http3Server) -> Self { + pub(crate) fn new_with(mut client: Http3Client, mut server: Http3Server) -> Self { connect_with(&mut client, &mut server); Self { client, server } } @@ -213,7 +216,7 @@ impl WtTest { } } - pub fn cancel_session_client(&mut self, wt_stream_id: StreamId) { + pub(crate) fn cancel_session_client(&mut self, wt_stream_id: StreamId) { self.client .cancel_fetch(wt_stream_id, Error::HttpNone.code()) .unwrap(); @@ -238,7 +241,7 @@ impl WtTest { } } - pub fn check_session_closed_event_client( + pub(crate) fn check_session_closed_event_client( &mut self, wt_session_id: StreamId, expected_reason: &CloseReason, @@ -260,7 +263,7 @@ impl WtTest { assert!(event_found); } - pub fn cancel_session_server(&mut self, wt_session: &WebTransportRequest) { + pub(crate) fn cancel_session_server(&mut self, wt_session: &WebTransportRequest) { wt_session.cancel_fetch(Error::HttpNone.code()).unwrap(); self.exchange_packets(); } @@ -282,7 +285,7 @@ impl WtTest { } } - pub fn check_session_closed_event_server( + pub(crate) fn check_session_closed_event_server( &self, wt_session: &WebTransportRequest, expected_reason: &CloseReason, @@ -585,13 +588,22 @@ impl WtTest { assert_eq!(close_event, expected_session_close.is_some()); } - pub fn session_close_frame_client(&mut self, session_id: StreamId, error: u32, message: &str) { + pub(crate) fn session_close_frame_client( + &mut self, + session_id: StreamId, + error: u32, + message: &str, + ) { self.client .webtransport_close_session(session_id, error, message, now()) .unwrap(); } - pub fn session_close_frame_server(wt_session: &WebTransportRequest, error: u32, message: &str) { + pub(crate) fn session_close_frame_server( + wt_session: &WebTransportRequest, + error: u32, + message: &str, + ) { wt_session.close_session(error, message, now()).unwrap(); } diff --git a/neqo-http3/src/features/extended_connect/webtransport_session.rs b/neqo-http3/src/features/extended_connect/webtransport_session.rs index b41c93d4b6..f0300bd006 100644 --- a/neqo-http3/src/features/extended_connect/webtransport_session.rs +++ b/neqo-http3/src/features/extended_connect/webtransport_session.rs @@ -24,7 +24,7 @@ use crate::{ }; #[derive(Debug)] -pub struct Session { +pub(crate) struct Session { frame_reader: FrameReader, id: StreamId, send_streams: HashSet, diff --git a/neqo-http3/src/features/extended_connect/webtransport_streams.rs b/neqo-http3/src/features/extended_connect/webtransport_streams.rs index 6525bd07fe..3e1b44feab 100644 --- a/neqo-http3/src/features/extended_connect/webtransport_streams.rs +++ b/neqo-http3/src/features/extended_connect/webtransport_streams.rs @@ -15,11 +15,11 @@ use crate::{ SendStream, SendStreamEvents, Stream, }; -pub const WEBTRANSPORT_UNI_STREAM: u64 = 0x54; -pub const WEBTRANSPORT_STREAM: u64 = 0x41; +pub(crate) const WEBTRANSPORT_UNI_STREAM: u64 = 0x54; +pub(crate) const WEBTRANSPORT_STREAM: u64 = 0x41; #[derive(Debug)] -pub struct WebTransportRecvStream { +pub(crate) struct WebTransportRecvStream { stream_id: StreamId, stream_info: Http3StreamInfo, events: Box, @@ -29,7 +29,7 @@ pub struct WebTransportRecvStream { } impl WebTransportRecvStream { - pub fn new( + pub(crate) fn new( stream_id: StreamId, session_id: StreamId, events: Box, @@ -120,7 +120,7 @@ enum WebTransportSenderStreamState { } #[derive(Debug)] -pub struct WebTransportSendStream { +pub(crate) struct WebTransportSendStream { stream_id: StreamId, stream_info: Http3StreamInfo, state: WebTransportSenderStreamState, @@ -130,7 +130,7 @@ pub struct WebTransportSendStream { } impl WebTransportSendStream { - pub fn new( + pub(crate) fn new( stream_id: StreamId, session_id: StreamId, events: Box, diff --git a/neqo-http3/src/frames/capsule.rs b/neqo-http3/src/frames/capsule.rs index 5bb46773d4..80194ba610 100644 --- a/neqo-http3/src/frames/capsule.rs +++ b/neqo-http3/src/frames/capsule.rs @@ -9,21 +9,21 @@ use neqo_common::{Bytes, Encoder, qdebug}; use super::{hframe::HFrameType, reader::FrameDecoder}; use crate::Res; -pub const CAPSULE_TYPE_DATAGRAM: HFrameType = HFrameType(0x00); +pub(crate) const CAPSULE_TYPE_DATAGRAM: HFrameType = HFrameType(0x00); #[derive(PartialEq, Eq, Debug, Clone)] -pub enum Capsule { +pub(crate) enum Capsule { Datagram { payload: Bytes }, } impl Capsule { - pub const fn capsule_type(&self) -> u64 { + pub(crate) const fn capsule_type(&self) -> u64 { match self { Self::Datagram { .. } => CAPSULE_TYPE_DATAGRAM.0, } } - pub fn encode(&self, enc: &mut Encoder) { + pub(crate) fn encode(&self, enc: &mut Encoder) { enc.encode_varint(self.capsule_type()); match self { Self::Datagram { payload } => { diff --git a/neqo-http3/src/frames/hframe.rs b/neqo-http3/src/frames/hframe.rs index 0e9ca0f635..9ca6014621 100644 --- a/neqo-http3/src/frames/hframe.rs +++ b/neqo-http3/src/frames/hframe.rs @@ -38,7 +38,7 @@ impl From for u64 { // data for DATA frame is not read into HFrame::Data. #[derive(PartialEq, Eq, Debug)] -pub enum HFrame { +pub(crate) enum HFrame { Data { len: u64, // length of the data }, @@ -92,7 +92,7 @@ impl HFrame { } } - pub fn encode(&self, enc: &mut Encoder) { + pub(crate) fn encode(&self, enc: &mut Encoder) { enc.encode_varint(self.get_type()); match self { diff --git a/neqo-http3/src/frames/mod.rs b/neqo-http3/src/frames/mod.rs index ab3c52ce67..93044fade7 100644 --- a/neqo-http3/src/frames/mod.rs +++ b/neqo-http3/src/frames/mod.rs @@ -4,19 +4,21 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub mod capsule; -pub mod hframe; -pub mod reader; -pub mod wtframe; +pub(crate) mod capsule; +pub(crate) mod hframe; +pub(crate) mod reader; +pub(crate) mod wtframe; #[allow( clippy::allow_attributes, unused_imports, reason = "These are exported." )] -pub use hframe::{HFrame, HFrameType}; -pub use reader::{FrameReader, StreamReaderConnectionWrapper, StreamReaderRecvStreamWrapper}; -pub use wtframe::WebTransportFrame; +pub(crate) use hframe::{HFrame, HFrameType}; +pub(crate) use reader::{ + FrameReader, StreamReaderConnectionWrapper, StreamReaderRecvStreamWrapper, +}; +pub(crate) use wtframe::WebTransportFrame; #[cfg(test)] #[cfg_attr(coverage_nightly, coverage(off))] diff --git a/neqo-http3/src/frames/reader.rs b/neqo-http3/src/frames/reader.rs index 23110ecf41..53f062b9fc 100644 --- a/neqo-http3/src/frames/reader.rs +++ b/neqo-http3/src/frames/reader.rs @@ -17,7 +17,7 @@ use crate::{Error, RecvStream, Res}; const MAX_READ_SIZE: usize = 2048; // Given a practical MTU of 1500 bytes, this seems reasonable. -pub trait FrameDecoder { +pub(crate) trait FrameDecoder { /// Fuzzing corpus name for this frame type. If `Some`, decoded frames will be /// written to the fuzzing corpus with this name. #[cfg(feature = "build-fuzzing-corpus")] @@ -38,8 +38,7 @@ pub trait FrameDecoder { fn decode(frame_type: HFrameType, frame_len: u64, data: Option<&[u8]>) -> Res>; } -#[expect(clippy::module_name_repetitions, reason = "This is OK.")] -pub trait StreamReader { +pub(crate) trait StreamReader { /// # Errors /// /// An error may happen while reading a stream, e.g. early close, protocol error, etc. @@ -48,13 +47,13 @@ pub trait StreamReader { fn read_data(&mut self, buf: &mut [u8], now: Instant) -> Res<(usize, bool)>; } -pub struct StreamReaderConnectionWrapper<'a> { +pub(crate) struct StreamReaderConnectionWrapper<'a> { conn: &'a mut Connection, stream_id: StreamId, } impl<'a> StreamReaderConnectionWrapper<'a> { - pub const fn new(conn: &'a mut Connection, stream_id: StreamId) -> Self { + pub(crate) const fn new(conn: &'a mut Connection, stream_id: StreamId) -> Self { Self { conn, stream_id } } } @@ -69,14 +68,14 @@ impl StreamReader for StreamReaderConnectionWrapper<'_> { } } -pub struct StreamReaderRecvStreamWrapper<'a> { +pub(crate) struct StreamReaderRecvStreamWrapper<'a> { recv_stream: &'a mut Box, conn: &'a mut Connection, } impl<'a> StreamReaderRecvStreamWrapper<'a> { #[cfg_attr(fuzzing, expect(private_interfaces, reason = "OK for fuzzing."))] - pub fn new(conn: &'a mut Connection, recv_stream: &'a mut Box) -> Self { + pub(crate) fn new(conn: &'a mut Connection, recv_stream: &'a mut Box) -> Self { Self { recv_stream, conn } } } @@ -98,8 +97,7 @@ enum FrameReaderState { UnknownFrameDischargeData { decoder: IncrementalDecoderIgnore }, } -#[expect(clippy::module_name_repetitions, reason = "This is OK.")] -pub struct FrameReader { +pub(crate) struct FrameReader { state: FrameReaderState, frame_type: HFrameType, frame_len: u64, @@ -123,7 +121,7 @@ impl Debug for FrameReader { impl FrameReader { #[must_use] - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { state: FrameReaderState::GetType { decoder: IncrementalDecoderUint::default(), @@ -135,7 +133,7 @@ impl FrameReader { } #[must_use] - pub fn new_with_type(frame_type: HFrameType) -> Self { + pub(crate) fn new_with_type(frame_type: HFrameType) -> Self { Self { state: FrameReaderState::GetLength { decoder: IncrementalDecoderUint::default(), @@ -176,7 +174,7 @@ impl FrameReader { /// /// May return `HttpFrame` if a frame cannot be decoded. /// and `TransportStreamDoesNotExist` if `stream_recv` fails. - pub fn receive>( + pub(crate) fn receive>( &mut self, stream_reader: &mut dyn StreamReader, now: Instant, diff --git a/neqo-http3/src/frames/tests/mod.rs b/neqo-http3/src/frames/tests/mod.rs index ea427edcde..1bc18c729b 100644 --- a/neqo-http3/src/frames/tests/mod.rs +++ b/neqo-http3/src/frames/tests/mod.rs @@ -13,7 +13,7 @@ use crate::frames::{ FrameReader, HFrame, StreamReaderConnectionWrapper, WebTransportFrame, reader::FrameDecoder, }; -pub fn enc_dec>(d: &Encoder, st: &str, remaining: usize) -> T { +pub(super) fn enc_dec>(d: &Encoder, st: &str, remaining: usize) -> T { // For data, headers and push_promise we do not read all bytes from the buffer let d2 = Encoder::from_hex(st); assert_eq!(d.as_ref(), &d2.as_ref()[..d.as_ref().len()]); @@ -60,14 +60,14 @@ pub fn enc_dec>(d: &Encoder, st: &str, remaining: usize) -> T frame.unwrap() } -pub fn enc_dec_hframe(f: &HFrame, st: &str, remaining: usize) { +pub(super) fn enc_dec_hframe(f: &HFrame, st: &str, remaining: usize) { let mut d = Encoder::default(); f.encode(&mut d); let frame = enc_dec::(&d, st, remaining); assert_eq!(*f, frame); } -pub fn enc_dec_wtframe(f: &WebTransportFrame, st: &str, remaining: usize) { +pub(super) fn enc_dec_wtframe(f: &WebTransportFrame, st: &str, remaining: usize) { let mut d = Encoder::default(); f.encode(&mut d); let frame = enc_dec::(&d, st, remaining); diff --git a/neqo-http3/src/frames/tests/reader.rs b/neqo-http3/src/frames/tests/reader.rs index e433e33939..50dc89180f 100644 --- a/neqo-http3/src/frames/tests/reader.rs +++ b/neqo-http3/src/frames/tests/reader.rs @@ -28,7 +28,7 @@ struct FrameReaderTest { } impl FrameReaderTest { - pub fn new() -> Self { + pub(crate) fn new() -> Self { let (conn_c, mut conn_s) = connect(); let stream_id = conn_s.stream_create(StreamType::BiDi).unwrap(); Self { diff --git a/neqo-http3/src/frames/wtframe.rs b/neqo-http3/src/frames/wtframe.rs index bce0249b69..b44694b26a 100644 --- a/neqo-http3/src/frames/wtframe.rs +++ b/neqo-http3/src/frames/wtframe.rs @@ -9,10 +9,10 @@ use neqo_common::{Decoder, Encoder}; use super::hframe::HFrameType; use crate::{Error, Res, frames::reader::FrameDecoder}; -pub type WebTransportFrameType = u64; +pub(crate) type WebTransportFrameType = u64; #[derive(PartialEq, Eq, Debug)] -pub enum WebTransportFrame { +pub(crate) enum WebTransportFrame { CloseSession { error: u32, message: String }, } @@ -27,7 +27,7 @@ impl WebTransportFrame { /// The value 1024 is used to limit the message size for security and interoperability. const CLOSE_MAX_MESSAGE_SIZE: u64 = 1024; - pub fn encode(&self, enc: &mut Encoder) { + pub(crate) fn encode(&self, enc: &mut Encoder) { #[cfg(feature = "build-fuzzing-corpus")] let start = enc.len(); diff --git a/neqo-http3/src/headers_checks.rs b/neqo-http3/src/headers_checks.rs index 0bd9fce1d7..54560fee3c 100644 --- a/neqo-http3/src/headers_checks.rs +++ b/neqo-http3/src/headers_checks.rs @@ -48,7 +48,7 @@ impl TryFrom<(MessageType, &str)> for PseudoHeaderState { /// /// Returns an error if response headers do not contain /// a status header or if the value of the header is 101 or cannot be parsed. -pub fn is_interim(headers: &[Header]) -> Res { +pub(crate) fn is_interim(headers: &[Header]) -> Res { if let Some(h) = headers.iter().take(1).find_header(":status") { let status_code = std::str::from_utf8(h.value()) .map_err(|_| Error::InvalidHeader)? @@ -94,7 +94,7 @@ fn track_pseudo( /// # Errors /// /// Returns an error if headers are not well formed. -pub fn headers_valid(headers: &[Header], message_type: MessageType) -> Res<()> { +pub(crate) fn headers_valid(headers: &[Header], message_type: MessageType) -> Res<()> { let mut method_value: Option<&[u8]> = None; let mut protocol_value: Option<&[u8]> = None; let mut scheme_value: Option<&[u8]> = None; @@ -162,7 +162,7 @@ pub fn headers_valid(headers: &[Header], message_type: MessageType) -> Res<()> { /// # Errors /// /// Returns an error if trailers are not well formed. -pub fn trailers_valid(headers: &[Header]) -> Res<()> { +pub(crate) fn trailers_valid(headers: &[Header]) -> Res<()> { for header in headers { if header.name().starts_with(':') { return Err(Error::InvalidHeader); diff --git a/neqo-http3/src/lib.rs b/neqo-http3/src/lib.rs index 9c9b0f955e..da7b8fc7ec 100644 --- a/neqo-http3/src/lib.rs +++ b/neqo-http3/src/lib.rs @@ -640,7 +640,7 @@ enum CloseType { impl CloseType { #[must_use] - pub const fn error(&self) -> Option { + pub(crate) const fn error(&self) -> Option { match self { Self::ResetApp(error) | Self::ResetRemote(error) | Self::LocalError(error) => { Some(*error) @@ -650,7 +650,7 @@ impl CloseType { } #[must_use] - pub const fn locally_initiated(&self) -> bool { + pub(crate) const fn locally_initiated(&self) -> bool { matches!(self, Self::ResetApp(_)) } } diff --git a/neqo-http3/src/priority.rs b/neqo-http3/src/priority.rs index 5c363b0ab1..214d009b0a 100644 --- a/neqo-http3/src/priority.rs +++ b/neqo-http3/src/priority.rs @@ -99,14 +99,14 @@ impl fmt::Display for Priority { } #[derive(Debug)] -pub struct PriorityHandler { +pub(crate) struct PriorityHandler { push_stream: bool, priority: Priority, last_send_priority: Priority, } impl PriorityHandler { - pub const fn new(push_stream: bool, priority: Priority) -> Self { + pub(crate) const fn new(push_stream: bool, priority: Priority) -> Self { Self { push_stream, priority, @@ -119,7 +119,7 @@ impl PriorityHandler { }*/ /// Returns if an priority update will be issued - pub fn maybe_update_priority(&mut self, priority: Priority) -> bool { + pub(crate) fn maybe_update_priority(&mut self, priority: Priority) -> bool { if priority == self.priority { false } else { @@ -128,12 +128,12 @@ impl PriorityHandler { } } - pub const fn priority_update_sent(&mut self) { + pub(crate) const fn priority_update_sent(&mut self) { self.last_send_priority = self.priority; } /// Returns `HFrame` if an priority update is outstanding - pub fn maybe_encode_frame(&self, stream_id: StreamId) -> Option { + pub(crate) fn maybe_encode_frame(&self, stream_id: StreamId) -> Option { if self.priority == self.last_send_priority { None } else if self.push_stream { diff --git a/neqo-http3/src/push_controller.rs b/neqo-http3/src/push_controller.rs index 10a78ffb8a..968da068d2 100644 --- a/neqo-http3/src/push_controller.rs +++ b/neqo-http3/src/push_controller.rs @@ -63,7 +63,7 @@ struct ActivePushStreams { impl ActivePushStreams { // Const constructor for compile-time initialization in PushController::new(). // Could derive Default if const was not required. - pub const fn new() -> Self { + pub(crate) const fn new() -> Self { Self { push_streams: VecDeque::new(), first_push_id: PushId::new(0), @@ -71,7 +71,7 @@ impl ActivePushStreams { } /// Returns None if a stream has been closed already. - pub fn get_mut( + pub(crate) fn get_mut( &mut self, push_id: PushId, ) -> Option<&mut >::Output> { @@ -90,12 +90,12 @@ impl ActivePushStreams { } /// Returns None if a stream has been closed already. - pub fn get(&mut self, push_id: PushId) -> Option<&mut PushState> { + pub(crate) fn get(&mut self, push_id: PushId) -> Option<&mut PushState> { self.get_mut(push_id) } /// Returns the State of a closed push stream or None for already closed streams. - pub fn close(&mut self, push_id: PushId) -> Option { + pub(crate) fn close(&mut self, push_id: PushId) -> Option { match self.get_mut(push_id) { None | Some(PushState::Closed) => None, Some(s) => { @@ -110,7 +110,7 @@ impl ActivePushStreams { } #[must_use] - pub fn number_done(&self) -> PushId { + pub(crate) fn number_done(&self) -> PushId { self.first_push_id + u64::try_from( self.push_streams @@ -121,7 +121,7 @@ impl ActivePushStreams { .expect("usize fits in u64") } - pub fn clear(&mut self) { + pub(crate) fn clear(&mut self) { self.first_push_id = PushId::new(0); self.push_streams.clear(); } @@ -146,7 +146,7 @@ impl ActivePushStreams { /// `CANCEL_PUSH` frame. The difference is that `PushCanceled` will not /// be posted and a `CANCEL_PUSH` frame may be sent. #[derive(Debug)] -pub struct PushController { +pub(crate) struct PushController { max_concurent_push: u64, current_max_push_id: PushId, // push_streams holds the states of push streams. @@ -165,7 +165,7 @@ impl Display for PushController { } impl PushController { - pub const fn new(max_concurent_push: u64, conn_events: Http3ClientEvents) -> Self { + pub(crate) const fn new(max_concurent_push: u64, conn_events: Http3ClientEvents) -> Self { Self { max_concurent_push, current_max_push_id: PushId::new(0), @@ -179,7 +179,7 @@ impl PushController { /// # Errors /// /// `HttpId` if `push_id` greater than it is allowed has been received. - pub fn new_push_promise( + pub(crate) fn new_push_promise( &mut self, push_id: PushId, ref_stream_id: StreamId, @@ -233,7 +233,11 @@ impl PushController { } } - pub fn add_new_push_stream(&mut self, push_id: PushId, stream_id: StreamId) -> Res { + pub(crate) fn add_new_push_stream( + &mut self, + push_id: PushId, + stream_id: StreamId, + ) -> Res { qtrace!("A new push stream with push_id={push_id} stream_id={stream_id}"); self.check_push_id(push_id)?; @@ -278,7 +282,7 @@ impl PushController { } } - pub fn handle_cancel_push( + pub(crate) fn handle_cancel_push( &mut self, push_id: PushId, conn: &mut Connection, @@ -316,7 +320,7 @@ impl PushController { } } - pub fn close(&mut self, push_id: PushId) { + pub(crate) fn close(&mut self, push_id: PushId) { qtrace!("Push stream has been closed"); if let Some(push_state) = self.push_streams.close(push_id) { debug_assert!(matches!(push_state, PushState::Active { .. })); @@ -325,7 +329,7 @@ impl PushController { } } - pub fn cancel( + pub(crate) fn cancel( &mut self, push_id: PushId, conn: &mut Connection, @@ -369,7 +373,7 @@ impl PushController { } } - pub fn push_stream_reset(&mut self, push_id: PushId, close_type: CloseType) { + pub(crate) fn push_stream_reset(&mut self, push_id: PushId, close_type: CloseType) { qtrace!("Push stream has been reset, push_id={push_id}"); if let Some(push_state) = self.push_streams.get(push_id) { match push_state { @@ -395,14 +399,14 @@ impl PushController { } } - pub fn get_active_stream_id(&mut self, push_id: PushId) -> Option { + pub(crate) fn get_active_stream_id(&mut self, push_id: PushId) -> Option { match self.push_streams.get(push_id) { Some(PushState::Active { stream_id, .. }) => Some(*stream_id), _ => None, } } - pub fn maybe_send_max_push_id_frame(&mut self, base_handler: &mut Http3Connection) { + pub(crate) fn maybe_send_max_push_id_frame(&mut self, base_handler: &mut Http3Connection) { let push_done = self.push_streams.number_done(); if self.max_concurent_push > 0 && (self.current_max_push_id - push_done) <= (self.max_concurent_push / 2).into() @@ -414,19 +418,19 @@ impl PushController { } } - pub const fn handle_zero_rtt_rejected(&mut self) { + pub(crate) const fn handle_zero_rtt_rejected(&mut self) { self.current_max_push_id = PushId::new(0); } - pub fn clear(&mut self) { + pub(crate) fn clear(&mut self) { self.push_streams.clear(); } - pub const fn can_receive_push(&self) -> bool { + pub(crate) const fn can_receive_push(&self) -> bool { self.max_concurent_push > 0 } - pub fn new_stream_event(&mut self, push_id: PushId, event: Http3ClientEvent) { + pub(crate) fn new_stream_event(&mut self, push_id: PushId, event: Http3ClientEvent) { match self.push_streams.get_mut(push_id) { None => { debug_assert!(false, "Push has been closed already"); @@ -450,13 +454,13 @@ impl PushController { /// `PushHeaderReady` and `PushDataReadable` events or to postpone them if /// a `push_promise` has not been yet received for the stream. #[derive(Debug)] -pub struct RecvPushEvents { +pub(crate) struct RecvPushEvents { push_id: PushId, push_handler: Rc>, } impl RecvPushEvents { - pub const fn new(push_id: PushId, push_handler: Rc>) -> Self { + pub(crate) const fn new(push_id: PushId, push_handler: Rc>) -> Self { Self { push_id, push_handler, diff --git a/neqo-http3/src/qlog.rs b/neqo-http3/src/qlog.rs index c8862f9354..635f9858ed 100644 --- a/neqo-http3/src/qlog.rs +++ b/neqo-http3/src/qlog.rs @@ -12,7 +12,7 @@ use neqo_common::qlog::Qlog; use neqo_transport::StreamId; use qlog::events::{DataRecipient, EventData}; -pub fn h3_data_moved_up(qlog: &mut Qlog, stream_id: StreamId, amount: usize, now: Instant) { +pub(crate) fn h3_data_moved_up(qlog: &mut Qlog, stream_id: StreamId, amount: usize, now: Instant) { qlog.add_event_at( || { let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved { @@ -30,7 +30,12 @@ pub fn h3_data_moved_up(qlog: &mut Qlog, stream_id: StreamId, amount: usize, now ); } -pub fn h3_data_moved_down(qlog: &mut Qlog, stream_id: StreamId, amount: usize, now: Instant) { +pub(crate) fn h3_data_moved_down( + qlog: &mut Qlog, + stream_id: StreamId, + amount: usize, + now: Instant, +) { qlog.add_event_at( || { let ev_data = EventData::DataMoved(qlog::events::quic::DataMoved { diff --git a/neqo-http3/src/qpack_decoder_receiver.rs b/neqo-http3/src/qpack_decoder_receiver.rs index 4e72ff0ec7..4197bd6363 100644 --- a/neqo-http3/src/qpack_decoder_receiver.rs +++ b/neqo-http3/src/qpack_decoder_receiver.rs @@ -12,13 +12,13 @@ use neqo_transport::{Connection, StreamId}; use crate::{CloseType, Error, Http3StreamType, ReceiveOutput, RecvStream, Res, Stream}; #[derive(Debug)] -pub struct DecoderRecvStream { +pub(crate) struct DecoderRecvStream { stream_id: StreamId, decoder: Rc>, } impl DecoderRecvStream { - pub const fn new(stream_id: StreamId, decoder: Rc>) -> Self { + pub(crate) const fn new(stream_id: StreamId, decoder: Rc>) -> Self { Self { stream_id, decoder } } } diff --git a/neqo-http3/src/qpack_encoder_receiver.rs b/neqo-http3/src/qpack_encoder_receiver.rs index 1ba3d113e0..358f6d4a5f 100644 --- a/neqo-http3/src/qpack_encoder_receiver.rs +++ b/neqo-http3/src/qpack_encoder_receiver.rs @@ -12,13 +12,13 @@ use neqo_transport::{Connection, StreamId}; use crate::{CloseType, Error, Http3StreamType, ReceiveOutput, RecvStream, Res, Stream}; #[derive(Debug)] -pub struct EncoderRecvStream { +pub(crate) struct EncoderRecvStream { stream_id: StreamId, encoder: Rc>, } impl EncoderRecvStream { - pub const fn new(stream_id: StreamId, encoder: Rc>) -> Self { + pub(crate) const fn new(stream_id: StreamId, encoder: Rc>) -> Self { Self { stream_id, encoder } } } diff --git a/neqo-http3/src/recv_message.rs b/neqo-http3/src/recv_message.rs index 6b0dad9169..bc6efbe531 100644 --- a/neqo-http3/src/recv_message.rs +++ b/neqo-http3/src/recv_message.rs @@ -27,7 +27,7 @@ use crate::{ qlog, }; -pub struct RecvMessageInfo { +pub(crate) struct RecvMessageInfo { pub message_type: MessageType, pub stream_type: Http3StreamType, pub stream_id: StreamId, @@ -73,7 +73,7 @@ struct PushInfo { } #[derive(Debug)] -pub struct RecvMessage { +pub(crate) struct RecvMessage { state: RecvMessageState, stream_info: Http3StreamInfo, message_type: MessageType, @@ -93,7 +93,7 @@ impl Display for RecvMessage { } impl RecvMessage { - pub fn new( + pub(crate) fn new( message_info: &RecvMessageInfo, qpack_decoder: Rc>, conn_events: Box, diff --git a/neqo-http3/src/send_message.rs b/neqo-http3/src/send_message.rs index 6b5245bd96..343561073b 100644 --- a/neqo-http3/src/send_message.rs +++ b/neqo-http3/src/send_message.rs @@ -109,7 +109,7 @@ impl MessageState { } #[derive(Debug)] -pub struct SendMessage { +pub(crate) struct SendMessage { state: MessageState, stream_info: Http3StreamInfo, message_type: MessageType, @@ -120,7 +120,7 @@ pub struct SendMessage { } impl SendMessage { - pub fn new( + pub(crate) fn new( message_type: MessageType, stream_type: Http3StreamType, stream_id: StreamId, diff --git a/neqo-http3/src/server.rs b/neqo-http3/src/server.rs index 0005ccf143..6a1fe31468 100644 --- a/neqo-http3/src/server.rs +++ b/neqo-http3/src/server.rs @@ -415,7 +415,7 @@ mod tests { .max_blocked_streams(qpack_settings.max_blocked_streams) } - pub fn create_server(conn_params: Http3Parameters) -> Http3Server { + pub(super) fn create_server(conn_params: Http3Parameters) -> Http3Server { fixture_init(); Http3Server::new( now(), @@ -430,7 +430,7 @@ mod tests { } /// Create a http3 server with default configuration. - pub fn default_server() -> Http3Server { + pub(super) fn default_server() -> Http3Server { create_server(http3params(DEFAULT_SETTINGS)) } @@ -1365,7 +1365,7 @@ mod tests { } #[derive(Debug, Default)] - pub struct RejectZeroRtt {} + pub(super) struct RejectZeroRtt {} impl ZeroRttChecker for RejectZeroRtt { fn check(&self, _token: &[u8]) -> ZeroRttCheckResult { ZeroRttCheckResult::Reject diff --git a/neqo-http3/src/server_connection_events.rs b/neqo-http3/src/server_connection_events.rs index 6fa3642bf0..4ee2a6c8c1 100644 --- a/neqo-http3/src/server_connection_events.rs +++ b/neqo-http3/src/server_connection_events.rs @@ -18,7 +18,7 @@ use crate::{ /// Server events for a single connection. #[derive(Debug, PartialEq, Eq, Clone)] -pub enum Http3ServerConnEvent { +pub(crate) enum Http3ServerConnEvent { /// Headers are ready. Headers { stream_info: Http3StreamInfo, @@ -51,7 +51,7 @@ pub enum Http3ServerConnEvent { } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum WebTransportEvent { +pub(crate) enum WebTransportEvent { Session { stream_id: StreamId, headers: Vec
, @@ -69,7 +69,7 @@ pub enum WebTransportEvent { } #[derive(Debug, PartialEq, Eq, Clone)] -pub enum ConnectUdpEvent { +pub(crate) enum ConnectUdpEvent { Session { stream_id: StreamId, headers: Vec
, @@ -86,7 +86,7 @@ pub enum ConnectUdpEvent { } #[derive(Debug, Default, Clone)] -pub struct Http3ServerConnEvents { +pub(crate) struct Http3ServerConnEvents { events: Rc>>, } @@ -253,19 +253,19 @@ impl Http3ServerConnEvents { self.events.borrow_mut().retain(|evt| !f(evt)); } - pub fn has_events(&self) -> bool { + pub(crate) fn has_events(&self) -> bool { !self.events.borrow().is_empty() } - pub fn next_event(&self) -> Option { + pub(crate) fn next_event(&self) -> Option { self.events.borrow_mut().pop_front() } - pub fn connection_state_change(&self, state: Http3State) { + pub(crate) fn connection_state_change(&self, state: Http3State) { self.insert(Http3ServerConnEvent::StateChange(state)); } - pub fn priority_update(&self, stream_id: StreamId, priority: Priority) { + pub(crate) fn priority_update(&self, stream_id: StreamId, priority: Priority) { self.insert(Http3ServerConnEvent::PriorityUpdate { stream_id, priority, diff --git a/neqo-http3/src/server_events.rs b/neqo-http3/src/server_events.rs index 15e86837c9..0238d5a4c2 100644 --- a/neqo-http3/src/server_events.rs +++ b/neqo-http3/src/server_events.rs @@ -581,7 +581,7 @@ pub enum Http3ServerEvent { } #[derive(Debug, Default, Clone)] -pub struct Http3ServerEvents { +pub(crate) struct Http3ServerEvents { events: Rc>>, } @@ -591,17 +591,17 @@ impl Http3ServerEvents { } /// Take all events - pub fn events(&self) -> impl Iterator + use<> { + pub(crate) fn events(&self) -> impl Iterator + use<> { self.events.replace(VecDeque::new()).into_iter() } /// Whether there is request pending. - pub fn has_events(&self) -> bool { + pub(crate) fn has_events(&self) -> bool { !self.events.borrow().is_empty() } /// Take the next event if present. - pub fn next_event(&self) -> Option { + pub(crate) fn next_event(&self) -> Option { self.events.borrow_mut().pop_front() } diff --git a/neqo-http3/src/settings.rs b/neqo-http3/src/settings.rs index 22f6e31893..c02f043345 100644 --- a/neqo-http3/src/settings.rs +++ b/neqo-http3/src/settings.rs @@ -31,9 +31,9 @@ const SETTINGS_H3_DATAGRAM: SettingsType = 0x33; /// Advertises support for HTTP Extended CONNECT. /// /// See -pub const SETTINGS_ENABLE_CONNECT_PROTOCOL: SettingsType = 0x08; +pub(crate) const SETTINGS_ENABLE_CONNECT_PROTOCOL: SettingsType = 0x08; -pub const H3_RESERVED_SETTINGS: &[SettingsType] = &[0x2, 0x3, 0x4, 0x5]; +pub(crate) const H3_RESERVED_SETTINGS: &[SettingsType] = &[0x2, 0x3, 0x4, 0x5]; #[derive(Clone, PartialEq, Eq, Debug, Copy)] pub enum HSettingType { @@ -251,20 +251,20 @@ impl From<&Http3Parameters> for HSettings { } #[derive(Debug)] -pub struct HttpZeroRttChecker { +pub(crate) struct HttpZeroRttChecker { settings: Http3Parameters, } impl HttpZeroRttChecker { /// Right now we only have QPACK settings, so that is all this takes. #[must_use] - pub const fn new(settings: Http3Parameters) -> Self { + pub(crate) const fn new(settings: Http3Parameters) -> Self { Self { settings } } /// Save the settings that matter for 0-RTT. #[must_use] - pub fn save(settings: &Http3Parameters) -> Vec { + pub(crate) fn save(settings: &Http3Parameters) -> Vec { let mut enc = Encoder::default(); enc.encode_varint(SETTINGS_ZERO_RTT_VERSION) .encode_varint(SETTINGS_QPACK_MAX_TABLE_CAPACITY) diff --git a/neqo-http3/src/stream_type_reader.rs b/neqo-http3/src/stream_type_reader.rs index 6cf058f569..23455e76ce 100644 --- a/neqo-http3/src/stream_type_reader.rs +++ b/neqo-http3/src/stream_type_reader.rs @@ -16,12 +16,12 @@ use crate::{ frames::{HFrame, hframe::HFrameType, reader::FrameDecoder}, }; -pub const HTTP3_UNI_STREAM_TYPE_PUSH: u64 = 0x1; -pub const WEBTRANSPORT_UNI_STREAM: u64 = 0x54; -pub const WEBTRANSPORT_STREAM: u64 = 0x41; +pub(crate) const HTTP3_UNI_STREAM_TYPE_PUSH: u64 = 0x1; +pub(crate) const WEBTRANSPORT_UNI_STREAM: u64 = 0x54; +pub(crate) const WEBTRANSPORT_STREAM: u64 = 0x41; #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum NewStreamType { +pub(crate) enum NewStreamType { Control, Decoder, Encoder, @@ -79,7 +79,7 @@ impl NewStreamType { /// is identified by the type and `PushId`. After reading the type in the `ReadType` state, /// `NewStreamHeadReader` changes to `ReadId` state and from there to `Done` state #[derive(Debug)] -pub enum NewStreamHeadReader { +pub(crate) enum NewStreamHeadReader { ReadType { role: Role, reader: IncrementalDecoderUint, @@ -94,7 +94,7 @@ pub enum NewStreamHeadReader { } impl NewStreamHeadReader { - pub fn new(stream_id: StreamId, role: Role) -> Self { + pub(crate) fn new(stream_id: StreamId, role: Role) -> Self { Self::ReadType { role, reader: IncrementalDecoderUint::default(), @@ -130,7 +130,7 @@ impl NewStreamHeadReader { } } - pub fn get_type(&mut self, conn: &mut Connection) -> Res> { + pub(crate) fn get_type(&mut self, conn: &mut Connection) -> Res> { loop { let (output, fin) = self.read(conn)?; let Some(output) = output else { diff --git a/neqo-http3/tests/common/mod.rs b/neqo-http3/tests/common/mod.rs index 4adfae8659..4d0a175491 100644 --- a/neqo-http3/tests/common/mod.rs +++ b/neqo-http3/tests/common/mod.rs @@ -9,7 +9,9 @@ use test_fixture::*; /// Connect a client and server, send a GET request from the client, /// and exchange packets so the server receives it. -pub fn connect_and_send_request(close_sending_side: bool) -> (Http3Client, Http3Server, StreamId) { +pub(crate) fn connect_and_send_request( + close_sending_side: bool, +) -> (Http3Client, Http3Server, StreamId) { let mut client = default_http3_client(); let mut server = default_http3_server(); let dgram = connect_peers(&mut client, &mut server); diff --git a/neqo-qpack/src/decoder_instructions.rs b/neqo-qpack/src/decoder_instructions.rs index 5a2a0094d8..cc9007f4a8 100644 --- a/neqo-qpack/src/decoder_instructions.rs +++ b/neqo-qpack/src/decoder_instructions.rs @@ -20,7 +20,7 @@ use crate::{ }; #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)] -pub enum DecoderInstruction { +pub(crate) enum DecoderInstruction { InsertCountIncrement { increment: u64, }, @@ -77,7 +77,7 @@ enum DecoderInstructionReaderState { } #[derive(Debug, Default)] -pub struct DecoderInstructionReader { +pub(crate) struct DecoderInstructionReader { state: DecoderInstructionReaderState, instruction: DecoderInstruction, } @@ -94,7 +94,10 @@ impl DecoderInstructionReader { /// 1) `NeedMoreData` if the reader needs more data /// 2) `ClosedCriticalStream` /// 3) other errors will be translated to `DecoderStream` by the caller of this function. - pub fn read_instructions(&mut self, recv: &mut R) -> Res { + pub(crate) fn read_instructions( + &mut self, + recv: &mut R, + ) -> Res { qdebug!("[{self}] read a new instruction"); loop { match &mut self.state { diff --git a/neqo-qpack/src/encoder.rs b/neqo-qpack/src/encoder.rs index 4a6684f06d..ed0ec76faa 100644 --- a/neqo-qpack/src/encoder.rs +++ b/neqo-qpack/src/encoder.rs @@ -36,7 +36,7 @@ enum LocalStreamState { } impl LocalStreamState { - pub const fn stream_id(&self) -> Option { + pub(crate) const fn stream_id(&self) -> Option { match self { Self::NoStream => None, Self::Uninitialized(stream_id) | Self::Initialized(stream_id) => Some(*stream_id), @@ -572,20 +572,20 @@ mod tests { } impl TestEncoder { - pub fn change_capacity(&mut self, capacity: u64) -> Res<()> { + pub(crate) fn change_capacity(&mut self, capacity: u64) -> Res<()> { self.encoder.set_max_capacity(capacity)?; // We will try to really change the table only when we send the change capacity // instruction. self.encoder.send_encoder_updates(&mut self.conn) } - pub fn insert(&mut self, header: &[u8], value: &[u8], inst: &[u8]) { + pub(crate) fn insert(&mut self, header: &[u8], value: &[u8], inst: &[u8]) { let res = self.encoder.send_and_insert(&mut self.conn, header, value); assert!(res.is_ok()); self.send_instructions(inst); } - pub fn encode_header_block( + pub(crate) fn encode_header_block( &mut self, stream_id: StreamId, headers: &[Header], @@ -599,7 +599,7 @@ mod tests { self.send_instructions(inst); } - pub fn send_instructions(&mut self, encoder_instruction: &[u8]) { + pub(crate) fn send_instructions(&mut self, encoder_instruction: &[u8]) { self.encoder.send_encoder_updates(&mut self.conn).unwrap(); let out = self.conn.process_output(now()); let out2 = self.peer_conn.process(out.dgram(), now()); diff --git a/neqo-qpack/src/encoder_instructions.rs b/neqo-qpack/src/encoder_instructions.rs index aeeaba04d6..ec7801e3ff 100644 --- a/neqo-qpack/src/encoder_instructions.rs +++ b/neqo-qpack/src/encoder_instructions.rs @@ -24,7 +24,7 @@ use crate::{ // The encoder only uses InsertWithNameLiteral. // All instructions are used for testing, therefore they are guarded with `#[cfg(test)]`. #[derive(Debug, PartialEq, Eq)] -pub enum EncoderInstruction<'a> { +pub(crate) enum EncoderInstruction<'a> { Capacity { value: u64, }, @@ -98,7 +98,7 @@ enum EncoderInstructionReaderState { } #[derive(Debug, PartialEq, Eq, Default)] -pub enum DecodedEncoderInstruction { +pub(crate) enum DecodedEncoderInstruction { Capacity { value: u64, }, @@ -154,7 +154,7 @@ impl<'a> From<&'a EncoderInstruction<'a>> for DecodedEncoderInstruction { } #[derive(Debug, Default)] -pub struct EncoderInstructionReader { +pub(crate) struct EncoderInstructionReader { state: EncoderInstructionReaderState, instruction: DecodedEncoderInstruction, } @@ -233,7 +233,7 @@ impl EncoderInstructionReader { /// 1) `NeedMoreData` if the reader needs more data /// 2) `ClosedCriticalStream` /// 3) other errors will be translated to `EncoderStream` by the caller of this function. - pub fn read_instructions( + pub(crate) fn read_instructions( &mut self, recv: &mut T, ) -> Res { diff --git a/neqo-qpack/src/fuzz.rs b/neqo-qpack/src/fuzz.rs index 3a0122c3bb..4646e40898 100644 --- a/neqo-qpack/src/fuzz.rs +++ b/neqo-qpack/src/fuzz.rs @@ -7,7 +7,7 @@ //! Fuzzing support for QPACK. #[cfg(feature = "build-fuzzing-corpus")] -pub use write_corpus::write_item_to_fuzzing_corpus; +pub(crate) use write_corpus::write_item_to_fuzzing_corpus; #[cfg(feature = "build-fuzzing-corpus")] /// Helpers to write data to the fuzzing corpus. @@ -15,7 +15,7 @@ mod write_corpus { use neqo_transport::StreamId; /// Write QPACK data to the fuzzing corpus. - pub fn write_item_to_fuzzing_corpus(stream_id: StreamId, buf: &[u8]) { + pub(crate) fn write_item_to_fuzzing_corpus(stream_id: StreamId, buf: &[u8]) { let mut data = Vec::with_capacity(size_of::() + buf.len()); data.extend_from_slice(&stream_id.as_u64().to_le_bytes()); data.extend_from_slice(buf); diff --git a/neqo-qpack/src/header_block.rs b/neqo-qpack/src/header_block.rs index 3cef23bc21..1d6c9b4494 100644 --- a/neqo-qpack/src/header_block.rs +++ b/neqo-qpack/src/header_block.rs @@ -152,7 +152,7 @@ impl Deref for HeaderEncoder { } } -pub struct HeaderDecoder<'a> { +pub(crate) struct HeaderDecoder<'a> { buf: ReceiverBufferWrapper<'a>, base: u64, req_insert_cnt: u64, @@ -165,13 +165,13 @@ impl Display for HeaderDecoder<'_> { } #[derive(Debug, PartialEq, Eq)] -pub enum HeaderDecoderResult { +pub(crate) enum HeaderDecoderResult { Blocked(u64), Headers(Vec
), } impl<'a> HeaderDecoder<'a> { - pub const fn new(buf: &'a [u8]) -> Self { + pub(crate) const fn new(buf: &'a [u8]) -> Self { Self { buf: ReceiverBufferWrapper::new(buf), base: 0, @@ -179,7 +179,7 @@ impl<'a> HeaderDecoder<'a> { } } - pub fn refers_dynamic_table( + pub(crate) fn refers_dynamic_table( &mut self, max_entries: u64, total_num_of_inserts: u64, @@ -191,7 +191,7 @@ impl<'a> HeaderDecoder<'a> { Ok(self.req_insert_cnt != 0) } - pub fn decode_header_block( + pub(crate) fn decode_header_block( &mut self, table: &HeaderTable, max_entries: u64, @@ -257,7 +257,7 @@ impl<'a> HeaderDecoder<'a> { Ok(HeaderDecoderResult::Headers(h)) } - pub const fn get_req_insert_cnt(&self) -> u64 { + pub(crate) const fn get_req_insert_cnt(&self) -> u64 { self.req_insert_cnt } diff --git a/neqo-qpack/src/huffman.rs b/neqo-qpack/src/huffman.rs index 543826d1d5..3fda3504ef 100644 --- a/neqo-qpack/src/huffman.rs +++ b/neqo-qpack/src/huffman.rs @@ -17,7 +17,7 @@ struct BitReader<'a> { } impl<'a> BitReader<'a> { - pub const fn new(input: &'a [u8]) -> Self { + pub(crate) const fn new(input: &'a [u8]) -> Self { BitReader { input, offset: 0, @@ -25,7 +25,7 @@ impl<'a> BitReader<'a> { } } - pub fn read_bit(&mut self) -> Res { + pub(crate) fn read_bit(&mut self) -> Res { if self.input.len() == self.offset { return Err(Error::NeedMoreData); } @@ -41,7 +41,7 @@ impl<'a> BitReader<'a> { Ok((self.input[self.offset] >> self.current_bit) & 0x01) } - pub fn verify_ending(&mut self, i: u8) -> Res<()> { + pub(crate) fn verify_ending(&mut self, i: u8) -> Res<()> { if (i + self.current_bit) > 7 { return Err(Error::HuffmanDecompression); } @@ -60,7 +60,7 @@ impl<'a> BitReader<'a> { } } - pub const fn has_more_data(&self) -> bool { + pub(crate) const fn has_more_data(&self) -> bool { !self.input.is_empty() && (self.offset != self.input.len() || (self.current_bit != 0)) } } diff --git a/neqo-qpack/src/huffman_decode_helper.rs b/neqo-qpack/src/huffman_decode_helper.rs index b8ab4e8cdd..7371c91c0c 100644 --- a/neqo-qpack/src/huffman_decode_helper.rs +++ b/neqo-qpack/src/huffman_decode_helper.rs @@ -11,12 +11,12 @@ use crate::huffman_table::HUFFMAN_TABLE; // Since we're encoding the table length as a u16, we need to ensure that it fits. static_assertions::const_assert!(HUFFMAN_TABLE.len() <= u16::MAX as usize); -pub struct HuffmanDecoderNode { +pub(crate) struct HuffmanDecoderNode { pub next: [Option>; 2], pub value: Option, } -pub fn huffman_decoder_root() -> &'static HuffmanDecoderNode { +pub(crate) fn huffman_decoder_root() -> &'static HuffmanDecoderNode { static ROOT: OnceLock = OnceLock::new(); ROOT.get_or_init(|| make_huffman_tree(0, 0)) } diff --git a/neqo-qpack/src/prefix.rs b/neqo-qpack/src/prefix.rs index e5bf9e36e9..01d6b7046f 100644 --- a/neqo-qpack/src/prefix.rs +++ b/neqo-qpack/src/prefix.rs @@ -48,7 +48,7 @@ impl Prefix { #[macro_export] macro_rules! create_prefix { ($n:ident) => { - pub const $n: Prefix = Prefix { + pub(crate) const $n: Prefix = Prefix { prefix: 0x0, len: 0, mask: 0xFF, @@ -57,7 +57,7 @@ macro_rules! create_prefix { ($n:ident, $v:expr, $l:expr) => { static_assertions::const_assert!($l < 7); static_assertions::const_assert!($v & ((1 << (8 - $l)) - 1) == 0); - pub const $n: Prefix = Prefix { + pub(crate) const $n: Prefix = Prefix { prefix: $v, len: $l, mask: ((1 << $l) - 1) << (8 - $l), @@ -67,7 +67,7 @@ macro_rules! create_prefix { static_assertions::const_assert!($l < 7); static_assertions::const_assert!($v & ((1 << (8 - $l)) - 1) == 0); static_assertions::const_assert!((((1 << $l) - 1) << (8 - $l)) >= $m); - pub const $n: Prefix = Prefix { + pub(crate) const $n: Prefix = Prefix { prefix: $v, len: $l, mask: $m, diff --git a/neqo-qpack/src/qlog.rs b/neqo-qpack/src/qlog.rs index d1a8f5ba46..57599bba29 100644 --- a/neqo-qpack/src/qlog.rs +++ b/neqo-qpack/src/qlog.rs @@ -14,7 +14,7 @@ use qlog::events::{ qpack::{QPackInstruction, QpackInstructionParsed, QpackInstructionTypeName}, }; -pub fn qpack_read_insert_count_increment_instruction( +pub(crate) fn qpack_read_insert_count_increment_instruction( qlog: &mut Qlog, increment: u64, data: &[u8], diff --git a/neqo-qpack/src/qpack_send_buf.rs b/neqo-qpack/src/qpack_send_buf.rs index 8b7c3e513d..eeb17aac78 100644 --- a/neqo-qpack/src/qpack_send_buf.rs +++ b/neqo-qpack/src/qpack_send_buf.rs @@ -11,7 +11,7 @@ use crate::{huffman, prefix::Prefix}; /// This trait extends the standard [`neqo_common::Encoder`] with QPACK-specific /// methods for encoding integers with prefixes and literal strings with /// optional Huffman encoding. -pub trait Encoder { +pub(crate) trait Encoder { /// Encode an integer with a QPACK prefix according to RFC 7541 Section 5.1. fn encode_prefixed_encoded_int(&mut self, prefix: Prefix, val: u64) -> usize; diff --git a/neqo-qpack/src/reader.rs b/neqo-qpack/src/reader.rs index 9897f7fc11..328575013c 100644 --- a/neqo-qpack/src/reader.rs +++ b/neqo-qpack/src/reader.rs @@ -53,7 +53,7 @@ impl Reader for ReceiverConnWrapper<'_> { } impl<'a> ReceiverConnWrapper<'a> { - pub const fn new(conn: &'a mut Connection, stream_id: StreamId) -> Self { + pub(crate) const fn new(conn: &'a mut Connection, stream_id: StreamId) -> Self { Self { conn, stream_id } } } @@ -79,11 +79,11 @@ impl ReadByte for ReceiverBufferWrapper<'_> { } impl<'a> ReceiverBufferWrapper<'a> { - pub const fn new(buf: &'a [u8]) -> Self { + pub(crate) const fn new(buf: &'a [u8]) -> Self { Self { buf, offset: 0 } } - pub const fn peek(&self) -> Res { + pub(crate) const fn peek(&self) -> Res { if self.offset == self.buf.len() { Err(Error::Decompression) } else { @@ -91,7 +91,7 @@ impl<'a> ReceiverBufferWrapper<'a> { } } - pub const fn done(&self) -> bool { + pub(crate) const fn done(&self) -> bool { self.offset == self.buf.len() } @@ -100,7 +100,7 @@ impl<'a> ReceiverBufferWrapper<'a> { /// `ReceiverBufferWrapper` is only used for decoding header blocks. The header blocks are read /// entirely before a decoding starts, therefore any incomplete varint because of reaching the /// end of a buffer will be treated as the `Error::Decompression` error. - pub fn read_prefixed_int(&mut self, prefix_len: u8) -> Res { + pub(crate) fn read_prefixed_int(&mut self, prefix_len: u8) -> Res { debug_assert!(prefix_len < 8); let first_byte = self.read_byte()?; @@ -119,7 +119,7 @@ impl<'a> ReceiverBufferWrapper<'a> { /// `ReceiverBufferWrapper` is only used for decoding header blocks. The header blocks are read /// entirely before a decoding starts, therefore any incomplete varint or literal because of /// reaching the end of a buffer will be treated as the `Error::Decompression` error. - pub fn read_literal_from_buffer(&mut self, prefix_len: u8) -> Res> { + pub(crate) fn read_literal_from_buffer(&mut self, prefix_len: u8) -> Res> { debug_assert!(prefix_len < 7); let first_byte = self.read_byte()?; @@ -361,7 +361,7 @@ pub(crate) mod test_receiver { use super::{Error, ReadByte, Reader, Res}; #[derive(Default)] - pub struct TestReceiver { + pub(crate) struct TestReceiver { buf: VecDeque, } @@ -386,7 +386,7 @@ pub(crate) mod test_receiver { } impl TestReceiver { - pub fn write(&mut self, buf: &[u8]) { + pub(crate) fn write(&mut self, buf: &[u8]) { for b in buf { self.buf.push_front(*b); } diff --git a/neqo-qpack/src/static_table.rs b/neqo-qpack/src/static_table.rs index 79af223f57..29d502c3f6 100644 --- a/neqo-qpack/src/static_table.rs +++ b/neqo-qpack/src/static_table.rs @@ -5,22 +5,22 @@ // except according to those terms. #[derive(Debug)] -pub struct StaticTableEntry { +pub(crate) struct StaticTableEntry { index: u64, name: &'static [u8], value: &'static [u8], } impl StaticTableEntry { - pub const fn name(&self) -> &[u8] { + pub(crate) const fn name(&self) -> &[u8] { self.name } - pub const fn value(&self) -> &[u8] { + pub(crate) const fn value(&self) -> &[u8] { self.value } - pub const fn index(&self) -> u64 { + pub(crate) const fn index(&self) -> u64 { self.index } } @@ -31,7 +31,7 @@ macro_rules! static_table_entries { }; } -pub const HEADER_STATIC_TABLE: &[StaticTableEntry] = static_table_entries![ +pub(crate) const HEADER_STATIC_TABLE: &[StaticTableEntry] = static_table_entries![ 0, b":authority", b""; 1, b":path", b"/"; 2, b"age", b"0"; diff --git a/neqo-qpack/src/table.rs b/neqo-qpack/src/table.rs index 767d3a9bd2..6f484366d0 100644 --- a/neqo-qpack/src/table.rs +++ b/neqo-qpack/src/table.rs @@ -16,16 +16,16 @@ use crate::{ static_table::{HEADER_STATIC_TABLE, StaticTableEntry}, }; -pub const ADDITIONAL_TABLE_ENTRY_SIZE: usize = 32; +pub(crate) const ADDITIONAL_TABLE_ENTRY_SIZE: usize = 32; -pub struct LookupResult { +pub(crate) struct LookupResult { pub index: u64, pub static_table: bool, pub value_matches: bool, } #[derive(Debug)] -pub struct DynamicTableEntry { +pub(crate) struct DynamicTableEntry { base: u64, name: Vec, value: Vec, @@ -35,38 +35,38 @@ pub struct DynamicTableEntry { } impl DynamicTableEntry { - pub const fn can_reduce(&self, first_not_acked: u64) -> bool { + pub(crate) const fn can_reduce(&self, first_not_acked: u64) -> bool { self.refs == 0 && self.base < first_not_acked } - pub const fn size(&self) -> usize { + pub(crate) const fn size(&self) -> usize { self.name.len() + self.value.len() + ADDITIONAL_TABLE_ENTRY_SIZE } - pub const fn add_ref(&mut self) { + pub(crate) const fn add_ref(&mut self) { self.refs += 1; } - pub fn remove_ref(&mut self) { + pub(crate) fn remove_ref(&mut self) { assert!(self.refs > 0); self.refs -= 1; } - pub fn name(&self) -> &[u8] { + pub(crate) fn name(&self) -> &[u8] { &self.name } - pub fn value(&self) -> &[u8] { + pub(crate) fn value(&self) -> &[u8] { &self.value } - pub const fn index(&self) -> u64 { + pub(crate) const fn index(&self) -> u64 { self.base } } #[derive(Debug)] -pub struct HeaderTable { +pub(crate) struct HeaderTable { dynamic: VecDeque, /// The total capacity (in QPACK bytes) of the table. This is set by /// configuration. @@ -91,7 +91,7 @@ impl Display for HeaderTable { } impl HeaderTable { - pub const fn new(encoder: bool) -> Self { + pub(crate) const fn new(encoder: bool) -> Self { Self { dynamic: VecDeque::new(), capacity: 0, @@ -102,12 +102,12 @@ impl HeaderTable { } /// Returns number of inserts. - pub const fn base(&self) -> u64 { + pub(crate) const fn base(&self) -> u64 { self.base } /// Returns capacity of the dynamic table - pub const fn capacity(&self) -> u64 { + pub(crate) const fn capacity(&self) -> u64 { self.capacity } @@ -118,7 +118,7 @@ impl HeaderTable { /// [`Error::ChangeCapacity`] if table capacity cannot be reduced. /// The table cannot be reduced if there are entries that are referred to at /// the moment, or whose inserts are unacked. - pub fn set_capacity(&mut self, cap: u64) -> Res<()> { + pub(crate) fn set_capacity(&mut self, cap: u64) -> Res<()> { qtrace!("[{self}] set capacity to {cap}"); if !self.evict_to(cap) { return Err(Error::ChangeCapacity); @@ -132,7 +132,7 @@ impl HeaderTable { /// # Errors /// /// `HeaderLookup` if the index does not exist in the static table. - pub fn get_static(index: u64) -> Res<&'static StaticTableEntry> { + pub(crate) fn get_static(index: u64) -> Res<&'static StaticTableEntry> { let inx = usize::try_from(index).or(Err(Error::HeaderLookup))?; HEADER_STATIC_TABLE.get(inx).ok_or(Error::HeaderLookup) } @@ -157,7 +157,7 @@ impl HeaderTable { /// # Errors /// /// `HeaderLookup` if entry does not exist. - pub fn get_dynamic(&self, index: u64, base: u64, post: bool) -> Res<&DynamicTableEntry> { + pub(crate) fn get_dynamic(&self, index: u64, base: u64, post: bool) -> Res<&DynamicTableEntry> { let inx = if post { if self.base < base @@ -179,7 +179,7 @@ impl HeaderTable { } /// Remove a reference to a dynamic table entry. - pub fn remove_ref(&mut self, index: u64) { + pub(crate) fn remove_ref(&mut self, index: u64) { qtrace!("[{self}] remove reference to entry {index}"); self.get_dynamic_with_abs_index(index) .expect("we should have the entry") @@ -187,7 +187,7 @@ impl HeaderTable { } /// Add a reference to a dynamic table entry. - pub fn add_ref(&mut self, index: u64) { + pub(crate) fn add_ref(&mut self, index: u64) { qtrace!("[{self}] add reference to entry {index}"); self.get_dynamic_with_abs_index(index) .expect("we should have the entry") @@ -197,7 +197,12 @@ impl HeaderTable { /// Look for a header pair. /// The function returns `LookupResult`: `index`, `static_table` (if it is a static table entry) /// and `value_matches` (if the header value matches as well not only header name) - pub fn lookup(&mut self, name: &[u8], value: &[u8], can_block: bool) -> Option { + pub(crate) fn lookup( + &mut self, + name: &[u8], + value: &[u8], + can_block: bool, + ) -> Option { qtrace!("[{self}] lookup name:{name:?} value {value:?} can_block={can_block}"); let mut name_match = None; for iter in HEADER_STATIC_TABLE { @@ -259,7 +264,7 @@ impl HeaderTable { true } - pub fn can_evict_to(&self, reduce: u64) -> bool { + pub(crate) fn can_evict_to(&self, reduce: u64) -> bool { let evictable_size: usize = self .dynamic .iter() @@ -271,7 +276,7 @@ impl HeaderTable { self.used - u64::try_from(evictable_size).expect("usize fits in u64") <= reduce } - pub fn insert_possible(&self, size: usize) -> bool { + pub(crate) fn insert_possible(&self, size: usize) -> bool { let size = u64::try_from(size).expect("usize fits in u64"); size <= self.capacity && self.can_evict_to(self.capacity - size) } @@ -282,7 +287,7 @@ impl HeaderTable { /// /// `DynamicTableFull` if an entry cannot be added to the table because there is not enough /// space and/or other entry cannot be evicted. - pub fn insert(&mut self, name: &[u8], value: &[u8]) -> Res { + pub(crate) fn insert(&mut self, name: &[u8], value: &[u8]) -> Res { qtrace!("[{self}] insert name={name:?} value={value:?}"); let entry = DynamicTableEntry { name: name.to_vec(), @@ -310,7 +315,7 @@ impl HeaderTable { /// `DynamicTableFull` if an entry cannot be added to the table because there is not enough /// space and/or other entry cannot be evicted. /// `HeaderLookup` if the index dos not exits in the static/dynamic table. - pub fn insert_with_name_ref( + pub(crate) fn insert_with_name_ref( &mut self, name_static_table: bool, name_index: u64, @@ -341,7 +346,7 @@ impl HeaderTable { /// `DynamicTableFull` if an entry cannot be added to the table because there is not enough /// space and/or other entry cannot be evicted. /// `HeaderLookup` if the index dos not exits in the static/dynamic table. - pub fn duplicate(&mut self, index: u64) -> Res { + pub(crate) fn duplicate(&mut self, index: u64) -> Res { qtrace!("[{self}] duplicate entry={index}"); // need to remember name and value because insert may delete the entry. let name: Vec; @@ -360,7 +365,7 @@ impl HeaderTable { /// # Errors /// /// `IncrementAck` if ack is greater than actual number of inserts. - pub fn increment_acked(&mut self, increment: u64) -> Res<()> { + pub(crate) fn increment_acked(&mut self, increment: u64) -> Res<()> { qtrace!("[{self}] increment acked by {increment}"); self.acked_inserts_cnt += increment; if self.base < self.acked_inserts_cnt { @@ -370,7 +375,7 @@ impl HeaderTable { } /// Return number of acknowledge inserts. - pub const fn get_acked_inserts_cnt(&self) -> u64 { + pub(crate) const fn get_acked_inserts_cnt(&self) -> u64 { self.acked_inserts_cnt } } diff --git a/neqo-transport/src/addr_valid.rs b/neqo-transport/src/addr_valid.rs index 34d6f53e93..8cec579195 100644 --- a/neqo-transport/src/addr_valid.rs +++ b/neqo-transport/src/addr_valid.rs @@ -56,14 +56,14 @@ pub enum ValidateAddress { Always, } -pub enum AddressValidationResult { +pub(crate) enum AddressValidationResult { Pass, ValidRetry(ConnectionId), Validate, Invalid, } -pub struct AddressValidation { +pub(crate) struct AddressValidation { /// What sort of validation is performed. validation: ValidateAddress, /// A self-encryption object used for protecting Retry tokens. @@ -73,7 +73,7 @@ pub struct AddressValidation { } impl AddressValidation { - pub fn new(now: Instant, validation: ValidateAddress) -> Res { + pub(crate) fn new(now: Instant, validation: ValidateAddress) -> Res { Ok(Self { validation, self_encrypt: SelfEncrypt::new(TLS_VERSION_1_3, TLS_AES_128_GCM_SHA256)?, @@ -107,7 +107,7 @@ impl AddressValidation { aad } - pub fn generate_token( + pub(crate) fn generate_token( &self, dcid: Option<&ConnectionId>, peer_address: SocketAddr, @@ -152,7 +152,7 @@ impl AddressValidation { } /// This generates a token for use with Retry. - pub fn generate_retry_token( + pub(crate) fn generate_retry_token( &self, dcid: &ConnectionId, peer_address: SocketAddr, @@ -162,11 +162,15 @@ impl AddressValidation { } /// This generates a token for use with `NEW_TOKEN`. - pub fn generate_new_token(&self, peer_address: SocketAddr, now: Instant) -> Res> { + pub(crate) fn generate_new_token( + &self, + peer_address: SocketAddr, + now: Instant, + ) -> Res> { self.generate_token(None, peer_address, now) } - pub fn set_validation(&mut self, validation: ValidateAddress) { + pub(crate) fn set_validation(&mut self, validation: ValidateAddress) { qtrace!("AddressValidation {self:p}: set to {validation:?}"); self.validation = validation; } @@ -211,7 +215,7 @@ impl AddressValidation { usize::try_from(difference).expect("u32 fits in usize") < TOKEN_IDENTIFIER_RETRY.len() } - pub fn validate( + pub(crate) fn validate( &self, token: &[u8], peer_address: SocketAddr, @@ -283,7 +287,7 @@ impl AddressValidation { } #[expect(clippy::large_enum_variant, reason = "No way around it.")] -pub enum NewTokenState { +pub(crate) enum NewTokenState { Client { /// Tokens that haven't been taken yet. pending: SmallVec<[Vec; MAX_NEW_TOKEN]>, @@ -294,7 +298,7 @@ pub enum NewTokenState { } impl NewTokenState { - pub fn new(role: Role) -> Self { + pub(crate) fn new(role: Role) -> Self { match role { Role::Client => Self::Client { pending: SmallVec::<[_; MAX_NEW_TOKEN]>::new(), @@ -305,7 +309,7 @@ impl NewTokenState { } /// Is there a token available? - pub fn has_token(&self) -> bool { + pub(crate) fn has_token(&self) -> bool { match self { Self::Client { pending, .. } => !pending.is_empty(), Self::Server(..) => false, @@ -314,7 +318,7 @@ impl NewTokenState { /// If this is a client, take a token if there is one. /// If this is a server, panic. - pub fn take_token(&mut self) -> Option<&[u8]> { + pub(crate) fn take_token(&mut self) -> Option<&[u8]> { if let Self::Client { pending, old } = self { pending.pop().map(|t| { if old.len() >= MAX_SAVED_TOKENS { @@ -330,7 +334,7 @@ impl NewTokenState { /// If this is a client, save a token. /// If this is a server, panic. - pub fn save_token(&mut self, token: Vec) { + pub(crate) fn save_token(&mut self, token: Vec) { if let Self::Client { pending, old } = self { for t in old.iter().rev().chain(pending.iter().rev()) { if t == &token { @@ -350,7 +354,7 @@ impl NewTokenState { /// If this is a server, maybe send a frame. /// If this is a client, do nothing. - pub fn write_frames( + pub(crate) fn write_frames( &mut self, builder: &mut packet::Builder, tokens: &mut recovery::Tokens, @@ -363,7 +367,7 @@ impl NewTokenState { /// If this a server, buffer a `NEW_TOKEN` for sending. /// If this is a client, panic. - pub fn send_new_token(&mut self, token: Vec) { + pub(crate) fn send_new_token(&mut self, token: Vec) { if let Self::Server(sender) = self { sender.send_new_token(token); } else { @@ -373,7 +377,7 @@ impl NewTokenState { /// If this a server, process a lost signal for a `NEW_TOKEN` frame. /// If this is a client, panic. - pub fn lost(&mut self, seqno: usize) { + pub(crate) fn lost(&mut self, seqno: usize) { if let Self::Server(sender) = self { sender.lost(seqno); } else { @@ -383,7 +387,7 @@ impl NewTokenState { /// If this a server, process remove the acknowledged `NEW_TOKEN` frame. /// If this is a client, panic. - pub fn acked(&mut self, seqno: usize) { + pub(crate) fn acked(&mut self, seqno: usize) { if let Self::Server(sender) = self { sender.acked(seqno); } else { @@ -405,7 +409,7 @@ impl NewTokenFrameStatus { } #[derive(Default)] -pub struct NewTokenSender { +pub(crate) struct NewTokenSender { /// The unacknowledged `NEW_TOKEN` frames we are yet to send. tokens: Vec, /// A sequence number that is used to track individual tokens @@ -415,7 +419,7 @@ pub struct NewTokenSender { impl NewTokenSender { /// Add a token to be sent. - pub fn send_new_token(&mut self, token: Vec) { + pub(crate) fn send_new_token(&mut self, token: Vec) { self.tokens.push(NewTokenFrameStatus { seqno: self.next_seqno, token, @@ -424,7 +428,7 @@ impl NewTokenSender { self.next_seqno += 1; } - pub fn write_frames( + pub(crate) fn write_frames( &mut self, builder: &mut packet::Builder, tokens: &mut recovery::Tokens, @@ -444,7 +448,7 @@ impl NewTokenSender { } } - pub fn lost(&mut self, seqno: usize) { + pub(crate) fn lost(&mut self, seqno: usize) { for t in &mut self.tokens { if t.seqno == seqno { t.needs_sending = true; @@ -453,7 +457,7 @@ impl NewTokenSender { } } - pub fn acked(&mut self, seqno: usize) { + pub(crate) fn acked(&mut self, seqno: usize) { self.tokens.retain(|i| i.seqno != seqno); } } diff --git a/neqo-transport/src/cc/classic_cc.rs b/neqo-transport/src/cc/classic_cc.rs index f47e05fdb2..100a68d2fa 100644 --- a/neqo-transport/src/cc/classic_cc.rs +++ b/neqo-transport/src/cc/classic_cc.rs @@ -26,7 +26,9 @@ use crate::{ stats::{CongestionControlStats, SlowStartExitReason}, }; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub const CWND_INITIAL_PKTS: usize = 10; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub const PERSISTENT_CONG_THRESH: u32 = 3; #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -46,21 +48,21 @@ enum Phase { } impl Phase { - pub const fn in_recovery(self) -> bool { + pub(crate) const fn in_recovery(self) -> bool { matches!(self, Self::RecoveryStart | Self::Recovery) } - pub fn in_slow_start(self) -> bool { + pub(crate) fn in_slow_start(self) -> bool { self == Self::SlowStart } /// These states are transient, we tell qlog on entry, but not on exit. - pub const fn transient(self) -> bool { + pub(crate) const fn transient(self) -> bool { matches!(self, Self::RecoveryStart | Self::PersistentCongestion) } /// Update a transient phase to the actual phase. - pub fn update(&mut self) { + pub(crate) fn update(&mut self) { *self = match self { Self::PersistentCongestion => Self::SlowStart, Self::RecoveryStart => Self::Recovery, @@ -68,7 +70,7 @@ impl Phase { }; } - pub const fn to_qlog(self) -> &'static str { + pub(crate) const fn to_qlog(self) -> &'static str { match self { Self::SlowStart | Self::PersistentCongestion => "slow_start", Self::CongestionAvoidance => "congestion_avoidance", @@ -77,7 +79,7 @@ impl Phase { } } -pub trait WindowAdjustment: Display + Debug { +pub(crate) trait WindowAdjustment: Display + Debug { /// This is called when an ack is received. /// The function calculates the amount of acked bytes congestion controller needs /// to collect before increasing its cwnd by `MAX_DATAGRAM_SIZE`. @@ -117,7 +119,7 @@ pub trait WindowAdjustment: Display + Debug { /// Implementations define when and if to exit from slow start, how the slow start threshold /// (`ssthresh`) is set on exit and they can influence how fast the exponential congestion window /// growth rate during slow start is. -pub trait SlowStart: Display + Debug { +pub(crate) trait SlowStart: Display + Debug { /// Enables a trait implementor to track RTT rounds via the next packet numer that is to be sent /// out. fn on_packet_sent(&mut self, sent_pn: packet::Number); @@ -169,7 +171,7 @@ impl Display for State { } impl State { - pub const fn new(mtu: usize) -> Self { + pub(crate) const fn new(mtu: usize) -> Self { Self { phase: Phase::SlowStart, congestion_window: cwnd_initial(mtu), @@ -181,6 +183,7 @@ impl State { } #[derive(Debug)] +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub struct ClassicCongestionController { slow_start: S, congestion_control: T, @@ -226,7 +229,7 @@ impl Display for ClassicCongestionController { } impl ClassicCongestionController { - pub const fn max_datagram_size(&self) -> usize { + pub(crate) const fn max_datagram_size(&self) -> usize { self.pmtud.plpmtu() } } @@ -595,7 +598,7 @@ where S: SlowStart, T: WindowAdjustment, { - pub fn new( + pub(crate) fn new( slow_start: S, congestion_control: T, pmtud: Pmtud, @@ -618,31 +621,31 @@ where #[cfg(test)] #[must_use] - pub const fn ssthresh(&self) -> usize { + pub(crate) const fn ssthresh(&self) -> usize { self.current.ssthresh } #[cfg(test)] - pub const fn set_ssthresh(&mut self, v: usize) { + pub(crate) const fn set_ssthresh(&mut self, v: usize) { self.current.ssthresh = v; } /// Accessor for [`ClassicCongestionController::congestion_control`]. Is used to call Cubic /// getters in tests. #[cfg(test)] - pub const fn congestion_control(&self) -> &T { + pub(crate) const fn congestion_control(&self) -> &T { &self.congestion_control } /// Mutable accessor for [`ClassicCongestionController::congestion_control`]. Is used to call /// Cubic setters in tests. #[cfg(test)] - pub const fn congestion_control_mut(&mut self) -> &mut T { + pub(crate) const fn congestion_control_mut(&mut self) -> &mut T { &mut self.congestion_control } #[cfg(test)] - pub const fn acked_bytes(&self) -> usize { + pub(crate) const fn acked_bytes(&self) -> usize { self.current.acked_bytes } diff --git a/neqo-transport/src/cc/classic_slow_start.rs b/neqo-transport/src/cc/classic_slow_start.rs index 4bc242c6bc..6f80c01634 100644 --- a/neqo-transport/src/cc/classic_slow_start.rs +++ b/neqo-transport/src/cc/classic_slow_start.rs @@ -16,6 +16,7 @@ use crate::{cc::classic_cc::SlowStart, packet, rtt::RttEstimate, stats::Congesti /// /// #[derive(Debug, Default)] +#[expect(unreachable_pub, reason = "re-exported via cc::ClassicSlowStart")] pub struct ClassicSlowStart {} impl Display for ClassicSlowStart { diff --git a/neqo-transport/src/cc/cubic.rs b/neqo-transport/src/cc/cubic.rs index ba43f3a594..eee9eecf40 100644 --- a/neqo-transport/src/cc/cubic.rs +++ b/neqo-transport/src/cc/cubic.rs @@ -24,7 +24,7 @@ use crate::{ /// Convert an integer congestion window value into a floating point value. /// This has the effect of reducing larger values to `1<<53`. /// If you have a congestion window that large, something is probably wrong. -pub fn convert_to_f64(v: usize) -> f64 { +pub(super) fn convert_to_f64(v: usize) -> f64 { let mut f_64 = f64::from(u32::try_from(v >> 21).unwrap_or(u32::MAX)); f_64 *= 2_097_152.0; // f_64 <<= 21 #[expect(clippy::cast_possible_truncation, reason = "The mask makes this safe.")] @@ -34,7 +34,7 @@ pub fn convert_to_f64(v: usize) -> f64 { } #[derive(Debug, Default, Clone)] -pub struct State { +pub(super) struct State { /// > An estimate for the congestion window \[...\] in the Reno-friendly region -- that /// > is, an estimate for the congestion window of Reno. /// @@ -100,6 +100,7 @@ impl Display for State { } #[derive(Debug, Default)] +#[expect(unreachable_pub, reason = "re-exported via cc::Cubic")] pub struct Cubic { /// Current CUBIC parameters. current: State, @@ -123,7 +124,7 @@ impl Cubic { /// See section 5.1 of RFC9438 for discussion on how to set the concrete value: /// /// - pub const C: f64 = 0.4; + pub(crate) const C: f64 = 0.4; /// > CUBIC additive increase factor used in the Reno-friendly region \[to achieve approximately /// > the same average congestion window size as Reno\]. @@ -140,7 +141,7 @@ impl Cubic { /// `ALPHA = 3.0 * (1.0 - CUBIC_BETA) / (1.0 + CUBIC_BETA)` /// /// - pub const ALPHA: f64 = 3.0 * (1.0 - 0.7) / (1.0 + 0.7); // with CUBIC_BETA = 0.7 + pub(crate) const ALPHA: f64 = 3.0 * (1.0 - 0.7) / (1.0 + 0.7); // with CUBIC_BETA = 0.7 /// > CUBIC multiplicative decrease factor /// @@ -157,7 +158,7 @@ impl Cubic { /// For implementation reasons neqo uses a dividend and divisor approach with `usize` typing. /// The divisor is set to `100` to also accommodate the `0.85` beta value for ECN induced /// congestion events. - pub const BETA_USIZE_DIVISOR: usize = 100; + pub(crate) const BETA_USIZE_DIVISOR: usize = 100; /// > CUBIC multiplicative decrease factor /// @@ -173,7 +174,7 @@ impl Cubic { /// /// For implementation reasons neqo uses a dividend and divisor approach with `usize` typing to /// construct `CUBIC_BETA = 0.7` from `70/100`. - pub const BETA_USIZE_DIVIDEND: usize = 70; + pub(crate) const BETA_USIZE_DIVIDEND: usize = 70; /// As per RFC 8511 it makes sense to have a different decrease factor for ECN-CE congestion /// events than for loss induced congestion events. @@ -184,7 +185,7 @@ impl Cubic { /// /// For implementation reasons neqo uses a dividend and divisor approach with `usize` typing to /// construct the beta value from `85/100`. - pub const BETA_USIZE_DIVIDEND_ECN: usize = 85; + pub(crate) const BETA_USIZE_DIVIDEND_ECN: usize = 85; /// This is the factor that is used by fast convergence to further reduce the next `W_max` when /// a congestion event occurs while `cwnd < W_max`. This speeds up the bandwidth release for @@ -193,7 +194,7 @@ impl Cubic { /// The calculation assumes `CUBIC_BETA = 0.7`. /// /// - pub const FAST_CONVERGENCE_FACTOR: f64 = f64::midpoint(1.0, 0.7); + pub(crate) const FAST_CONVERGENCE_FACTOR: f64 = f64::midpoint(1.0, 0.7); /// Original equation is: /// @@ -263,12 +264,12 @@ impl Cubic { } #[cfg(test)] - pub const fn w_max(&self) -> Option { + pub(crate) const fn w_max(&self) -> Option { self.current.w_max } #[cfg(test)] - pub const fn set_w_max(&mut self, w_max: f64) { + pub(crate) const fn set_w_max(&mut self, w_max: f64) { self.current.w_max = Some(w_max); } } diff --git a/neqo-transport/src/cc/hystart.rs b/neqo-transport/src/cc/hystart.rs index 7705d3a831..45a5283b49 100644 --- a/neqo-transport/src/cc/hystart.rs +++ b/neqo-transport/src/cc/hystart.rs @@ -34,6 +34,7 @@ pub enum HyStartCssBaseline { } #[derive(Debug)] +#[expect(unreachable_pub, reason = "re-exported via cc::HyStart")] pub struct HyStart { /// > While an arriving ACK may newly acknowledge an arbitrary number of bytes, the HyStart++ /// > algorithm limits the number of those bytes applied to increase the cwnd to `L*SMSS` @@ -62,21 +63,21 @@ impl Display for HyStart { } impl HyStart { - pub const MIN_RTT_THRESH: Duration = Duration::from_millis(4); + pub(crate) const MIN_RTT_THRESH: Duration = Duration::from_millis(4); - pub const MAX_RTT_THRESH: Duration = Duration::from_millis(16); + pub(crate) const MAX_RTT_THRESH: Duration = Duration::from_millis(16); - pub const MIN_RTT_DIVISOR: u32 = 8; + pub(crate) const MIN_RTT_DIVISOR: u32 = 8; - pub const N_RTT_SAMPLE: usize = 8; + pub(crate) const N_RTT_SAMPLE: usize = 8; - pub const CSS_GROWTH_DIVISOR: usize = 4; + pub(crate) const CSS_GROWTH_DIVISOR: usize = 4; - pub const CSS_ROUNDS: usize = 5; + pub(crate) const CSS_ROUNDS: usize = 5; - pub const NON_PACED_L: usize = 8; + pub(crate) const NON_PACED_L: usize = 8; - pub const fn new(pacing: bool, css_baseline_mode: HyStartCssBaseline) -> Self { + pub(crate) const fn new(pacing: bool, css_baseline_mode: HyStartCssBaseline) -> Self { let limit = if pacing { usize::MAX } else { @@ -155,7 +156,7 @@ impl HyStart { } /// Checks if HyStart is in Conservative Slow Start. Is `pub` for use in tests. - pub const fn in_css(&self) -> bool { + pub(crate) const fn in_css(&self) -> bool { self.css_baseline_min_rtt.is_some() } @@ -164,27 +165,27 @@ impl HyStart { } #[cfg(test)] - pub const fn window_end(&self) -> Option { + pub(crate) const fn window_end(&self) -> Option { self.window_end } #[cfg(test)] - pub const fn rtt_sample_count(&self) -> usize { + pub(crate) const fn rtt_sample_count(&self) -> usize { self.rtt_sample_count } #[cfg(test)] - pub const fn current_round_min_rtt(&self) -> Option { + pub(crate) const fn current_round_min_rtt(&self) -> Option { self.current_round_min_rtt } #[cfg(test)] - pub const fn last_round_min_rtt(&self) -> Option { + pub(crate) const fn last_round_min_rtt(&self) -> Option { self.last_round_min_rtt } #[cfg(test)] - pub const fn css_round_count(&self) -> usize { + pub(crate) const fn css_round_count(&self) -> usize { self.css_round_count } } diff --git a/neqo-transport/src/cc/mod.rs b/neqo-transport/src/cc/mod.rs index f936116ab1..3186f0ebea 100644 --- a/neqo-transport/src/cc/mod.rs +++ b/neqo-transport/src/cc/mod.rs @@ -21,10 +21,15 @@ mod cubic; mod hystart; mod new_reno; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use classic_cc::{CWND_INITIAL_PKTS, ClassicCongestionController, PERSISTENT_CONG_THRESH}; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use classic_slow_start::ClassicSlowStart; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use cubic::Cubic; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use hystart::{HyStart, HyStartCssBaseline}; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use new_reno::NewReno; #[derive(Clone, Copy, PartialEq, Eq, Debug)] @@ -33,7 +38,7 @@ pub enum CongestionTrigger { Ecn, } -pub trait CongestionController: Display + Debug { +pub(crate) trait CongestionController: Display + Debug { fn set_qlog(&mut self, qlog: Qlog); #[must_use] diff --git a/neqo-transport/src/cc/new_reno.rs b/neqo-transport/src/cc/new_reno.rs index dbf3bfeaee..602a95bc67 100644 --- a/neqo-transport/src/cc/new_reno.rs +++ b/neqo-transport/src/cc/new_reno.rs @@ -17,6 +17,7 @@ use crate::{ }; #[derive(Debug, Default)] +#[expect(unreachable_pub, reason = "re-exported via cc::NewReno")] pub struct NewReno {} impl Display for NewReno { diff --git a/neqo-transport/src/cc/tests/mod.rs b/neqo-transport/src/cc/tests/mod.rs index 38a4967408..1365554dd6 100644 --- a/neqo-transport/src/cc/tests/mod.rs +++ b/neqo-transport/src/cc/tests/mod.rs @@ -21,12 +21,12 @@ mod cubic; mod hystart; mod new_reno; -pub const IP_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); -pub const MTU: Option = Some(1_500); -pub const RTT: Duration = Duration::from_millis(100); +pub(super) const IP_ADDR: IpAddr = IpAddr::V4(Ipv4Addr::UNSPECIFIED); +pub(super) const MTU: Option = Some(1_500); +pub(super) const RTT: Duration = Duration::from_millis(100); /// Helper to create `ClassicCongestionController` with New Reno for tests. -pub fn make_cc_newreno() -> ClassicCongestionController { +pub(super) fn make_cc_newreno() -> ClassicCongestionController { ClassicCongestionController::new( ClassicSlowStart::default(), NewReno::default(), @@ -36,7 +36,7 @@ pub fn make_cc_newreno() -> ClassicCongestionController ClassicCongestionController { +pub(super) fn make_cc_cubic() -> ClassicCongestionController { ClassicCongestionController::new( ClassicSlowStart::default(), Cubic::default(), @@ -46,7 +46,7 @@ pub fn make_cc_cubic() -> ClassicCongestionController { } /// Helper to create `ClassicCongestionController` with HyStart++ for tests. -pub fn make_cc_hystart(paced: bool) -> ClassicCongestionController { +pub(super) fn make_cc_hystart(paced: bool) -> ClassicCongestionController { ClassicCongestionController::new( HyStart::new(paced, crate::cc::HyStartCssBaseline::default()), Cubic::default(), diff --git a/neqo-transport/src/cid.rs b/neqo-transport/src/cid.rs index 77aec278ed..7a00b7083c 100644 --- a/neqo-transport/src/cid.rs +++ b/neqo-transport/src/cid.rs @@ -343,25 +343,25 @@ impl ConnectionIdEntry { } } -pub type RemoteConnectionIdEntry = ConnectionIdEntry; +pub(crate) type RemoteConnectionIdEntry = ConnectionIdEntry; /// A collection of connection IDs that are indexed by a sequence number. /// Used to store connection IDs that are provided by a peer. #[derive(Debug, Default)] -pub struct ConnectionIdStore { +pub(crate) struct ConnectionIdStore { cids: SmallVec<[ConnectionIdEntry; 8]>, } impl ConnectionIdStore { - pub fn retire(&mut self, seqno: u64) { + pub(crate) fn retire(&mut self, seqno: u64) { self.cids.retain(|c| c.seqno != seqno); } - pub fn contains(&self, cid: ConnectionIdRef) -> bool { + pub(crate) fn contains(&self, cid: ConnectionIdRef) -> bool { self.cids.iter().any(|c| c.cid == cid) } - pub fn next(&mut self) -> Option> { + pub(crate) fn next(&mut self) -> Option> { if self.cids.is_empty() { None } else { @@ -369,13 +369,13 @@ impl ConnectionIdStore { } } - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.cids.len() } } impl ConnectionIdStore { - pub fn add_remote(&mut self, entry: ConnectionIdEntry) -> Res<()> { + pub(crate) fn add_remote(&mut self, entry: ConnectionIdEntry) -> Res<()> { // It's OK if this perfectly matches an existing entry. if self.cids.iter().any(|c| c == &entry) { return Ok(()); @@ -396,7 +396,7 @@ impl ConnectionIdStore { } // Retire connection IDs and return the sequence numbers of those that were retired. - pub fn retire_prior_to(&mut self, retire_prior: u64) -> Vec { + pub(crate) fn retire_prior_to(&mut self, retire_prior: u64) -> Vec { let mut retired = Vec::new(); self.cids.retain(|e| { if !e.is_empty() && e.seqno < retire_prior { diff --git a/neqo-transport/src/connection/idle.rs b/neqo-transport/src/connection/idle.rs index 30dc4842b2..9ece31c257 100644 --- a/neqo-transport/src/connection/idle.rs +++ b/neqo-transport/src/connection/idle.rs @@ -27,21 +27,21 @@ enum IdleTimeoutState { /// -transport 10.1 ("Idle Timeout"). /// /// -pub struct IdleTimeout { +pub(super) struct IdleTimeout { timeout: Duration, state: IdleTimeoutState, keep_alive_outstanding: bool, } impl IdleTimeout { - pub const fn new(timeout: Duration) -> Self { + pub(super) const fn new(timeout: Duration) -> Self { Self { timeout, state: IdleTimeoutState::Init, keep_alive_outstanding: false, } } - pub fn set_peer_timeout(&mut self, peer_timeout: Duration) { + pub(super) fn set_peer_timeout(&mut self, peer_timeout: Duration) { self.timeout = min(self.timeout, peer_timeout); } @@ -52,14 +52,14 @@ impl IdleTimeout { } } - pub fn expiry(&self, now: Instant, pto: Duration) -> Instant { + pub(super) fn expiry(&self, now: Instant, pto: Duration) -> Instant { let delay = max(self.timeout, pto * 3); let t = self.start(now) + delay; qtrace!("IdleTimeout::expiry@{now:?} pto={pto:?} => {t:?}"); t } - pub const fn on_packet_sent(&mut self, now: Instant) { + pub(super) const fn on_packet_sent(&mut self, now: Instant) { // Only reset idle timeout if we've received a packet since the last // time we reset the timeout here. match self.state { @@ -78,7 +78,7 @@ impl IdleTimeout { } } - pub fn on_packet_received(&mut self, now: Instant) { + pub(super) fn on_packet_received(&mut self, now: Instant) { // Only update if this doesn't rewind the idle timeout. // We sometimes process packets after caching them, which uses // the time the packet was received. That could be in the past. @@ -93,7 +93,7 @@ impl IdleTimeout { } } - pub fn expired(&self, now: Instant, pto: Duration) -> bool { + pub(super) fn expired(&self, now: Instant, pto: Duration) -> bool { now >= self.expiry(now, pto) } @@ -103,7 +103,7 @@ impl IdleTimeout { self.start(now) + max(self.timeout / 2, pto) } - pub fn next_keep_alive(&self, now: Instant, pto: Duration) -> Option { + pub(super) fn next_keep_alive(&self, now: Instant, pto: Duration) -> Option { if self.keep_alive_outstanding { return None; } @@ -118,7 +118,7 @@ impl IdleTimeout { Some(timeout) } - pub fn send_keep_alive( + pub(super) fn send_keep_alive( &mut self, now: Instant, pto: Duration, @@ -133,11 +133,11 @@ impl IdleTimeout { } } - pub const fn lost_keep_alive(&mut self) { + pub(super) const fn lost_keep_alive(&mut self) { self.keep_alive_outstanding = false; } - pub const fn ack_keep_alive(&mut self) { + pub(super) const fn ack_keep_alive(&mut self) { self.keep_alive_outstanding = false; } } diff --git a/neqo-transport/src/connection/mod.rs b/neqo-transport/src/connection/mod.rs index d63bc5b6cd..711da253c8 100644 --- a/neqo-transport/src/connection/mod.rs +++ b/neqo-transport/src/connection/mod.rs @@ -68,18 +68,21 @@ use crate::{ }; mod idle; -pub mod params; +pub(crate) mod params; mod state; #[cfg(any(test, feature = "build-fuzzing-corpus"))] #[cfg_attr(coverage_nightly, coverage(off))] -pub mod test_internal; +pub(crate) mod test_internal; use idle::IdleTimeout; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use params::ConnectionParameters; use params::PreferredAddressConfig; use state::StateSignaling; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use state::{ClosingFrame, State}; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use crate::send_stream::{RetransmissionPriority, TransmissionPriority}; #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -237,14 +240,18 @@ enum AddressValidationInfo { } impl AddressValidationInfo { - pub fn token(&self) -> &[u8] { + pub(crate) fn token(&self) -> &[u8] { match self { Self::NewToken(token) | Self::Retry { token, .. } => token, _ => &[], } } - pub fn generate_new_token(&self, peer_address: SocketAddr, now: Instant) -> Option> { + pub(crate) fn generate_new_token( + &self, + peer_address: SocketAddr, + now: Instant, + ) -> Option> { match self { Self::Server(w) => w .upgrade()? diff --git a/neqo-transport/src/connection/params.rs b/neqo-transport/src/connection/params.rs index 2b14bdc78e..ad797d057e 100644 --- a/neqo-transport/src/connection/params.rs +++ b/neqo-transport/src/connection/params.rs @@ -6,6 +6,7 @@ use std::{cmp::max, time::Duration}; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use crate::recovery::FAST_PTO_SCALE; use crate::{ CongestionControl, DEFAULT_INITIAL_RTT, HyStartCssBaseline, Res, SlowStart, @@ -82,7 +83,7 @@ pub const MAX_LOCAL_MAX_STREAM_DATA: u64 = 10 * 1024 * 1024; /// for the size of the connection-level receive window. /// /// See also . -pub const MAX_LOCAL_MAX_DATA: u64 = MAX_LOCAL_MAX_STREAM_DATA * CONNECTION_FACTOR; +pub(crate) const MAX_LOCAL_MAX_DATA: u64 = MAX_LOCAL_MAX_STREAM_DATA * CONNECTION_FACTOR; // Maximum size of a QUIC DATAGRAM frame, as specified in https://datatracker.ietf.org/doc/html/rfc9221#section-3-4. const MAX_DATAGRAM_FRAME_SIZE: u64 = 65535; diff --git a/neqo-transport/src/connection/state.rs b/neqo-transport/src/connection/state.rs index b0f0e2df4a..baf2425fa2 100644 --- a/neqo-transport/src/connection/state.rs +++ b/neqo-transport/src/connection/state.rs @@ -76,6 +76,7 @@ impl State { } #[derive(Debug, Clone)] +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub struct ClosingFrame { path: PathRef, error: CloseReason, @@ -99,11 +100,11 @@ impl ClosingFrame { } } - pub const fn path(&self) -> &PathRef { + pub(crate) const fn path(&self) -> &PathRef { &self.path } - pub fn sanitize(&self) -> Option { + pub(crate) fn sanitize(&self) -> Option { if let CloseReason::Application(_) = self.error { // The default CONNECTION_CLOSE frame that is sent when an application // error code needs to be sent in an Initial or Handshake packet. @@ -121,9 +122,9 @@ impl ClosingFrame { /// Length of a closing frame with a truncated `reason_length`. Allow 8 bytes for the reason /// phrase to ensure that if it needs to be truncated there is still at least a few bytes of /// the value. - pub const MIN_LENGTH: usize = 1 + 8 + 8 + 2 + 8; + pub(crate) const MIN_LENGTH: usize = 1 + 8 + 8 + 2 + 8; - pub fn write_frame(&self, builder: &mut packet::Builder) { + pub(crate) fn write_frame(&self, builder: &mut packet::Builder) { if builder.remaining() < Self::MIN_LENGTH { return; } @@ -162,7 +163,7 @@ impl ClosingFrame { /// * `CloseSent` -> Closing: any time a new `CONNECTION_CLOSE` is needed /// * -> Reset: from any state in case of a stateless reset #[derive(Debug, Clone)] -pub enum StateSignaling { +pub(super) enum StateSignaling { Idle, HandshakeDone, /// These states save the frame that needs to be sent. @@ -175,14 +176,14 @@ pub enum StateSignaling { } impl StateSignaling { - pub fn handshake_done(&mut self) { + pub(super) fn handshake_done(&mut self) { if !matches!(self, Self::Idle) { return; } *self = Self::HandshakeDone; } - pub fn write_done( + pub(super) fn write_done( &mut self, builder: &mut packet::Builder, ) -> Option { @@ -193,7 +194,7 @@ impl StateSignaling { }) } - pub fn close>( + pub(super) fn close>( &mut self, path: PathRef, error: CloseReason, @@ -205,7 +206,7 @@ impl StateSignaling { } } - pub fn drain>( + pub(super) fn drain>( &mut self, path: PathRef, error: CloseReason, @@ -218,7 +219,7 @@ impl StateSignaling { } /// If a close is pending, take a frame. - pub fn close_frame(&mut self) -> Option { + pub(super) fn close_frame(&mut self) -> Option { match self { Self::Closing(frame) => { // When we are closing, we might need to send the close frame again. @@ -237,14 +238,14 @@ impl StateSignaling { } /// If a close can be sent again, prepare to send it again. - pub fn send_close(&mut self) { + pub(super) fn send_close(&mut self) { if let Self::CloseSent(Some(frame)) = self { *self = Self::Closing(frame.clone()); } } /// We just got a stateless reset. Terminate. - pub fn reset(&mut self) { + pub(super) fn reset(&mut self) { *self = Self::Reset; } } diff --git a/neqo-transport/src/connection/tests/ecn.rs b/neqo-transport/src/connection/tests/ecn.rs index 57386844de..9e1e251b7c 100644 --- a/neqo-transport/src/connection/tests/ecn.rs +++ b/neqo-transport/src/connection/tests/ecn.rs @@ -307,7 +307,7 @@ fn disables_on_remark() { /// modifies packets via `new_path_modifier`. It sends `burst` packets on the new path. /// The function returns the TOS value of the last packet sent on the old path and the TOS value /// of the last packet sent on the new path to allow for verification of correct behavior. -pub fn migration_with_modifiers( +pub(super) fn migration_with_modifiers( orig_path_modifier: fn(Datagram) -> Option, new_path_modifier: fn(Datagram) -> Option, burst: usize, diff --git a/neqo-transport/src/connection/tests/migration.rs b/neqo-transport/src/connection/tests/migration.rs index bfa51f8702..03246cb8b2 100644 --- a/neqo-transport/src/connection/tests/migration.rs +++ b/neqo-transport/src/connection/tests/migration.rs @@ -618,7 +618,7 @@ fn migrate_same_fail() { /// This gets the connection ID from a datagram using the default /// connection ID generator/decoder. -pub fn get_cid(d: &Datagram) -> ConnectionIdRef<'_> { +pub(super) fn get_cid(d: &Datagram) -> ConnectionIdRef<'_> { let r#gen = CountingConnectionIdGenerator::default(); assert_eq!(d[0] & 0x80, 0); // Only support short packets for now. r#gen.decode_cid(&mut Decoder::from(&d[1..])).unwrap() diff --git a/neqo-transport/src/connection/tests/mod.rs b/neqo-transport/src/connection/tests/mod.rs index 073c6f3d94..4d19398e9a 100644 --- a/neqo-transport/src/connection/tests/mod.rs +++ b/neqo-transport/src/connection/tests/mod.rs @@ -67,7 +67,7 @@ const CLIENT_HANDSHAKE_1RTT_PACKETS: usize = 1; /// This version doesn't randomize the length; as the congestion control tests /// count the amount of data sent precisely. #[derive(Debug, Default)] -pub struct CountingConnectionIdGenerator { +pub(super) struct CountingConnectionIdGenerator { counter: u32, } @@ -101,7 +101,7 @@ impl ConnectionIdGenerator for CountingConnectionIdGenerator { // test_fixture because they produce different - and incompatible - types. // // These are a direct copy of those functions. -pub fn new_client(params: ConnectionParameters) -> Connection { +pub(super) fn new_client(params: ConnectionParameters) -> Connection { fixture_init(); let (log, _contents) = new_neqo_qlog(); let mut client = Connection::new_client( @@ -118,7 +118,7 @@ pub fn new_client(params: ConnectionParameters) -> Connection { client } -pub fn default_client() -> Connection { +pub(super) fn default_client() -> Connection { new_client(ConnectionParameters::default()) } @@ -135,7 +135,7 @@ fn zero_len_cid_client(local_addr: SocketAddr, remote_addr: SocketAddr) -> Conne .unwrap() } -pub fn new_server(params: ConnectionParameters) -> Connection { +pub(super) fn new_server(params: ConnectionParameters) -> Connection { fixture_init(); let (log, _contents) = new_neqo_qlog(); let mut c = Connection::new_server( @@ -150,16 +150,16 @@ pub fn new_server(params: ConnectionParameters) -> Connection { .expect("enable 0-RTT"); c } -pub fn default_server() -> Connection { +pub(super) fn default_server() -> Connection { new_server(ConnectionParameters::default()) } -pub fn resumed_server(client: &Connection) -> Connection { +pub(super) fn resumed_server(client: &Connection) -> Connection { new_server(ConnectionParameters::default().versions(client.version(), Version::all())) } /// If state is `AuthenticationNeeded` call `authenticated()`. This function will /// consume all outstanding events on the connection. -pub fn maybe_authenticate(conn: &mut Connection) -> bool { +pub(super) fn maybe_authenticate(conn: &mut Connection) -> bool { let authentication_needed = |e| matches!(e, ConnectionEvent::AuthenticationNeeded); if conn.events().any(authentication_needed) { conn.authenticated(AuthenticationStatus::Ok, now()); @@ -169,7 +169,7 @@ pub fn maybe_authenticate(conn: &mut Connection) -> bool { } /// Compute the RTT variance after `n` ACKs or other RTT updates. -pub fn rttvar_after_n_updates(n: usize, rtt: Duration) -> Duration { +pub(super) fn rttvar_after_n_updates(n: usize, rtt: Duration) -> Duration { assert!(n > 0); let mut rttvar = rtt / 2; for _ in 1..n { diff --git a/neqo-transport/src/connection/tests/vn.rs b/neqo-transport/src/connection/tests/vn.rs index 6dc21484a5..907c466f5f 100644 --- a/neqo-transport/src/connection/tests/vn.rs +++ b/neqo-transport/src/connection/tests/vn.rs @@ -35,7 +35,7 @@ const INITIAL_PTO: Duration = Duration::from_millis(300); /// /// When the count of received packets doesn't match the count of received packets with the /// (default) DSCP. -pub fn assert_dscp(stats: &Stats) { +pub(super) fn assert_dscp(stats: &Stats) { assert_eq!(stats.dscp_rx[Dscp::Cs0], stats.packets_rx); } @@ -590,7 +590,7 @@ fn server_initial_versions() { /// packet receipt correctly. #[test] fn client_initial_versions() { - pub struct CryptoWriter {} + pub(crate) struct CryptoWriter {} impl test_internal::FrameWriter for CryptoWriter { fn write_frames(&mut self, builder: &mut packet::Builder<&mut Vec>) { diff --git a/neqo-transport/src/crypto.rs b/neqo-transport/src/crypto.rs index 527feb5977..35b095d3f7 100644 --- a/neqo-transport/src/crypto.rs +++ b/neqo-transport/src/crypto.rs @@ -16,6 +16,7 @@ use std::{ use enum_map::EnumMap; use neqo_common::{Buffer, Encoder, Role, hex, hex_snip_middle, qdebug, qinfo, qtrace}; +#[expect(unreachable_pub, reason = "re-exported via lib.rs")] pub use nss::Epoch; use nss::{ Agent, AntiReplay, Cipher, Error as CryptoError, HandshakeState, PrivateKey, PublicKey, Record, @@ -44,7 +45,7 @@ use crate::{ /// to update keys. This has to be much smaller than the number returned /// by `CryptoDxState::limit` or updates will happen too often. As we don't /// need to ask permission to update, this can be quite small. -pub const UPDATE_WRITE_KEYS_AT: packet::Number = 100; +pub(crate) const UPDATE_WRITE_KEYS_AT: packet::Number = 100; // This is a testing kludge that allows for overwriting the number of // invocations of the next cipher to operate. With this, it is possible @@ -55,7 +56,7 @@ pub const UPDATE_WRITE_KEYS_AT: packet::Number = 100; thread_local!(pub static OVERWRITE_INVOCATIONS: RefCell> = RefCell::default()); #[derive(Debug)] -pub struct Crypto { +pub(crate) struct Crypto { version: Version, protocols: Vec, tls: Agent, @@ -66,7 +67,7 @@ pub struct Crypto { type TpHandler = Rc>; impl Crypto { - pub fn new( + pub(crate) fn new( version: Version, conn_params: &ConnectionParameters, mut agent: Agent, @@ -122,7 +123,7 @@ impl Crypto { } /// Get the name of the server. (Only works for the client currently). - pub fn server_name(&self) -> Option<&str> { + pub(crate) fn server_name(&self) -> Option<&str> { if let Agent::Client(c) = &self.tls { Some(c.server_name()) } else { @@ -131,11 +132,11 @@ impl Crypto { } /// Get the set of enabled protocols. - pub fn protocols(&self) -> &[String] { + pub(crate) fn protocols(&self) -> &[String] { &self.protocols } - pub fn server_enable_0rtt( + pub(crate) fn server_enable_0rtt( &mut self, tphandler: TpHandler, anti_replay: &AntiReplay, @@ -152,7 +153,7 @@ impl Crypto { } } - pub fn server_enable_ech( + pub(crate) fn server_enable_ech( &mut self, config: u8, public_name: &str, @@ -167,7 +168,7 @@ impl Crypto { } } - pub fn client_enable_ech>(&mut self, ech_config_list: A) -> Res<()> { + pub(crate) fn client_enable_ech>(&mut self, ech_config_list: A) -> Res<()> { if let Agent::Client(c) = &mut self.tls { c.enable_ech(ech_config_list)?; Ok(()) @@ -177,11 +178,11 @@ impl Crypto { } /// Get the active ECH configuration, which is empty if ECH is disabled. - pub fn ech_config(&self) -> &[u8] { + pub(crate) fn ech_config(&self) -> &[u8] { self.tls.ech_config() } - pub fn handshake( + pub(crate) fn handshake( &mut self, now: Instant, space: PacketNumberSpace, @@ -218,7 +219,7 @@ impl Crypto { } /// Enable 0-RTT and return `true` if it is enabled successfully. - pub fn enable_0rtt(&mut self, version: Version, role: Role) -> Res { + pub(crate) fn enable_0rtt(&mut self, version: Version, role: Role) -> Res { let info = self.tls.preinfo()?; // `info.early_data()` returns false for a server, // so use `early_data_cipher()` to tell if 0-RTT is enabled. @@ -241,14 +242,14 @@ impl Crypto { } /// Lock in a compatible upgrade. - pub fn confirm_version(&mut self, confirmed: Version) -> Res<()> { + pub(crate) fn confirm_version(&mut self, confirmed: Version) -> Res<()> { self.states.confirm_version(self.version, confirmed)?; self.version = confirmed; Ok(()) } /// Returns true if new handshake keys were installed. - pub fn install_keys(&mut self, role: Role) -> Res { + pub(crate) fn install_keys(&mut self, role: Role) -> Res { if self.tls.state().is_final() { Ok(false) } else { @@ -282,7 +283,7 @@ impl Crypto { } #[must_use] - pub const fn has_handshake_keys(&self) -> bool { + pub(crate) const fn has_handshake_keys(&self) -> bool { self.states.handshake.is_some() || self.states.app_write.is_some() } @@ -295,7 +296,11 @@ impl Crypto { Ok(()) } - pub fn install_application_keys(&mut self, version: Version, expire_0rtt: Instant) -> Res<()> { + pub(crate) fn install_application_keys( + &mut self, + version: Version, + expire_0rtt: Instant, + ) -> Res<()> { self.maybe_install_application_write_key(version)?; // The write key might have been installed earlier, but it should // always be installed now. @@ -311,7 +316,7 @@ impl Crypto { } /// Buffer crypto records for sending. - pub fn buffer_records(&mut self, records: RecordList) -> Res<()> { + pub(crate) fn buffer_records(&mut self, records: RecordList) -> Res<()> { for r in records { if r.ct != TLS_CT_HANDSHAKE { return Err(Error::ProtocolViolation); @@ -322,7 +327,7 @@ impl Crypto { Ok(()) } - pub fn write_frame( + pub(crate) fn write_frame( &mut self, space: PacketNumberSpace, sni_slicing: bool, @@ -334,7 +339,7 @@ impl Crypto { .write_frame(space, sni_slicing, builder, tokens, stats); } - pub fn acked(&mut self, token: &CryptoRecoveryToken) { + pub(crate) fn acked(&mut self, token: &CryptoRecoveryToken) { qdebug!( "Acked crypto frame space={} offset={} length={}", token.space, @@ -344,7 +349,7 @@ impl Crypto { self.streams.acked(token); } - pub fn lost(&mut self, token: &CryptoRecoveryToken) { + pub(crate) fn lost(&mut self, token: &CryptoRecoveryToken) { qinfo!( "Lost crypto frame space={} offset={} length={}", token.space, @@ -356,18 +361,18 @@ impl Crypto { /// Mark any outstanding frames in the indicated space as "lost" so /// that they can be sent again. - pub fn resend_unacked(&mut self, space: PacketNumberSpace) { + pub(crate) fn resend_unacked(&mut self, space: PacketNumberSpace) { self.streams.resend_unacked(space); } /// Discard state for a packet number space and return true /// if something was discarded. - pub fn discard(&mut self, space: PacketNumberSpace) -> bool { + pub(crate) fn discard(&mut self, space: PacketNumberSpace) -> bool { self.streams.discard(space); self.states.discard(space) } - pub fn create_resumption_token( + pub(crate) fn create_resumption_token( &mut self, new_token: Option<&[u8]>, tps: &TransportParameters, @@ -393,7 +398,7 @@ impl Crypto { } } - pub fn has_resumption_token(&self) -> bool { + pub(crate) fn has_resumption_token(&self) -> bool { if let Agent::Client(c) = &self.tls { c.has_resumption_token() } else { @@ -402,32 +407,32 @@ impl Crypto { } #[must_use] - pub const fn tls_mut(&mut self) -> &mut Agent { + pub(crate) const fn tls_mut(&mut self) -> &mut Agent { &mut self.tls } #[must_use] - pub const fn tls(&self) -> &Agent { + pub(crate) const fn tls(&self) -> &Agent { &self.tls } #[must_use] - pub const fn streams(&self) -> &CryptoStreams { + pub(crate) const fn streams(&self) -> &CryptoStreams { &self.streams } #[must_use] - pub const fn streams_mut(&mut self) -> &mut CryptoStreams { + pub(crate) const fn streams_mut(&mut self) -> &mut CryptoStreams { &mut self.streams } #[must_use] - pub const fn states(&self) -> &CryptoStates { + pub(crate) const fn states(&self) -> &CryptoStates { &self.states } #[must_use] - pub const fn states_mut(&mut self) -> &mut CryptoStates { + pub(crate) const fn states_mut(&mut self) -> &mut CryptoStates { &mut self.states } } @@ -761,7 +766,7 @@ impl Display for CryptoDxState { } #[derive(Debug)] -pub struct CryptoState { +pub(crate) struct CryptoState { tx: CryptoDxState, rx: CryptoDxState, } @@ -769,7 +774,7 @@ pub struct CryptoState { /// `CryptoDxAppData` wraps the state necessary for one direction of application data keys. /// This includes the secret needed to generate the next set of keys. #[derive(Debug)] -pub struct CryptoDxAppData { +pub(crate) struct CryptoDxAppData { dx: CryptoDxState, cipher: Cipher, // Not the secret used to create `self.dx`, but the one needed for the next iteration. @@ -777,7 +782,7 @@ pub struct CryptoDxAppData { } impl CryptoDxAppData { - pub fn new( + pub(crate) fn new( version: Version, dir: CryptoDxDirection, secret: &SymKey, @@ -795,7 +800,7 @@ impl CryptoDxAppData { Ok(next) } - pub fn next(&self) -> Res { + pub(crate) fn next(&self) -> Res { if self.dx.epoch == usize::MAX { // Guard against too many key updates. return Err(Error::KeysExhausted); @@ -808,7 +813,7 @@ impl CryptoDxAppData { }) } - pub const fn epoch(&self) -> usize { + pub(crate) const fn epoch(&self) -> usize { self.dx.epoch } } @@ -819,7 +824,7 @@ impl CryptoDxAppData { /// used for Initial keys; a version has been selected at the time we need to /// get other keys, so those have fixed versions. #[derive(Debug, Default)] -pub struct CryptoStates { +pub(crate) struct CryptoStates { initials: EnumMap>, handshake: Option, zero_rtt: Option, // One direction only! @@ -840,7 +845,7 @@ impl CryptoStates { /// Select a `CryptoDxState` and `CryptoSpace` for the given `PacketNumberSpace`. /// This selects 0-RTT keys for `PacketNumberSpace::ApplicationData` if 1-RTT keys are /// not yet available. - pub fn select_tx_mut( + pub(crate) fn select_tx_mut( &mut self, version: Version, space: PacketNumberSpace, @@ -862,7 +867,7 @@ impl CryptoStates { } } - pub fn tx_mut<'a>( + pub(crate) fn tx_mut<'a>( &'a mut self, version: Version, epoch: Epoch, @@ -879,7 +884,7 @@ impl CryptoStates { } } - pub fn tx<'a>(&'a self, version: Version, epoch: Epoch) -> Option<&'a CryptoDxState> { + pub(crate) fn tx<'a>(&'a self, version: Version, epoch: Epoch) -> Option<&'a CryptoDxState> { let tx = |k: Option<&'a CryptoState>| k.map(|dx| &dx.tx); match epoch { Epoch::Initial => tx(self.initials[version].as_ref()), @@ -892,7 +897,7 @@ impl CryptoStates { } } - pub fn select_tx( + pub(crate) fn select_tx( &self, version: Version, space: PacketNumberSpace, @@ -956,7 +961,7 @@ impl CryptoStates { } } - pub fn rx_hp(&mut self, version: Version, epoch: Epoch) -> Option<&mut CryptoDxState> { + pub(crate) fn rx_hp(&mut self, version: Version, epoch: Epoch) -> Option<&mut CryptoDxState> { match epoch { Epoch::ApplicationData => self.app_read.as_mut().map(|ar| &mut ar.dx), Epoch::Initial => { @@ -967,7 +972,7 @@ impl CryptoStates { } } - pub fn rx<'a>( + pub(crate) fn rx<'a>( &'a mut self, version: Version, epoch: Epoch, @@ -1001,7 +1006,7 @@ impl CryptoStates { /// is possible to attribute 0-RTT packets to an existing connection if there /// is a multi-packet Initial, that is an unusual circumstance, so we /// don't do caching for that in those places that call this function. - pub fn rx_pending(&self, space: Epoch) -> bool { + pub(crate) fn rx_pending(&self, space: Epoch) -> bool { match space { Epoch::Initial | Epoch::ZeroRtt => false, Epoch::Handshake => self.handshake.is_none() && !self.initials_is_empty(), @@ -1011,7 +1016,7 @@ impl CryptoStates { /// Create the initial crypto state. /// Note that the version here can change and that's OK. - pub fn init<'v, V>( + pub(crate) fn init<'v, V>( &mut self, versions: V, role: Role, @@ -1072,7 +1077,7 @@ impl CryptoStates { /// This is maybe slightly inefficient in the first case, because we might /// not need the send keys if the packet is subsequently discarded, but /// the overall effort is small enough to write off. - pub fn init_server( + pub(crate) fn init_server( &mut self, version: Version, dcid: &[u8], @@ -1084,7 +1089,7 @@ impl CryptoStates { Ok(()) } - pub fn confirm_version(&mut self, orig: Version, confirmed: Version) -> Res<()> { + pub(crate) fn confirm_version(&mut self, orig: Version, confirmed: Version) -> Res<()> { if orig != confirmed { // This part where the old data is removed and then re-added is to // appease the borrow checker. @@ -1102,7 +1107,7 @@ impl CryptoStates { Ok(()) } - pub fn set_0rtt_keys( + pub(crate) fn set_0rtt_keys( &mut self, version: Version, dir: CryptoDxDirection, @@ -1122,7 +1127,7 @@ impl CryptoStates { } /// Discard keys and return true if that happened. - pub fn discard(&mut self, space: PacketNumberSpace) -> bool { + pub(crate) fn discard(&mut self, space: PacketNumberSpace) -> bool { match space { PacketNumberSpace::Initial => { let empty = self.initials_is_empty(); @@ -1134,7 +1139,7 @@ impl CryptoStates { } } - pub fn discard_0rtt_keys(&mut self) { + pub(crate) fn discard_0rtt_keys(&mut self) { qtrace!("[{self}] discard 0-RTT keys"); assert!( self.app_read.is_none(), @@ -1143,7 +1148,7 @@ impl CryptoStates { self.zero_rtt = None; } - pub fn set_handshake_keys( + pub(crate) fn set_handshake_keys( &mut self, version: Version, write_secret: &SymKey, @@ -1172,7 +1177,11 @@ impl CryptoStates { Ok(()) } - pub fn set_application_write_key(&mut self, version: Version, secret: &SymKey) -> Res<()> { + pub(crate) fn set_application_write_key( + &mut self, + version: Version, + secret: &SymKey, + ) -> Res<()> { debug_assert!(self.app_write.is_none()); debug_assert_ne!(self.cipher, 0); let mut app = CryptoDxAppData::new(version, CryptoDxDirection::Write, secret, self.cipher)?; @@ -1186,7 +1195,7 @@ impl CryptoStates { Ok(()) } - pub fn set_application_read_key( + pub(crate) fn set_application_read_key( &mut self, version: Version, secret: &SymKey, @@ -1207,7 +1216,10 @@ impl CryptoStates { } /// Update the write keys. - pub fn initiate_key_update(&mut self, largest_acknowledged: Option) -> Res<()> { + pub(crate) fn initiate_key_update( + &mut self, + largest_acknowledged: Option, + ) -> Res<()> { // Only update if we are able to. We can only do this if we have // received an acknowledgement for a packet in the current phase. // Also, skip this if we are waiting for read keys on the existing @@ -1248,7 +1260,7 @@ impl CryptoStates { /// Check whether write keys are close to running out of invocations. /// If that is close, update them if possible. Failing to update at /// this stage is cause for a fatal error. - pub fn auto_update(&mut self) -> Res<()> { + pub(crate) fn auto_update(&mut self) -> Res<()> { if let Some(app_write) = self.app_write.as_ref() && app_write.dx.should_update() { @@ -1269,7 +1281,7 @@ impl CryptoStates { /// Prepare to update read keys. This doesn't happen immediately as /// we want to ensure that we can continue to receive any delayed /// packets that use the old keys. So we just set a timer. - pub fn key_update_received(&mut self, expiration: Instant) -> Res<()> { + pub(crate) fn key_update_received(&mut self, expiration: Instant) -> Res<()> { qtrace!("[{self}] Key update received"); // If we received a key update, then we assume that the peer has // acknowledged a packet we sent in this epoch. It's OK to do that @@ -1288,14 +1300,14 @@ impl CryptoStates { } #[must_use] - pub const fn update_time(&self) -> Option { + pub(crate) const fn update_time(&self) -> Option { self.read_update_time } /// Check if time has passed for updating key update parameters. /// If it has, then swap keys over and allow more key updates to be initiated. /// This is also used to discard 0-RTT read keys at the server in the same way. - pub fn check_key_update(&mut self, now: Instant) -> Res<()> { + pub(crate) fn check_key_update(&mut self, now: Instant) -> Res<()> { if let Some(expiry) = self.read_update_time { // If enough time has passed, then install new keys and clear the timer. if now >= expiry { @@ -1316,7 +1328,7 @@ impl CryptoStates { /// Get the current/highest epoch. This returns (write, read) epochs. #[cfg(test)] - pub fn get_epochs(&self) -> (Option, Option) { + pub(crate) fn get_epochs(&self) -> (Option, Option) { let to_epoch = |app: &Option| app.as_ref().map(|a| a.dx.epoch); (to_epoch(&self.app_write), to_epoch(&self.app_read)) } @@ -1325,7 +1337,7 @@ impl CryptoStates { /// valid packets that are protected with old keys. We need to ensure that /// these don't carry packet numbers higher than those in packets protected /// with the newer keys. To ensure that, this is called after every decryption. - pub fn check_pn_overlap(&mut self) -> Res<()> { + pub(crate) fn check_pn_overlap(&mut self) -> Res<()> { // We only need to do the check while we are waiting for read keys to be updated. if self.read_update_time.is_some() { qtrace!("[{self}] Checking for PN overlap"); @@ -1427,13 +1439,13 @@ impl Display for CryptoStates { } #[derive(Debug, Default)] -pub struct CryptoStream { +pub(crate) struct CryptoStream { tx: TxBuffer, rx: RxStreamOrderer, } #[derive(Debug)] -pub enum CryptoStreams { +pub(crate) enum CryptoStreams { Initial { initial: CryptoStream, handshake: CryptoStream, @@ -1452,7 +1464,7 @@ impl CryptoStreams { /// Keep around 64k if a server wants to push excess data at us. const BUFFER_LIMIT: u64 = 65536; - pub fn discard(&mut self, space: PacketNumberSpace) { + pub(crate) fn discard(&mut self, space: PacketNumberSpace) { match space { PacketNumberSpace::Initial => { if let Self::Initial { @@ -1482,7 +1494,7 @@ impl CryptoStreams { } } - pub fn send(&mut self, space: PacketNumberSpace, data: &[u8]) -> Res<()> { + pub(crate) fn send(&mut self, space: PacketNumberSpace, data: &[u8]) -> Res<()> { self.get_mut(space) .ok_or(Error::ProtocolViolation)? .tx @@ -1490,7 +1502,12 @@ impl CryptoStreams { Ok(()) } - pub fn inbound_frame(&mut self, space: PacketNumberSpace, offset: u64, data: &[u8]) -> Res<()> { + pub(crate) fn inbound_frame( + &mut self, + space: PacketNumberSpace, + offset: u64, + data: &[u8], + ) -> Res<()> { let rx = &mut self.get_mut(space).ok_or(Error::Internal)?.rx; rx.inbound_frame(offset, data); if rx.received() - rx.retired() <= Self::BUFFER_LIMIT { @@ -1500,11 +1517,15 @@ impl CryptoStreams { } } - pub fn data_ready(&self, space: PacketNumberSpace) -> bool { + pub(crate) fn data_ready(&self, space: PacketNumberSpace) -> bool { self.get(space).is_some_and(|cs| cs.rx.data_ready()) } - pub fn read_to_end(&mut self, space: PacketNumberSpace, buf: &mut Vec) -> Res { + pub(crate) fn read_to_end( + &mut self, + space: PacketNumberSpace, + buf: &mut Vec, + ) -> Res { Ok(self .get_mut(space) .ok_or(Error::ProtocolViolation)? @@ -1512,13 +1533,13 @@ impl CryptoStreams { .read_to_end(buf)) } - pub fn acked(&mut self, token: &CryptoRecoveryToken) { + pub(crate) fn acked(&mut self, token: &CryptoRecoveryToken) { if let Some(cs) = self.get_mut(token.space) { cs.tx.mark_as_acked(token.offset, token.length); } } - pub fn lost(&mut self, token: &CryptoRecoveryToken) { + pub(crate) fn lost(&mut self, token: &CryptoRecoveryToken) { // See BZ 1624800, ignore lost packets in spaces we've dropped keys if let Some(cs) = self.get_mut(token.space) { cs.tx.mark_as_lost(token.offset, token.length); @@ -1527,7 +1548,7 @@ impl CryptoStreams { /// Resend any Initial or Handshake CRYPTO frames that might be outstanding. /// This can help speed up handshake times. - pub fn resend_unacked(&mut self, space: PacketNumberSpace) { + pub(crate) fn resend_unacked(&mut self, space: PacketNumberSpace) { if space != PacketNumberSpace::ApplicationData && let Some(cs) = self.get_mut(space) { @@ -1535,7 +1556,7 @@ impl CryptoStreams { } } - pub fn is_empty(&mut self, space: PacketNumberSpace) -> bool { + pub(crate) fn is_empty(&mut self, space: PacketNumberSpace) -> bool { self.get_mut(space).is_none_or(|cs| cs.tx.is_empty()) } @@ -1579,7 +1600,7 @@ impl CryptoStreams { } } - pub fn write_frame( + pub(crate) fn write_frame( &mut self, space: PacketNumberSpace, sni_slicing: bool, diff --git a/neqo-transport/src/fc.rs b/neqo-transport/src/fc.rs index e8e5c2f304..a176e9b64a 100644 --- a/neqo-transport/src/fc.rs +++ b/neqo-transport/src/fc.rs @@ -35,7 +35,7 @@ use crate::{ /// per RTT. /// /// Value aligns with [`crate::connection::params::ConnectionParameters::DEFAULT_ACK_RATIO`]. -pub const WINDOW_UPDATE_FRACTION: u64 = 4; +pub(crate) const WINDOW_UPDATE_FRACTION: u64 = 4; /// Multiplier for auto-tuning the stream receive window. /// @@ -616,13 +616,13 @@ impl ReceiverFlowControl { } } -pub struct RemoteStreamLimit { +pub(crate) struct RemoteStreamLimit { streams_fc: ReceiverFlowControl, next_stream: StreamId, } impl RemoteStreamLimit { - pub const fn new(stream_type: StreamType, max_streams: u64, role: Role) -> Self { + pub(crate) const fn new(stream_type: StreamType, max_streams: u64, role: Role) -> Self { Self { streams_fc: ReceiverFlowControl::new(stream_type, max_streams), // // This is for a stream created by a peer, therefore we use role.remote(). @@ -630,19 +630,19 @@ impl RemoteStreamLimit { } } - pub const fn is_allowed(&self, stream_id: StreamId) -> bool { + pub(crate) const fn is_allowed(&self, stream_id: StreamId) -> bool { let stream_idx = stream_id.as_u64() >> 2; self.streams_fc.check_allowed(stream_idx) } - pub fn is_new_stream(&self, stream_id: StreamId) -> Res { + pub(crate) fn is_new_stream(&self, stream_id: StreamId) -> Res { if !self.is_allowed(stream_id) { return Err(Error::StreamLimit); } Ok(stream_id >= self.next_stream) } - pub fn take_stream_id(&mut self) -> StreamId { + pub(crate) fn take_stream_id(&mut self) -> StreamId { let new_stream = self.next_stream; self.next_stream.next(); assert!(self.is_allowed(new_stream)); @@ -663,10 +663,14 @@ impl DerefMut for RemoteStreamLimit { } } -pub struct RemoteStreamLimits(EnumMap); +pub(crate) struct RemoteStreamLimits(EnumMap); impl RemoteStreamLimits { - pub const fn new(local_max_stream_bidi: u64, local_max_stream_uni: u64, role: Role) -> Self { + pub(crate) const fn new( + local_max_stream_bidi: u64, + local_max_stream_uni: u64, + role: Role, + ) -> Self { // Array order must match StreamType enum order: BiDi, UniDi Self(EnumMap::from_array([ RemoteStreamLimit::new(StreamType::BiDi, local_max_stream_bidi, role), @@ -689,13 +693,13 @@ impl IndexMut for RemoteStreamLimits { } } -pub struct LocalStreamLimits { +pub(crate) struct LocalStreamLimits { limits: EnumMap>, role_bit: u64, } impl LocalStreamLimits { - pub const fn new(role: Role) -> Self { + pub(crate) const fn new(role: Role) -> Self { Self { // Array order must match StreamType enum order: BiDi, UniDi limits: EnumMap::from_array([ @@ -706,7 +710,7 @@ impl LocalStreamLimits { } } - pub fn take_stream_id(&mut self, stream_type: StreamType) -> Option { + pub(crate) fn take_stream_id(&mut self, stream_type: StreamType) -> Option { let fc = &mut self.limits[stream_type]; if fc.available() > 0 { let new_stream = fc.used(); diff --git a/neqo-transport/src/frame.rs b/neqo-transport/src/frame.rs index cb9447a785..c48dab39d1 100644 --- a/neqo-transport/src/frame.rs +++ b/neqo-transport/src/frame.rs @@ -681,7 +681,7 @@ impl<'a> Frame<'a> { } /// Extension trait for [`Encoder`] that automates writing to fuzzing corpus. -pub trait FrameEncoder { +pub(crate) trait FrameEncoder { /// Encode a frame with the given type and encoding closure. /// /// This method: diff --git a/neqo-transport/src/pace.rs b/neqo-transport/src/pace.rs index aeeac25784..7fe37e527c 100644 --- a/neqo-transport/src/pace.rs +++ b/neqo-transport/src/pace.rs @@ -17,7 +17,7 @@ use neqo_common::qtrace; use crate::rtt::GRANULARITY; /// A pacer that uses a leaky bucket. -pub struct Pacer { +pub(crate) struct Pacer { /// Whether pacing is enabled. enabled: bool, /// The last update time. @@ -52,7 +52,7 @@ impl Pacer { /// The value of `p` is the packet size in bytes, which determines the minimum /// credit needed before a packet is sent. This should be a substantial /// fraction of the maximum packet size, if not the packet size. - pub fn new(enabled: bool, now: Instant, m: usize, p: usize) -> Self { + pub(crate) fn new(enabled: bool, now: Instant, m: usize, p: usize) -> Self { assert!(m >= p, "maximum capacity has to be at least one packet"); assert!(isize::try_from(p).is_ok(), "p ({p}) exceeds isize::MAX"); Self { @@ -64,11 +64,11 @@ impl Pacer { } } - pub const fn mtu(&self) -> usize { + pub(crate) const fn mtu(&self) -> usize { self.p } - pub const fn set_mtu(&mut self, mtu: usize) { + pub(crate) const fn set_mtu(&mut self, mtu: usize) { self.p = mtu; } @@ -76,7 +76,7 @@ impl Pacer { /// RTT, provided congestion window and accumulated credit or debt. This /// doesn't update state. This returns a time, which could be in the past /// (this object doesn't know what the current time is). - pub fn next(&self, rtt: Duration, cwnd: usize) -> Instant { + pub(crate) fn next(&self, rtt: Duration, cwnd: usize) -> Instant { let packet = isize::try_from(self.p).expect("packet size fits into isize"); if self.c >= packet { @@ -138,7 +138,7 @@ impl Pacer { /// This function takes the current time (`now`), an estimate of the round /// trip time (`rtt`), the estimated congestion window (`cwnd`), and the /// number of bytes that were sent (`count`). - pub fn spend(&mut self, now: Instant, rtt: Duration, cwnd: usize, count: usize) { + pub(crate) fn spend(&mut self, now: Instant, rtt: Duration, cwnd: usize, count: usize) { if !self.enabled { self.t = now; return; diff --git a/neqo-transport/src/packet/mod.rs b/neqo-transport/src/packet/mod.rs index 7c4e4d43e1..dc35299a97 100644 --- a/neqo-transport/src/packet/mod.rs +++ b/neqo-transport/src/packet/mod.rs @@ -32,7 +32,7 @@ use crate::{ /// a new connection across all QUIC versions this server supports. pub const MIN_INITIAL_PACKET_SIZE: usize = 1200; -pub const BIT_LONG: u8 = 0x80; +pub(crate) const BIT_LONG: u8 = 0x80; const BIT_SHORT: u8 = 0x00; const BIT_FIXED_QUIC: u8 = 0x40; const BIT_SPIN: u8 = 0x20; @@ -47,12 +47,16 @@ const MAX_PACKET_NUMBER_LEN: usize = 4; /// The length of a long packet length field. const LONG_PACKET_LENGTH_LEN: usize = 2; -pub mod metadata; +pub(crate) mod metadata; mod retry; +#[cfg_attr( + not(any(fuzzing, feature = "bench")), + expect(unreachable_pub, reason = "re-exported via lib.rs") +)] pub use metadata::MetaData; -pub type Number = u64; +pub(crate) type Number = u64; #[derive(Debug, Clone, Copy, PartialEq, Eq, Enum, EnumIter, FromRepr, Hash)] #[repr(u8)] @@ -563,7 +567,7 @@ impl From> for Encoder { /// `Public` holds information from packets that is public only. This allows for /// processing of packets prior to decryption. -pub struct Public<'a> { +pub(crate) struct Public<'a> { /// The packet type. packet_type: Type, /// The recovered destination connection ID. @@ -626,7 +630,7 @@ impl<'a> Public<'a> { /// # Errors /// /// This will return an error if the packet could not be decoded. - pub fn decode( + pub(crate) fn decode( data: &'a mut [u8], dcid_decoder: &dyn ConnectionIdDecoder, ) -> Res<(Self, &'a mut [u8])> { @@ -638,7 +642,7 @@ impl<'a> Public<'a> { /// # Errors /// /// This will return an error if the packet could not be decoded. - pub fn decode_server( + pub(crate) fn decode_server( data: &'a mut [u8], dcid_decoder: &dyn ConnectionIdDecoder, ) -> Res<(Self, &'a mut [u8])> { @@ -769,7 +773,7 @@ impl<'a> Public<'a> { /// Validate the given packet as though it were a retry. #[must_use] - pub fn is_valid_retry(&self, odcid: &ConnectionId) -> bool { + pub(crate) fn is_valid_retry(&self, odcid: &ConnectionId) -> bool { if self.packet_type != Type::Retry { return false; } @@ -792,19 +796,19 @@ impl<'a> Public<'a> { } #[must_use] - pub fn is_valid_initial(&self) -> bool { + pub(crate) fn is_valid_initial(&self) -> bool { // Packet has to be an initial, with a DCID of 8 bytes, or a token. // Note: the Server class validates the token and checks the length. self.packet_type == Type::Initial && (self.dcid().len() >= 8 || !self.token.is_empty()) } #[must_use] - pub const fn packet_type(&self) -> Type { + pub(crate) const fn packet_type(&self) -> Type { self.packet_type } #[must_use] - pub fn dcid(&self) -> ConnectionIdRef<'_> { + pub(crate) fn dcid(&self) -> ConnectionIdRef<'_> { self.dcid.as_cid_ref() } @@ -812,7 +816,7 @@ impl<'a> Public<'a> { /// /// This will panic if called for a short header packet. #[must_use] - pub fn scid(&self) -> ConnectionIdRef<'_> { + pub(crate) fn scid(&self) -> ConnectionIdRef<'_> { self.scid .as_ref() .expect("should only be called for long header packets") @@ -820,17 +824,17 @@ impl<'a> Public<'a> { } #[must_use] - pub fn token(&self) -> &[u8] { + pub(crate) fn token(&self) -> &[u8] { &self.token } #[must_use] - pub fn version(&self) -> Option { + pub(crate) fn version(&self) -> Option { Version::try_from(self.version?).ok() } #[must_use] - pub fn wire_version(&self) -> version::Wire { + pub(crate) fn wire_version(&self) -> version::Wire { debug_assert!(self.version.is_some()); self.version.unwrap_or(0) } @@ -841,13 +845,13 @@ impl<'a> Public<'a> { reason = "Is OK here." )] #[must_use] - pub const fn len(&self) -> usize { + pub(crate) const fn len(&self) -> usize { self.data.len() } #[cfg(feature = "build-fuzzing-corpus")] #[must_use] - pub const fn data(&self) -> &[u8] { + pub(crate) const fn data(&self) -> &[u8] { self.data } @@ -922,7 +926,7 @@ impl<'a> Public<'a> { /// # Errors /// /// This will return an error if the packet cannot be decrypted. - pub fn decrypt( + pub(crate) fn decrypt( mut self, crypto: &mut CryptoStates, release_at: Instant, @@ -989,7 +993,7 @@ impl<'a> Public<'a> { /// /// This will return an error if the packet is not a version negotiation packet /// or if the versions cannot be decoded. - pub fn supported_versions(&self) -> Res> { + pub(crate) fn supported_versions(&self) -> Res> { if self.packet_type != Type::VersionNegotiation { return Err(Error::InvalidPacket); } @@ -1018,7 +1022,7 @@ impl fmt::Debug for Public<'_> { /// Error information from a failed decryption attempt. /// Contains minimal packet information needed for error handling. #[derive(Debug)] -pub struct DecryptionError<'a> { +pub(crate) struct DecryptionError<'a> { /// The error that occurred. pub error: Error, /// The original packet data (unchanged since decryption failed). @@ -1042,7 +1046,7 @@ impl<'a> From<(Public<'a>, Error)> for DecryptionError<'a> { impl DecryptionError<'_> { #[must_use] - pub const fn len(&self) -> usize { + pub(crate) const fn len(&self) -> usize { self.data.len() } @@ -1050,12 +1054,16 @@ impl DecryptionError<'_> { // triggers the `clippy::len_without_is_empty` lint without this. #[cfg(any(fuzzing, feature = "bench"))] #[must_use] - pub const fn is_empty(&self) -> bool { + #[expect( + dead_code, + reason = "Exists to satisfy `clippy::len_without_is_empty` when `packet` is `pub mod`." + )] + pub(crate) const fn is_empty(&self) -> bool { self.data.is_empty() } #[must_use] - pub const fn packet_type(&self) -> Type { + pub(crate) const fn packet_type(&self) -> Type { self.packet_type } } @@ -1117,7 +1125,7 @@ impl Deref for Decrypted<'_> { } #[cfg(test)] -pub const LIMIT: usize = 2048; +pub(crate) const LIMIT: usize = 2048; #[cfg(all(test, not(feature = "disable-encryption")))] #[cfg(test)] diff --git a/neqo-transport/src/packet/retry.rs b/neqo-transport/src/packet/retry.rs index 69abe77013..801326a4f5 100644 --- a/neqo-transport/src/packet/retry.rs +++ b/neqo-transport/src/packet/retry.rs @@ -31,7 +31,7 @@ thread_local!(static RETRY_AEAD_V1: RefCell = RefCell::new(make_aead(Versi thread_local!(static RETRY_AEAD_V2: RefCell = RefCell::new(make_aead(Version::Version2))); /// Run a function with the appropriate Retry AEAD. -pub fn use_aead(version: Version, f: F) -> Res +pub(super) fn use_aead(version: Version, f: F) -> Res where F: FnOnce(&Aead) -> Res, { @@ -49,6 +49,6 @@ where } /// Determine how large the expansion is for a given key. -pub fn expansion(version: Version) -> usize { +pub(super) fn expansion(version: Version) -> usize { use_aead(version, |aead| Ok(aead.expansion())).expect("Unable to access Retry AEAD") } diff --git a/neqo-transport/src/path.rs b/neqo-transport/src/path.rs index 71e3c1d640..23cb8cc06f 100644 --- a/neqo-transport/src/path.rs +++ b/neqo-transport/src/path.rs @@ -35,7 +35,7 @@ use crate::{ /// The maximum number of paths that `Paths` will track. const MAX_PATHS: usize = 15; -pub type PathRef = Rc>; +pub(crate) type PathRef = Rc>; /// A collection for network paths. /// This holds a collection of paths that have been used for sending or @@ -44,7 +44,7 @@ pub type PathRef = Rc>; /// This structure limits its storage and will forget about paths if it /// is exposed to too many paths. #[derive(Debug)] -pub struct Paths { +pub(crate) struct Paths { /// All of the paths. All of these paths will be permanent. #[expect(clippy::struct_field_names, reason = "This is the best name.")] paths: Vec, @@ -68,7 +68,7 @@ pub struct Paths { impl Paths { #[must_use] - pub fn new(pmtud: bool) -> Self { + pub(crate) fn new(pmtud: bool) -> Self { Self { paths: Vec::new(), primary: None, @@ -81,7 +81,7 @@ impl Paths { /// Find the path for the given addresses. /// This might be a temporary path. - pub fn find_path( + pub(crate) fn find_path( &self, local: SocketAddr, remote: SocketAddr, @@ -106,12 +106,12 @@ impl Paths { } /// Get a reference to the primary path, if one exists. - pub fn primary(&self) -> Option { + pub(crate) fn primary(&self) -> Option { self.primary.clone() } /// Returns true if the path is not permanent. - pub fn is_temporary(&self, path: &PathRef) -> bool { + pub(crate) fn is_temporary(&self, path: &PathRef) -> bool { // Ask the path first, which is simpler. path.borrow().is_temporary() || !self.paths.iter().any(|p| Rc::ptr_eq(p, path)) } @@ -129,7 +129,7 @@ impl Paths { /// Adopt a temporary path as permanent. /// The first path that is made permanent is made primary. - pub fn make_permanent( + pub(crate) fn make_permanent( &mut self, path: &PathRef, local_cid: Option, @@ -193,7 +193,7 @@ impl Paths { /// Otherwise, migration will occur after probing succeeds. /// The path is always probed and will be abandoned if probing fails. /// Returns `true` if the path was migrated. - pub fn migrate( + pub(crate) fn migrate( &mut self, path: &PathRef, force: bool, @@ -223,7 +223,12 @@ impl Paths { /// /// TODO(mt) - the paths should own the RTT estimator, so they can find the PTO /// for themselves. - pub fn process_timeout(&mut self, now: Instant, pto: Duration, stats: &mut Stats) -> bool { + pub(crate) fn process_timeout( + &mut self, + now: Instant, + pto: Duration, + stats: &mut Stats, + ) -> bool { let to_retire = &mut self.to_retire; let mut primary_failed = false; self.paths.retain(|p| { @@ -272,7 +277,7 @@ impl Paths { } /// Get when the next call to `process_timeout()` should be scheduled. - pub fn next_timeout(&self, pto: Duration) -> Option { + pub(crate) fn next_timeout(&self, pto: Duration) -> Option { self.paths .iter() .filter_map(|p| p.borrow().next_timeout(pto)) @@ -282,7 +287,7 @@ impl Paths { /// Set the identified path to be primary. /// This panics if `make_permanent` hasn't been called. /// If PMTUD is enabled, it will be started on the new primary path. - pub fn handle_migration( + pub(crate) fn handle_migration( &mut self, path: &PathRef, remote: SocketAddr, @@ -314,7 +319,7 @@ impl Paths { /// Select a path to send on. This will select the first path that has /// probes to send, then fall back to the primary path. - pub fn select_path(&self) -> Option { + pub(crate) fn select_path(&self) -> Option { self.paths .iter() .find_map(|p| p.borrow().has_probe().then(|| Rc::clone(p))) @@ -325,7 +330,12 @@ impl Paths { /// Returns `true` if migration occurred. /// If PMTUD is enabled and migration occurs, it will be started on the new primary path. #[must_use] - pub fn path_response(&mut self, response: [u8; 8], now: Instant, stats: &mut Stats) -> bool { + pub(crate) fn path_response( + &mut self, + response: [u8; 8], + now: Instant, + stats: &mut Stats, + ) -> bool { // TODO(mt) consider recording an RTT measurement here as we don't train // RTT for non-primary paths. for p in &self.paths { @@ -352,7 +362,7 @@ impl Paths { /// Keep active paths if possible by pulling new connection IDs from the provided store. /// One slightly non-obvious consequence of this is that if migration is being attempted /// and the new path cannot obtain a new connection ID, the migration attempt will fail. - pub fn retire_cids(&mut self, retire_prior: u64, store: &mut ConnectionIdStore) { + pub(crate) fn retire_cids(&mut self, retire_prior: u64, store: &mut ConnectionIdStore) { let to_retire = &mut self.to_retire; let migration_target = &mut self.migration_target; @@ -391,7 +401,7 @@ impl Paths { } /// Write out any `RETIRE_CONNECTION_ID` frames that are outstanding. - pub fn write_frames( + pub(crate) fn write_frames( &mut self, builder: &mut packet::Builder, tokens: &mut recovery::Tokens, @@ -415,39 +425,39 @@ impl Paths { } } - pub fn lost_retire_cid(&mut self, lost: u64) { + pub(crate) fn lost_retire_cid(&mut self, lost: u64) { self.to_retire.push(lost); } - pub fn acked_retire_cid(&mut self, acked: u64) { + pub(crate) fn acked_retire_cid(&mut self, acked: u64) { self.to_retire.retain(|&seqno| seqno != acked); } - pub fn lost_ack_frequency(&self, lost: &AckRate) { + pub(crate) fn lost_ack_frequency(&self, lost: &AckRate) { if let Some(path) = self.primary() { path.borrow_mut().lost_ack_frequency(lost); } } - pub fn acked_ack_frequency(&self, acked: &AckRate) { + pub(crate) fn acked_ack_frequency(&self, acked: &AckRate) { if let Some(path) = self.primary() { path.borrow_mut().acked_ack_frequency(acked); } } - pub fn acked_ecn(&self) { + pub(crate) fn acked_ecn(&self) { if let Some(path) = self.primary() { path.borrow_mut().acked_ecn(); } } - pub fn lost_ecn(&self, stats: &mut Stats) { + pub(crate) fn lost_ecn(&self, stats: &mut Stats) { if let Some(path) = self.primary() { path.borrow_mut().lost_ecn(stats); } } - pub fn start_ecn(&self, stats: &mut Stats) { + pub(crate) fn start_ecn(&self, stats: &mut Stats) { if let Some(path) = self.primary() { path.borrow_mut().start_ecn(stats); } @@ -455,7 +465,7 @@ impl Paths { /// Get an estimate of the RTT on the primary path. #[cfg(test)] - pub fn rtt(&self) -> Duration { + pub(crate) fn rtt(&self) -> Duration { // Rather than have this fail when there is no active path, // make a new RTT estimate and interrogate that. // That is more expensive, but it should be rare and breaking encapsulation @@ -466,7 +476,7 @@ impl Paths { ) } - pub fn set_qlog(&mut self, qlog: Qlog) { + pub(crate) fn set_qlog(&mut self, qlog: Qlog) { for p in &mut self.paths { p.borrow_mut().set_qlog(qlog.clone()); } diff --git a/neqo-transport/src/qlog.rs b/neqo-transport/src/qlog.rs index 40548d4cd9..7f4151b06e 100644 --- a/neqo-transport/src/qlog.rs +++ b/neqo-transport/src/qlog.rs @@ -51,7 +51,11 @@ use crate::{ version::{self, Version}, }; -pub fn connection_tparams_set(qlog: &mut Qlog, tph: &TransportParametersHandler, now: Instant) { +pub(crate) fn connection_tparams_set( + qlog: &mut Qlog, + tph: &TransportParametersHandler, + now: Instant, +) { qlog.add_event_at( || { let remote = tph.remote(); @@ -100,11 +104,11 @@ pub fn connection_tparams_set(qlog: &mut Qlog, tph: &TransportParametersHandler, ); } -pub fn server_connection_started(qlog: &mut Qlog, path: &PathRef, now: Instant) { +pub(crate) fn server_connection_started(qlog: &mut Qlog, path: &PathRef, now: Instant) { connection_started(qlog, path, now); } -pub fn client_connection_started(qlog: &mut Qlog, path: &PathRef, now: Instant) { +pub(crate) fn client_connection_started(qlog: &mut Qlog, path: &PathRef, now: Instant) { connection_started(qlog, path, now); } @@ -133,7 +137,7 @@ fn connection_started(qlog: &mut Qlog, path: &PathRef, now: Instant) { ); } -pub fn connection_state_updated( +pub(crate) fn connection_state_updated( qlog: &mut Qlog, old_state: &State, new_state: &State, @@ -150,7 +154,7 @@ pub fn connection_state_updated( ); } -pub fn client_version_information_initiated( +pub(crate) fn client_version_information_initiated( qlog: &mut Qlog, version_config: &version::Config, now: Instant, @@ -173,7 +177,7 @@ pub fn client_version_information_initiated( ); } -pub fn client_version_information_negotiated( +pub(crate) fn client_version_information_negotiated( qlog: &mut Qlog, client: &[Version], server: &[version::Wire], @@ -197,7 +201,7 @@ pub fn client_version_information_negotiated( ); } -pub fn server_version_information_failed( +pub(crate) fn server_version_information_failed( qlog: &mut Qlog, server: &[Version], client: version::Wire, @@ -220,7 +224,7 @@ pub fn server_version_information_failed( ); } -pub fn packet_io(qlog: &mut Qlog, meta: packet::MetaData, now: Instant) { +pub(crate) fn packet_io(qlog: &mut Qlog, meta: packet::MetaData, now: Instant) { qlog.add_event_at( || { let mut d = Decoder::from(meta.payload()); @@ -258,7 +262,7 @@ pub fn packet_io(qlog: &mut Qlog, meta: packet::MetaData, now: Instant) { now, ); } -pub fn packet_dropped(qlog: &mut Qlog, decrypt_err: &packet::DecryptionError, now: Instant) { +pub(crate) fn packet_dropped(qlog: &mut Qlog, decrypt_err: &packet::DecryptionError, now: Instant) { qlog.add_event_at( || { let header = @@ -282,7 +286,7 @@ pub fn packet_dropped(qlog: &mut Qlog, decrypt_err: &packet::DecryptionError, no ); } -pub fn packets_lost(qlog: &mut Qlog, pkts: &[sent::Packet], now: Instant) { +pub(crate) fn packets_lost(qlog: &mut Qlog, pkts: &[sent::Packet], now: Instant) { qlog.add_event_with_stream(|stream| { for pkt in pkts { let header = @@ -305,7 +309,7 @@ pub fn packets_lost(qlog: &mut Qlog, pkts: &[sent::Packet], now: Instant) { }); } -pub fn recovery_parameters_set( +pub(crate) fn recovery_parameters_set( qlog: &mut Qlog, plpmtu: usize, cc: CongestionControl, @@ -344,14 +348,14 @@ pub fn recovery_parameters_set( ); } -pub fn connection_closed(qlog: &mut Qlog, close_reason: &CloseReason, now: Instant) { +pub(crate) fn connection_closed(qlog: &mut Qlog, close_reason: &CloseReason, now: Instant) { qlog.add_event_at( || Some(EventData::ConnectionClosed(close_reason.into())), now, ); } -pub fn packets_acked( +pub(crate) fn packets_acked( qlog: &mut Qlog, space: PacketNumberSpace, acked_pkts: &[sent::Packet], @@ -373,7 +377,13 @@ pub fn packets_acked( ); } -pub fn mtu_updated(qlog: &mut Qlog, old_mtu: usize, new_mtu: usize, done: bool, now: Instant) { +pub(crate) fn mtu_updated( + qlog: &mut Qlog, + old_mtu: usize, + new_mtu: usize, + done: bool, + now: Instant, +) { qlog.add_event_at( || { Some(EventData::MtuUpdated(MtuUpdated { @@ -388,7 +398,7 @@ pub fn mtu_updated(qlog: &mut Qlog, old_mtu: usize, new_mtu: usize, done: bool, #[derive(Clone, Copy)] #[expect(dead_code, reason = "TODO: Construct all variants.")] -pub enum Metric { +pub(crate) enum Metric { MinRtt(Duration), SmoothedRtt(Duration), LatestRtt(Duration), @@ -401,7 +411,7 @@ pub enum Metric { PacingRate(u64), } -pub fn metrics_updated>( +pub(crate) fn metrics_updated>( qlog: &mut Qlog, updated_metrics: M, now: Instant, @@ -494,7 +504,7 @@ impl From for CongestionStateUpdatedTrigger { } } -pub fn congestion_state_updated( +pub(crate) fn congestion_state_updated( qlog: &mut Qlog, old_state: &'static str, new_state: &'static str, @@ -528,11 +538,11 @@ pub enum LossTimerType { /// loss-detection (Ack) timer is derived lazily from packet state on every /// call to [`crate::recovery::Loss::next_timeout`] and has no single arm or /// cancel point to instrument. -pub fn loss_timer_set(qlog: &mut Qlog, now: Instant) { +pub(crate) fn loss_timer_set(qlog: &mut Qlog, now: Instant) { loss_timer_updated(qlog, LossTimerEventType::Set, Some(TimerType::Pto), now); } -pub fn loss_timer_expired(qlog: &mut Qlog, timer_type: LossTimerType, now: Instant) { +pub(crate) fn loss_timer_expired(qlog: &mut Qlog, timer_type: LossTimerType, now: Instant) { loss_timer_updated( qlog, LossTimerEventType::Expired, @@ -544,7 +554,7 @@ pub fn loss_timer_expired(qlog: &mut Qlog, timer_type: LossTimerType, now: Insta /// Emit a `loss_timer_updated` Cancelled event. /// /// See [`loss_timer_set`] for why only `TimerType::Pto` is used here. -pub fn loss_timer_cancelled(qlog: &mut Qlog, now: Instant) { +pub(crate) fn loss_timer_cancelled(qlog: &mut Qlog, now: Instant) { loss_timer_updated( qlog, LossTimerEventType::Cancelled, diff --git a/neqo-transport/src/quic_datagrams.rs b/neqo-transport/src/quic_datagrams.rs index abe8e24133..621c6b52a7 100644 --- a/neqo-transport/src/quic_datagrams.rs +++ b/neqo-transport/src/quic_datagrams.rs @@ -19,7 +19,7 @@ use crate::{ /// Length of a [`FrameType::Datagram`] or [`FrameType::DatagramWithLen`] in /// QUIC varint encoding. -pub const DATAGRAM_FRAME_TYPE_VARINT_LEN: usize = 1; +pub(crate) const DATAGRAM_FRAME_TYPE_VARINT_LEN: usize = 1; static_assertions::const_assert_eq!( Encoder::varint_len(FrameType::Datagram as u64), DATAGRAM_FRAME_TYPE_VARINT_LEN @@ -41,13 +41,13 @@ impl From> for DatagramTracking { } } -pub struct QuicDatagram { +pub(crate) struct QuicDatagram { data: Vec, tracking: DatagramTracking, } impl QuicDatagram { - pub const MAX_SIZE: u64 = 65535; + pub(crate) const MAX_SIZE: u64 = 65535; const fn tracking(&self) -> &DatagramTracking { &self.tracking @@ -60,7 +60,7 @@ impl AsRef<[u8]> for QuicDatagram { } } -pub struct QuicDatagrams { +pub(crate) struct QuicDatagrams { /// The max size of a datagram that would be acceptable. local_datagram_size: u64, /// The max size of a datagram that would be acceptable by the peer. @@ -75,7 +75,7 @@ pub struct QuicDatagrams { } impl QuicDatagrams { - pub fn new( + pub(crate) fn new( local_datagram_size: u64, max_queued_outgoing_datagrams: usize, max_queued_incoming_datagrams: usize, @@ -91,18 +91,18 @@ impl QuicDatagrams { } } - pub const fn remote_datagram_size(&self) -> u64 { + pub(crate) const fn remote_datagram_size(&self) -> u64 { self.remote_datagram_size } - pub fn set_remote_datagram_size(&mut self, v: u64) { + pub(crate) fn set_remote_datagram_size(&mut self, v: u64) { self.remote_datagram_size = min(v, QuicDatagram::MAX_SIZE); } /// This function tries to write a datagram frame into a packet. If the /// frame does not fit into the packet, the datagram will be dropped and a /// [`OutgoingDatagramOutcome::DroppedTooBig`] event will be posted. - pub fn write_frames( + pub(crate) fn write_frames( &mut self, builder: &mut packet::Builder, tokens: &mut recovery::Tokens, @@ -158,7 +158,7 @@ impl QuicDatagrams { /// datagram can fit into a packet (i.e. MTU limit). This is checked during /// creation of an actual packet and the datagram will be dropped if it does /// not fit into the packet. - pub fn add_datagram( + pub(crate) fn add_datagram( &mut self, data: Vec, tracking: DatagramTracking, @@ -187,7 +187,7 @@ impl QuicDatagrams { Ok(()) } - pub fn handle_datagram(&self, data: &[u8], stats: &mut Stats) -> Res<()> { + pub(crate) fn handle_datagram(&self, data: &[u8], stats: &mut Stats) -> Res<()> { if self.local_datagram_size < u64::try_from(data.len())? { return Err(Error::ProtocolViolation); } diff --git a/neqo-transport/src/recovery/mod.rs b/neqo-transport/src/recovery/mod.rs index 669fa7597d..9fa0f4f4ad 100644 --- a/neqo-transport/src/recovery/mod.rs +++ b/neqo-transport/src/recovery/mod.rs @@ -6,7 +6,7 @@ // Tracking of sent packets and detecting their loss. -pub mod sent; +pub(crate) mod sent; mod token; use std::{ @@ -20,6 +20,10 @@ use enum_map::EnumMap; use enumset::enum_set; use neqo_common::{qdebug, qinfo, qlog::Qlog, qtrace, qwarn}; use strum::IntoEnumIterator as _; +#[cfg_attr( + not(feature = "bench"), + expect(unreachable_pub, reason = "re-exported via lib.rs") +)] pub use token::{StreamRecoveryToken, Token, Tokens}; use crate::{ @@ -31,24 +35,28 @@ use crate::{ tracking::{PacketNumberSpace, PacketNumberSpaceSet}, }; -pub const PACKET_THRESHOLD: u64 = 3; +pub(crate) const PACKET_THRESHOLD: u64 = 3; /// `ACK_ONLY_SIZE_LIMIT` is the minimum size of the congestion window. /// If the congestion window is this small, we will only send ACK frames. -pub const ACK_ONLY_SIZE_LIMIT: usize = 256; +pub(crate) const ACK_ONLY_SIZE_LIMIT: usize = 256; /// The maximum number of packets we send on a PTO. -pub const MAX_PTO_PACKET_COUNT: usize = 2; +pub(crate) const MAX_PTO_PACKET_COUNT: usize = 2; /// The preferred limit on the number of packets that are tracked. /// If we exceed this number, we start sending `PING` frames sooner to /// force the peer to acknowledge some of them. -pub const MAX_OUTSTANDING_UNACK: usize = 200; +pub(crate) const MAX_OUTSTANDING_UNACK: usize = 200; /// Disable PING until this many packets are outstanding. -pub const MIN_OUTSTANDING_UNACK: usize = 16; +pub(crate) const MIN_OUTSTANDING_UNACK: usize = 16; /// The scale we use for the fast PTO feature. +#[cfg_attr( + not(feature = "bench"), + expect(unreachable_pub, reason = "re-exported via lib.rs") +)] pub const FAST_PTO_SCALE: u8 = 100; /// `SendProfile` tells a sender how to send packets. #[derive(Debug)] -pub struct SendProfile { +pub(crate) struct SendProfile { /// The limit on the size of the packet. limit: usize, /// What spaces should be probed. @@ -59,7 +67,7 @@ pub struct SendProfile { impl SendProfile { #[must_use] - pub fn new_limited(limit: usize) -> Self { + pub(crate) fn new_limited(limit: usize) -> Self { // When the limit is too low, we only send ACK frames. // Set the limit to `ACK_ONLY_SIZE_LIMIT - 1` to ensure that // ACK-only packets are still limited in size. @@ -71,7 +79,7 @@ impl SendProfile { } #[must_use] - pub fn new_paced() -> Self { + pub(crate) fn new_paced() -> Self { // When pacing, we still allow ACK frames to be sent. Self { limit: ACK_ONLY_SIZE_LIMIT - 1, @@ -81,7 +89,7 @@ impl SendProfile { } #[must_use] - pub fn new_pto(mtu: usize, probe: PacketNumberSpaceSet) -> Self { + pub(crate) fn new_pto(mtu: usize, probe: PacketNumberSpaceSet) -> Self { debug_assert!(mtu > ACK_ONLY_SIZE_LIMIT); Self { limit: mtu, @@ -94,30 +102,30 @@ impl SendProfile { /// that caused the timer to pop, but it is helpful to send a PING in a space /// that has the PTO timer armed. #[must_use] - pub fn should_probe(&self, space: PacketNumberSpace) -> bool { + pub(crate) fn should_probe(&self, space: PacketNumberSpace) -> bool { self.probe.contains(space) } /// Determine whether an ACK-only packet should be sent. Returns true if the congestion window /// is too small to send data frames. #[must_use] - pub const fn ack_only(&self) -> bool { + pub(crate) const fn ack_only(&self) -> bool { self.limit < ACK_ONLY_SIZE_LIMIT } #[must_use] - pub const fn paced(&self) -> bool { + pub(crate) const fn paced(&self) -> bool { self.paced } #[must_use] - pub const fn limit(&self) -> usize { + pub(crate) const fn limit(&self) -> usize { self.limit } } #[derive(Debug)] -pub struct LossRecoverySpace { +pub(crate) struct LossRecoverySpace { space: PacketNumberSpace, largest_acked: Option, largest_acked_sent_time: Option, @@ -142,7 +150,7 @@ pub struct LossRecoverySpace { impl LossRecoverySpace { #[must_use] - pub fn new(space: PacketNumberSpace) -> Self { + pub(crate) fn new(space: PacketNumberSpace) -> Self { Self { space, largest_acked: None, @@ -158,16 +166,16 @@ impl LossRecoverySpace { /// largest acknowledged and that isn't yet declared lost. /// Use the value we prepared earlier in `detect_lost_packets`. #[must_use] - pub const fn loss_recovery_timer_start(&self) -> Option { + pub(crate) const fn loss_recovery_timer_start(&self) -> Option { self.first_ooo_time } #[must_use] - pub const fn in_flight_outstanding(&self) -> bool { + pub(crate) const fn in_flight_outstanding(&self) -> bool { self.in_flight_outstanding > 0 } - pub fn pto_packets(&mut self) -> impl Iterator { + pub(crate) fn pto_packets(&mut self) -> impl Iterator { self.sent_packets.iter_mut().filter_map(|sent| { sent.pto().then(|| { qtrace!("PTO: marking packet {} lost ", sent.pn()); @@ -177,7 +185,7 @@ impl LossRecoverySpace { } #[must_use] - pub fn pto_base_time(&self) -> Option { + pub(crate) fn pto_base_time(&self) -> Option { if self.in_flight_outstanding() { debug_assert!(self.last_ack_eliciting.is_some()); self.last_ack_eliciting @@ -207,7 +215,7 @@ impl LossRecoverySpace { } } - pub fn on_packet_sent(&mut self, sent_packet: sent::Packet) { + pub(crate) fn on_packet_sent(&mut self, sent_packet: sent::Packet) { if sent_packet.ack_eliciting() { self.last_ack_eliciting = Some(sent_packet.time_sent()); self.in_flight_outstanding += 1; @@ -227,7 +235,7 @@ impl LossRecoverySpace { /// we would risk setting up a feedback loop; having this many packets /// outstanding can be normal and we don't want to PING too often. #[must_use] - pub fn should_probe(&self, pto: Duration, now: Instant) -> bool { + pub(crate) fn should_probe(&self, pto: Duration, now: Instant) -> bool { let n_pto = if self.sent_packets.len() >= MAX_OUTSTANDING_UNACK { 1 } else if self.sent_packets.len() >= MIN_OUTSTANDING_UNACK { @@ -305,7 +313,7 @@ impl LossRecoverySpace { /// Detect lost packets. /// `loss_delay` is the time we will wait before declaring something lost. /// `cleanup_delay` is the time we will wait before cleaning up a lost packet. - pub fn detect_lost_packets( + pub(crate) fn detect_lost_packets( &mut self, now: Instant, loss_delay: Duration, @@ -359,7 +367,7 @@ impl LossRecoverySpace { } #[derive(Debug)] -pub struct LossRecoverySpaces { +pub(crate) struct LossRecoverySpaces { spaces: EnumMap>, } @@ -370,7 +378,7 @@ impl LossRecoverySpaces { /// # Panics /// /// If the space has already been removed. - pub fn drop_space( + pub(crate) fn drop_space( &mut self, space: PacketNumberSpace, ) -> impl IntoIterator + use<> { @@ -384,11 +392,11 @@ impl LossRecoverySpaces { } #[must_use] - pub fn get(&self, space: PacketNumberSpace) -> Option<&LossRecoverySpace> { + pub(crate) fn get(&self, space: PacketNumberSpace) -> Option<&LossRecoverySpace> { self.spaces[space].as_ref() } - pub fn get_mut(&mut self, space: PacketNumberSpace) -> Option<&mut LossRecoverySpace> { + pub(crate) fn get_mut(&mut self, space: PacketNumberSpace) -> Option<&mut LossRecoverySpace> { self.spaces[space].as_mut() } @@ -427,7 +435,7 @@ struct PtoState { } impl PtoState { - pub fn new(space: PacketNumberSpace, probe: PacketNumberSpaceSet) -> Self { + pub(crate) fn new(space: PacketNumberSpace, probe: PacketNumberSpaceSet) -> Self { debug_assert!(probe.contains(space)); Self { space, @@ -437,7 +445,7 @@ impl PtoState { } } - pub fn pto(&mut self, space: PacketNumberSpace, probe: PacketNumberSpaceSet) { + pub(crate) fn pto(&mut self, space: PacketNumberSpace, probe: PacketNumberSpaceSet) { debug_assert!(probe.contains(space)); self.space = min(space, self.space); self.count += 1; @@ -445,17 +453,17 @@ impl PtoState { self.probe |= probe; } - pub const fn count(&self) -> usize { + pub(crate) const fn count(&self) -> usize { self.count } - pub fn count_pto(&self, stats: &mut Stats) { + pub(crate) fn count_pto(&self, stats: &mut Stats) { stats.add_pto_count(self.count); } /// Generate a sending profile, indicating what space it should be from. /// This takes a packet from the supply if one remains, or returns `None`. - pub fn send_profile(&mut self, mtu: usize) -> Option { + pub(crate) fn send_profile(&mut self, mtu: usize) -> Option { (self.packets > 0).then(|| { self.packets -= 1; // This is a PTO, so ignore the limit. @@ -463,7 +471,7 @@ impl PtoState { }) } - pub fn pto_sent(&mut self, space: PacketNumberSpace) { + pub(crate) fn pto_sent(&mut self, space: PacketNumberSpace) { // For Initial and Handshake packets, don't force probes after the first packet. // Probing forces the inclusion of frames, even when there is nothing to send. // We do want to send subsequent packets if there is something there, @@ -475,7 +483,7 @@ impl PtoState { } #[derive(Debug)] -pub struct Loss { +pub(crate) struct Loss { /// When the handshake was confirmed, if it has been. confirmed_time: Option, pto_state: Option, @@ -489,7 +497,7 @@ pub struct Loss { impl Loss { #[must_use] - pub fn new(stats: StatsCell, fast_pto: u8) -> Self { + pub(crate) fn new(stats: StatsCell, fast_pto: u8) -> Self { Self { confirmed_time: None, pto_state: None, @@ -501,16 +509,19 @@ impl Loss { } #[must_use] - pub fn largest_acknowledged_pn(&self, pn_space: PacketNumberSpace) -> Option { + pub(crate) fn largest_acknowledged_pn( + &self, + pn_space: PacketNumberSpace, + ) -> Option { self.spaces.get(pn_space)?.largest_acked } - pub fn set_qlog(&mut self, qlog: Qlog) { + pub(crate) fn set_qlog(&mut self, qlog: Qlog) { self.qlog = qlog; } /// Drop all 0rtt packets. - pub fn drop_0rtt(&mut self, primary_path: &PathRef, now: Instant) -> Vec { + pub(crate) fn drop_0rtt(&mut self, primary_path: &PathRef, now: Instant) -> Vec { let Some(sp) = self.spaces.get_mut(PacketNumberSpace::ApplicationData) else { return Vec::new(); }; @@ -526,7 +537,12 @@ impl Loss { dropped } - pub fn on_packet_sent(&mut self, path: &PathRef, mut sent_packet: sent::Packet, now: Instant) { + pub(crate) fn on_packet_sent( + &mut self, + path: &PathRef, + mut sent_packet: sent::Packet, + now: Instant, + ) { let pn_space = PacketNumberSpace::from(sent_packet.packet_type()); qtrace!("[{self}] packet {pn_space}-{} sent", sent_packet.pn()); if let Some(pto) = self.pto_state.as_mut() { @@ -545,7 +561,7 @@ impl Loss { /// Whether to probe the path. #[must_use] - pub fn should_probe(&self, pto: Duration, now: Instant) -> bool { + pub(crate) fn should_probe(&self, pto: Duration, now: Instant) -> bool { self.spaces .get(PacketNumberSpace::ApplicationData) .is_some_and(|sp| sp.should_probe(pto, now)) @@ -613,7 +629,7 @@ impl Loss { } /// Returns (acked packets, lost packets) - pub fn on_ack_received( + pub(crate) fn on_ack_received( &mut self, primary_path: &PathRef, pn_space: PacketNumberSpace, @@ -706,7 +722,7 @@ impl Loss { /// When receiving a retry, get all the sent packets so that they can be flushed. /// We also need to pretend that they never happened for the purposes of congestion control. - pub fn retry(&mut self, primary_path: &PathRef, now: Instant) -> Vec { + pub(crate) fn retry(&mut self, primary_path: &PathRef, now: Instant) -> Vec { if self.pto_state.is_some() { qlog::loss_timer_cancelled(&mut self.qlog, now); } @@ -740,14 +756,19 @@ impl Loss { /// It marks all packets that are outstanding as having being sent on a non-primary path. /// This way failure to deliver on the old path doesn't count against the congestion /// control state on the new path and the RTT measurements don't apply either. - pub fn migrate(&mut self) { + pub(crate) fn migrate(&mut self) { for space in self.spaces.iter_mut() { space.migrate(); } } /// Discard state for a given packet number space. - pub fn discard(&mut self, primary_path: &PathRef, space: PacketNumberSpace, now: Instant) { + pub(crate) fn discard( + &mut self, + primary_path: &PathRef, + space: PacketNumberSpace, + now: Instant, + ) { qdebug!("[{self}] Reset loss recovery state for {space:?}"); let mut path = primary_path.borrow_mut(); for p in self.spaces.drop_space(space) { @@ -770,7 +791,7 @@ impl Loss { /// Calculate when the next timeout is likely to be. This is the earlier of the loss timer /// and the PTO timer; either or both might be disabled, so this can return `None`. #[must_use] - pub fn next_timeout(&self, path: &Path) -> Option { + pub(crate) fn next_timeout(&self, path: &Path) -> Option { let rtt = path.rtt(); let loss_time = self.earliest_loss_time(rtt); let pto_time = if path.pto_possible() { @@ -932,7 +953,7 @@ impl Loss { } } - pub fn timeout( + pub(crate) fn timeout( &mut self, primary_path: &PathRef, now: Instant, @@ -983,7 +1004,7 @@ impl Loss { /// Check how packets should be sent, based on whether there is a PTO, /// what the current congestion window is, and what the pacer says. #[expect(clippy::option_if_let_else, reason = "Alternative is less readable.")] - pub fn send_profile(&mut self, path: &Path, now: Instant) -> SendProfile { + pub(crate) fn send_profile(&mut self, path: &Path, now: Instant) -> SendProfile { qtrace!("[{self}] get send profile {now:?}"); let sender = path.sender(); let mtu = path.plpmtu(); @@ -1068,7 +1089,7 @@ mod tests { // This shadows functions on the base object so that the path and RTT estimator // is used consistently in the tests. It also simplifies the function signatures. impl Fixture { - pub fn on_ack_received( + pub(crate) fn on_ack_received( &mut self, pn_space: PacketNumberSpace, acked_ranges: Vec>, @@ -1080,27 +1101,27 @@ mod tests { .on_ack_received(&self.path, pn_space, acked_ranges, ack_ecn, ack_delay, now) } - pub fn on_packet_sent(&mut self, sent_packet: sent::Packet, now: Instant) { + pub(crate) fn on_packet_sent(&mut self, sent_packet: sent::Packet, now: Instant) { self.lr.on_packet_sent(&self.path, sent_packet, now); } - pub fn timeout(&mut self, now: Instant) -> Vec { + pub(crate) fn timeout(&mut self, now: Instant) -> Vec { self.lr.timeout(&self.path, now, true) } - pub fn next_timeout(&self) -> Option { + pub(crate) fn next_timeout(&self) -> Option { self.lr.next_timeout(&self.path.borrow()) } - pub fn discard(&mut self, space: PacketNumberSpace, now: Instant) { + pub(crate) fn discard(&mut self, space: PacketNumberSpace, now: Instant) { self.lr.discard(&self.path, space, now); } - pub fn pto_time(&self, space: PacketNumberSpace) -> Option { + pub(crate) fn pto_time(&self, space: PacketNumberSpace) -> Option { self.lr.pto_time(self.path.borrow().rtt(), space) } - pub fn send_profile(&mut self, now: Instant) -> SendProfile { + pub(crate) fn send_profile(&mut self, now: Instant) -> SendProfile { self.lr.send_profile(&self.path.borrow(), now) } } diff --git a/neqo-transport/src/recovery/sent.rs b/neqo-transport/src/recovery/sent.rs index 77edfb0909..4a4f75f947 100644 --- a/neqo-transport/src/recovery/sent.rs +++ b/neqo-transport/src/recovery/sent.rs @@ -212,7 +212,7 @@ impl Packet { /// A collection for packets that we have sent that haven't been acknowledged. #[derive(Debug, Default)] -pub struct Packets { +pub(crate) struct Packets { /// The collection. packets: BTreeMap, } @@ -224,15 +224,15 @@ impl Packets { reason = "OK here." )] #[must_use] - pub fn len(&self) -> usize { + pub(crate) fn len(&self) -> usize { self.packets.len() } - pub fn track(&mut self, packet: Packet) { + pub(crate) fn track(&mut self, packet: Packet) { self.packets.insert(packet.pn, packet); } - pub fn iter_mut(&mut self) -> impl Iterator { + pub(crate) fn iter_mut(&mut self) -> impl Iterator { self.packets.values_mut() } @@ -240,7 +240,7 @@ impl Packets { /// The values returned will be reversed, so that the most recent packet appears first. /// This is because ACK frames arrive with ranges starting from the largest acknowledged /// and we want to match that. - pub fn take_ranges(&mut self, acked_ranges: R) -> Vec + pub(crate) fn take_ranges(&mut self, acked_ranges: R) -> Vec where R: IntoIterator>, R::IntoIter: ExactSizeIterator, @@ -302,13 +302,13 @@ impl Packets { } /// Empty out the packets, but keep the offset. - pub fn drain_all(&mut self) -> impl Iterator + use<> { + pub(crate) fn drain_all(&mut self) -> impl Iterator + use<> { std::mem::take(&mut self.packets).into_values() } /// See `LossRecoverySpace::remove_old_lost` for details on `now` and `cd`. /// Returns the number of ack-eliciting packets removed. - pub fn remove_expired(&mut self, now: Instant, cd: Duration) -> usize { + pub(crate) fn remove_expired(&mut self, now: Instant, cd: Duration) -> usize { let mut it = self.packets.iter(); // If the first item is not expired, do nothing (the most common case). if it.next().is_some_and(|(_, p)| p.expired(now, cd)) { @@ -336,7 +336,7 @@ impl Packets { /// Test helper to create a sent packet. #[cfg(test)] #[must_use] -pub fn make_packet(pn: packet::Number, sent_time: Instant, len: usize) -> Packet { +pub(crate) fn make_packet(pn: packet::Number, sent_time: Instant, len: usize) -> Packet { Packet::new( packet::Type::Short, pn, diff --git a/neqo-transport/src/recovery/token.rs b/neqo-transport/src/recovery/token.rs index 38a281831a..634d33fab9 100644 --- a/neqo-transport/src/recovery/token.rs +++ b/neqo-transport/src/recovery/token.rs @@ -15,6 +15,10 @@ use crate::{ tracking::AckToken, }; +#[cfg_attr( + not(feature = "bench"), + expect(unreachable_pub, reason = "re-exported via recovery::Tokens") +)] pub type Tokens = Vec; #[derive(Debug, Clone)] diff --git a/neqo-transport/src/rtt.rs b/neqo-transport/src/rtt.rs index 0d5e1c558c..ad39827289 100644 --- a/neqo-transport/src/rtt.rs +++ b/neqo-transport/src/rtt.rs @@ -21,7 +21,7 @@ use crate::{ /// The smallest time that the system timer (via `sleep()`, `nanosleep()`, /// `select()`, or similar) can reliably deliver; see `neqo_common::hrtime`. -pub const GRANULARITY: Duration = Duration::from_millis(1); +pub(crate) const GRANULARITY: Duration = Duration::from_millis(1); // Defined in -recovery 6.2 as 333ms but using lower value. pub const DEFAULT_INITIAL_RTT: Duration = Duration::from_millis(100); diff --git a/neqo-transport/src/saved.rs b/neqo-transport/src/saved.rs index 60d8d0f26b..e103bb4ce5 100644 --- a/neqo-transport/src/saved.rs +++ b/neqo-transport/src/saved.rs @@ -10,7 +10,7 @@ use neqo_common::{Datagram, qdebug, qinfo}; use crate::crypto::Epoch; -pub struct SavedDatagram { +pub(crate) struct SavedDatagram { /// The datagram. pub d: Datagram, /// The time that the datagram was received. @@ -18,7 +18,7 @@ pub struct SavedDatagram { } #[derive(Default)] -pub struct SavedDatagrams { +pub(crate) struct SavedDatagrams { handshake: Vec, application_data: Vec, available: Option, @@ -27,7 +27,7 @@ pub struct SavedDatagrams { impl SavedDatagrams { /// The number of datagrams that are saved during the handshake when /// keys to decrypt them are not yet available. - pub const CAPACITY: usize = 4; + pub(crate) const CAPACITY: usize = 4; fn store(&mut self, epoch: Epoch) -> &mut Vec { match epoch { @@ -38,11 +38,11 @@ impl SavedDatagrams { } /// Return whether either store of datagrams is currently full. - pub const fn is_either_full(&self) -> bool { + pub(crate) const fn is_either_full(&self) -> bool { self.handshake.len() == Self::CAPACITY || self.application_data.len() == Self::CAPACITY } - pub fn save(&mut self, epoch: Epoch, d: Datagram, t: Instant) { + pub(crate) fn save(&mut self, epoch: Epoch, d: Datagram, t: Instant) { let store = self.store(epoch); if store.len() < Self::CAPACITY { @@ -53,7 +53,7 @@ impl SavedDatagrams { } } - pub fn make_available(&mut self, epoch: Epoch) { + pub(crate) fn make_available(&mut self, epoch: Epoch) { debug_assert_ne!(epoch, Epoch::ZeroRtt); debug_assert_ne!(epoch, Epoch::Initial); if !self.store(epoch).is_empty() { @@ -61,11 +61,11 @@ impl SavedDatagrams { } } - pub const fn available(&self) -> Option { + pub(crate) const fn available(&self) -> Option { self.available } - pub fn take_saved(&mut self) -> Vec { + pub(crate) fn take_saved(&mut self) -> Vec { self.available .take() .map_or_else(Vec::new, |epoch| mem::take(self.store(epoch))) diff --git a/neqo-transport/src/scone.rs b/neqo-transport/src/scone.rs index 2b7b13314c..54283fa029 100644 --- a/neqo-transport/src/scone.rs +++ b/neqo-transport/src/scone.rs @@ -10,7 +10,7 @@ use std::{ }; #[derive(Debug, Clone)] -pub struct Scone { +pub(crate) struct Scone { updated: Instant, rate: Bitrate, } @@ -19,23 +19,23 @@ impl Scone { pub(crate) const PERIOD: Duration = Duration::from_secs(67); #[must_use] - pub const fn new(updated: Instant, rate: Bitrate) -> Self { + pub(crate) const fn new(updated: Instant, rate: Bitrate) -> Self { Self { updated, rate } } /// Determine if the advice has expired. #[must_use] - pub fn expired(&self, now: Instant) -> bool { + pub(crate) fn expired(&self, now: Instant) -> bool { self.updated + Self::PERIOD <= now } #[must_use] - pub const fn rate(&self) -> Bitrate { + pub(crate) const fn rate(&self) -> Bitrate { self.rate } /// Update the value, return true if updated. - pub fn update(&mut self, now: Instant, rate: Option) -> bool { + pub(crate) fn update(&mut self, now: Instant, rate: Option) -> bool { // This uses the simplest form of update, to keep it simple. // A fancier method would remember some number of higher-rate updates // and switch to those when the lower rate expires. diff --git a/neqo-transport/src/sender.rs b/neqo-transport/src/sender.rs index d24672ac7a..6c4fff1712 100644 --- a/neqo-transport/src/sender.rs +++ b/neqo-transport/src/sender.rs @@ -25,7 +25,7 @@ use crate::{ }; /// The number of packets we allow to burst from the pacer. -pub const PACING_BURST_SIZE: usize = 2; +pub(crate) const PACING_BURST_SIZE: usize = 2; #[derive(Debug)] pub struct PacketSender { diff --git a/neqo-transport/src/server.rs b/neqo-transport/src/server.rs index fee266e25b..4e9d5cba46 100644 --- a/neqo-transport/src/server.rs +++ b/neqo-transport/src/server.rs @@ -47,7 +47,7 @@ struct ServerZeroRttChecker { } impl ServerZeroRttChecker { - pub fn new(checker: Box) -> Self { + pub(crate) fn new(checker: Box) -> Self { Self { checker: Rc::new(RefCell::new(checker)), } diff --git a/neqo-transport/src/stats.rs b/neqo-transport/src/stats.rs index 0637f6df35..bc713f1a45 100644 --- a/neqo-transport/src/stats.rs +++ b/neqo-transport/src/stats.rs @@ -469,7 +469,7 @@ impl Debug for Stats { } #[derive(Default, Clone)] -pub struct StatsCell { +pub(crate) struct StatsCell { stats: Rc>, } diff --git a/neqo-transport/src/tparams.rs b/neqo-transport/src/tparams.rs index 7f6bbe01ab..3413e9bba8 100644 --- a/neqo-transport/src/tparams.rs +++ b/neqo-transport/src/tparams.rs @@ -859,7 +859,7 @@ impl TpZeroRttChecker where T: ZeroRttChecker + 'static, { - pub fn wrap( + pub(crate) fn wrap( handler: Rc>, app_checker: T, ) -> Box { diff --git a/neqo-transport/src/tracking.rs b/neqo-transport/src/tracking.rs index 4dbac63b72..38ef4b6927 100644 --- a/neqo-transport/src/tracking.rs +++ b/neqo-transport/src/tracking.rs @@ -71,17 +71,17 @@ impl From for PacketNumberSpace { } } -pub type PacketNumberSpaceSet = EnumSet; +pub(crate) type PacketNumberSpaceSet = EnumSet; /// `InsertionResult` tracks whether something was inserted for `PacketRange::add()`. -pub enum InsertionResult { +pub(crate) enum InsertionResult { Largest, Smallest, NotInserted, } #[derive(Clone, Debug, Default)] -pub struct PacketRange { +pub(crate) struct PacketRange { largest: packet::Number, smallest: packet::Number, ack_needed: bool, @@ -89,7 +89,7 @@ pub struct PacketRange { impl PacketRange { /// Make a single packet range. - pub const fn new(pn: packet::Number) -> Self { + pub(crate) const fn new(pn: packet::Number) -> Self { Self { largest: pn, smallest: pn, @@ -98,24 +98,24 @@ impl PacketRange { } /// Get the number of acknowledged packets in the range. - pub const fn len(&self) -> u64 { + pub(crate) const fn len(&self) -> u64 { self.largest - self.smallest + 1 } /// Returns whether this needs to be sent. - pub const fn ack_needed(&self) -> bool { + pub(crate) const fn ack_needed(&self) -> bool { self.ack_needed } /// Return whether the given number is in the range. - pub const fn contains(&self, pn: packet::Number) -> bool { + pub(crate) const fn contains(&self, pn: packet::Number) -> bool { (pn >= self.smallest) && (pn <= self.largest) } /// Maybe add a packet number to the range. Returns true if it was added /// at the small end (which indicates that this might need merging with a /// preceding range). - pub fn add(&mut self, pn: packet::Number) -> InsertionResult { + pub(crate) fn add(&mut self, pn: packet::Number) -> InsertionResult { assert!(!self.contains(pn)); // Only insert if this is adjacent the current range. if (self.largest + 1) == pn { @@ -146,7 +146,7 @@ impl PacketRange { /// When a packet containing the range `other` is acknowledged, /// clear the `ack_needed` attribute on this. /// Requires that other is equal to this, or a larger range. - pub const fn acknowledged(&mut self, other: &Self) { + pub(crate) const fn acknowledged(&mut self, other: &Self) { if (other.smallest <= self.smallest) && (other.largest >= self.largest) { self.ack_needed = false; } @@ -160,16 +160,16 @@ impl Display for PacketRange { } /// The default maximum ACK delay we use locally and advertise to the remote. -pub const DEFAULT_LOCAL_ACK_DELAY: Duration = Duration::from_millis(20); +pub(crate) const DEFAULT_LOCAL_ACK_DELAY: Duration = Duration::from_millis(20); /// The default maximum ACK delay we assume the remote uses. /// /// > If this value is absent, a default of 25 milliseconds is assumed. /// /// -pub const DEFAULT_REMOTE_ACK_DELAY: Duration = Duration::from_millis(25); +pub(crate) const DEFAULT_REMOTE_ACK_DELAY: Duration = Duration::from_millis(25); /// The default number of in-order packets we will receive after /// largest acknowledged without sending an immediate acknowledgment. -pub const DEFAULT_ACK_PACKET_TOLERANCE: packet::Number = 1; +pub(crate) const DEFAULT_ACK_PACKET_TOLERANCE: packet::Number = 1; const MAX_TRACKED_RANGES: usize = 32; const MAX_ACKS_PER_FRAME: usize = 32; @@ -190,7 +190,7 @@ impl AckToken { /// A structure that tracks what packets have been received, /// and what needs acknowledgement for a packet number space. #[derive(Debug)] -pub struct RecvdPackets { +pub(crate) struct RecvdPackets { space: PacketNumberSpace, ranges: VecDeque, /// The packet number of the lowest number packet that we are tracking. @@ -221,7 +221,7 @@ pub struct RecvdPackets { impl RecvdPackets { /// Make a new `RecvdPackets` for the indicated packet number space. - pub fn new(space: PacketNumberSpace) -> Self { + pub(crate) fn new(space: PacketNumberSpace) -> Self { Self { space, ranges: VecDeque::new(), @@ -244,17 +244,17 @@ impl RecvdPackets { } /// Get the ECN counts. - pub const fn ecn_marks(&mut self) -> &mut ecn::Count { + pub(crate) const fn ecn_marks(&mut self) -> &mut ecn::Count { &mut self.ecn_count } /// Get the time at which the next ACK should be sent. - pub const fn ack_time(&self) -> Option { + pub(crate) const fn ack_time(&self) -> Option { self.ack_time } /// Update acknowledgment delay parameters. - pub const fn ack_freq( + pub(crate) const fn ack_freq( &mut self, seqno: u64, tolerance: packet::Number, @@ -327,7 +327,7 @@ impl RecvdPackets { /// Add the packet to the tracked set. /// Return true if the packet was the largest received so far. - pub fn set_received( + pub(crate) fn set_received( &mut self, now: Instant, pn: packet::Number, @@ -373,13 +373,13 @@ impl RecvdPackets { } /// If we just received a PING frame, we should immediately acknowledge. - pub fn immediate_ack(&mut self, now: Instant) { + pub(crate) fn immediate_ack(&mut self, now: Instant) { self.ack_time = Some(now); qdebug!("[{self}] immediate_ack at {now:?}"); } /// Check if the packet is a duplicate. - pub fn is_duplicate(&self, pn: packet::Number) -> bool { + pub(crate) fn is_duplicate(&self, pn: packet::Number) -> bool { if pn < self.min_tracked { return true; } @@ -390,7 +390,7 @@ impl RecvdPackets { } /// Mark the given range as having been acknowledged. - pub fn acknowledged(&mut self, acked: &[PacketRange]) { + pub(crate) fn acknowledged(&mut self, acked: &[PacketRange]) { let mut range_iter = self.ranges.iter_mut(); let mut cur = range_iter.next().expect("should have at least one range"); for ack in acked { @@ -406,7 +406,7 @@ impl RecvdPackets { /// Length of the worst possible ACK frame, assuming only one range and ECN counts. /// Note that this assumes one byte for the type and count of extra ranges. - pub const USEFUL_ACK_LEN: usize = 1 + 8 + 8 + 1 + 8 + 3 * 8; + pub(crate) const USEFUL_ACK_LEN: usize = 1 + 8 + 8 + 1 + 8 + 3 * 8; /// Generate an ACK frame for this packet number space. /// @@ -519,12 +519,12 @@ impl Display for RecvdPackets { } } -pub struct AckTracker { +pub(crate) struct AckTracker { spaces: EnumMap>, } impl AckTracker { - pub fn drop_space(&mut self, space: PacketNumberSpace) { + pub(crate) fn drop_space(&mut self, space: PacketNumberSpace) { assert_ne!( space, PacketNumberSpace::ApplicationData, @@ -536,11 +536,11 @@ impl AckTracker { self.spaces[space].take(); } - pub fn get_mut(&mut self, space: PacketNumberSpace) -> Option<&mut RecvdPackets> { + pub(crate) fn get_mut(&mut self, space: PacketNumberSpace) -> Option<&mut RecvdPackets> { self.spaces[space].as_mut() } - pub fn ack_freq( + pub(crate) fn ack_freq( &mut self, seqno: u64, tolerance: packet::Number, @@ -554,14 +554,14 @@ impl AckTracker { } /// Force an ACK to be generated immediately. - pub fn immediate_ack(&mut self, space: PacketNumberSpace, now: Instant) { + pub(crate) fn immediate_ack(&mut self, space: PacketNumberSpace, now: Instant) { if let Some(space) = self.get_mut(space) { space.immediate_ack(now); } } /// Determine the earliest time that an ACK might be needed. - pub fn ack_time(&self, now: Instant) -> Option { + pub(crate) fn ack_time(&self, now: Instant) -> Option { if log_enabled!(Level::Trace) { for (space, recvd) in &self.spaces { if let Some(recvd) = recvd { @@ -588,7 +588,7 @@ impl AckTracker { .min() } - pub fn acked(&mut self, token: &AckToken) { + pub(crate) fn acked(&mut self, token: &AckToken) { if let Some(space) = self.get_mut(token.space) { space.acknowledged(&token.ranges); } diff --git a/neqo-transport/tests/common/mod.rs b/neqo-transport/tests/common/mod.rs index a07b29dd2c..fa1a53d266 100644 --- a/neqo-transport/tests/common/mod.rs +++ b/neqo-transport/tests/common/mod.rs @@ -20,12 +20,12 @@ use test_fixture::{CountingConnectionIdGenerator, default_client, now}; /// /// When the count of received packets doesn't match the count of received packets with the /// (default) DSCP. -pub fn assert_dscp(stats: &Stats) { +pub(crate) fn assert_dscp(stats: &Stats) { assert_eq!(stats.dscp_rx[Dscp::Cs0], stats.packets_rx); } /// Create a server. This is different than the one in the fixture, which is a single connection. -pub fn new_server(params: ConnectionParameters) -> Server { +pub(crate) fn new_server(params: ConnectionParameters) -> Server { Server::new( now(), test_fixture::DEFAULT_KEYS, @@ -39,12 +39,12 @@ pub fn new_server(params: ConnectionParameters) -> Server { } /// Create a server. This is different than the one in the fixture, which is a single connection. -pub fn default_server() -> Server { +pub(crate) fn default_server() -> Server { new_server(ConnectionParameters::default()) } // Check that there is at least one connection. Returns a ref to the first confirmed connection. -pub fn connected_server(server: &Server) -> ConnectionRef { +pub(crate) fn connected_server(server: &Server) -> ConnectionRef { #[expect( clippy::mutable_key_type, reason = "ActiveConnectionRef::Hash doesn't access any of the interior mutable types." @@ -59,7 +59,7 @@ pub fn connected_server(server: &Server) -> ConnectionRef { } /// Connect. This returns a reference to the server connection. -pub fn connect(client: &mut Connection, server: &mut Server) -> ConnectionRef { +pub(crate) fn connect(client: &mut Connection, server: &mut Server) -> ConnectionRef { server.set_validation(ValidateAddress::Never); assert_eq!(*client.state(), State::Init); @@ -96,7 +96,7 @@ pub fn connect(client: &mut Connection, server: &mut Server) -> ConnectionRef { #[cfg(test)] /// Scrub through client events to find a resumption token. -pub fn find_ticket(client: &mut Connection) -> ResumptionToken { +pub(crate) fn find_ticket(client: &mut Connection) -> ResumptionToken { client .events() .find_map(|e| { @@ -111,7 +111,7 @@ pub fn find_ticket(client: &mut Connection) -> ResumptionToken { #[cfg(test)] /// Connect to the server and have it generate a ticket. -pub fn generate_ticket(server: &mut Server) -> ResumptionToken { +pub(crate) fn generate_ticket(server: &mut Server) -> ResumptionToken { let mut client = default_client(); let server_conn = connect(&mut client, server); diff --git a/test-fixture/src/sim/delay.rs b/test-fixture/src/sim/delay.rs index f8f27a084a..f47fc343b0 100644 --- a/test-fixture/src/sim/delay.rs +++ b/test-fixture/src/sim/delay.rs @@ -20,7 +20,7 @@ use super::{Node, Rng}; /// An iterator that shares a `Random` instance and produces uniformly /// random `Duration`s within a specified range. -pub struct RandomDelayIter { +pub(super) struct RandomDelayIter { start: Duration, max: u64, rng: Option, @@ -31,7 +31,7 @@ impl RandomDelayIter { /// is inverted (i.e., `bounds.start > bounds.end`), or spans 2^64 /// or more nanoseconds. /// A zero-length range means that random values won't be taken from the Rng - pub fn new(bounds: Range) -> Self { + pub(super) fn new(bounds: Range) -> Self { let max = u64::try_from(bounds.end.checked_sub(bounds.start).unwrap().as_nanos()).unwrap(); Self { start: bounds.start, @@ -40,11 +40,11 @@ impl RandomDelayIter { } } - pub fn set_rng(&mut self, rng: Rng) { + pub(super) fn set_rng(&mut self, rng: Rng) { self.rng = Some(rng); } - pub fn next(&self) -> Duration { + pub(super) fn next(&self) -> Duration { let mut rng = self.rng.as_ref().unwrap().borrow_mut(); let r = rng.random_from(0..self.max); self.start + Duration::from_nanos(r) From ed067c21f74d1a4f58ac408363c48c0571bfea98 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Thu, 30 Apr 2026 14:17:41 +0300 Subject: [PATCH 2/3] Fixes --- mtu/src/lib.rs | 2 +- mtu/src/linux.rs | 2 +- mtu/src/windows.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mtu/src/lib.rs b/mtu/src/lib.rs index cd404700bd..000150304d 100644 --- a/mtu/src/lib.rs +++ b/mtu/src/lib.rs @@ -111,7 +111,7 @@ const fn aligned_by(size: usize, align: usize) -> usize { // // See . #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "visionos"))] -pub fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { +pub(crate) fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { return Err(default_err()); } diff --git a/mtu/src/linux.rs b/mtu/src/linux.rs index 78c1167820..354e1be334 100644 --- a/mtu/src/linux.rs +++ b/mtu/src/linux.rs @@ -348,7 +348,7 @@ fn if_name_mtu(if_index: i32, fd: &mut RouteSocket) -> Result<(String, usize)> { Err(default_err()) } -pub fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { +pub(crate) fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { // Create a netlink socket. let mut fd = RouteSocket::new(AF_NETLINK, NETLINK_ROUTE)?; let if_index = if_index(remote, &mut fd)?; diff --git a/mtu/src/windows.rs b/mtu/src/windows.rs index c3d64621dd..dbb29fed96 100644 --- a/mtu/src/windows.rs +++ b/mtu/src/windows.rs @@ -52,7 +52,7 @@ impl Drop for MibTablePtr { } } -pub fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { +pub(crate) fn interface_and_mtu_impl(remote: IpAddr) -> Result<(String, usize)> { // Convert remote to Windows SOCKADDR_INET format. The SOCKADDR_INET union contains an IPv4 or // an IPv6 address. // From eb20ff03d261f76276faaf3515b821ac24459639 Mon Sep 17 00:00:00 2001 From: Lars Eggert Date: Thu, 30 Apr 2026 14:58:48 +0300 Subject: [PATCH 3/3] Fixes --- neqo-http3/benches/common.rs | 4 ++-- neqo-transport/benches/transfer_common.rs | 8 +++---- neqo-transport/src/packet/mod.rs | 3 +++ neqo-transport/src/recovery/mod.rs | 3 +++ neqo-transport/src/recovery/sent.rs | 27 ++++++++++++++++++++--- 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/neqo-http3/benches/common.rs b/neqo-http3/benches/common.rs index 510174049d..adea21aad5 100644 --- a/neqo-http3/benches/common.rs +++ b/neqo-http3/benches/common.rs @@ -22,7 +22,7 @@ const RTT: Duration = Duration::from_millis(10); const BENCHMARK_PARAMS: [(usize, usize); 3] = [(1, 1_000), (1_000, 1), (1_000, 1_000)]; /// Creates a ready simulator for benchmarking HTTP/3 streams. -pub fn setup(streams: usize, data_size: usize) -> ReadySimulator { +pub(crate) fn setup(streams: usize, data_size: usize) -> ReadySimulator { let nodes = boxed![ Node::default_client(boxed![Requests::new(streams, data_size)]), TailDrop::dsl_uplink(), @@ -38,7 +38,7 @@ pub fn setup(streams: usize, data_size: usize) -> ReadySimulator { /// /// The closure receives the benchmark group and parameters, allowing each /// benchmark to define its own measurement approach. -pub fn benchmark(c: &mut Criterion, mut measure: M) +pub(crate) fn benchmark(c: &mut Criterion, mut measure: M) where M: FnMut(&mut BenchmarkGroup<'_, criterion::measurement::WallTime>, usize, usize), { diff --git a/neqo-transport/benches/transfer_common.rs b/neqo-transport/benches/transfer_common.rs index 9641988a30..9417768748 100644 --- a/neqo-transport/benches/transfer_common.rs +++ b/neqo-transport/benches/transfer_common.rs @@ -18,13 +18,13 @@ use test_fixture::{ }; const DELAY: Duration = Duration::from_millis(10); -pub const TRANSFER_AMOUNT: usize = 1 << 22; // 4Mbyte +pub(crate) const TRANSFER_AMOUNT: usize = 1 << 22; // 4Mbyte const FIXED_SEED: &str = "62df6933ba1f543cece01db8f27fb2025529b27f93df39e19f006e1db3b8c843"; /// Creates a ready simulator for benchmarking transfer. #[must_use] -pub fn setup(label: &str, seed: Option<&str>, pacing: bool) -> ReadySimulator { +pub(crate) fn setup(label: &str, seed: Option<&str>, pacing: bool) -> ReadySimulator { let nodes = boxed![ Node::new_client( ConnectionParameters::default() @@ -58,7 +58,7 @@ pub fn setup(label: &str, seed: Option<&str>, pacing: bool) -> ReadySimulator { /// /// The closure receives the benchmark group, label, seed, and pacing flag, /// allowing each benchmark to define its own measurement approach. -pub fn benchmark(c: &mut Criterion, mut measure: M) +pub(crate) fn benchmark(c: &mut Criterion, mut measure: M) where M: FnMut(&mut BenchmarkGroup<'_, criterion::measurement::WallTime>, &str, Option<&str>, bool), { @@ -81,7 +81,7 @@ where /// Returns the criterion configuration for transfer benchmarks. #[must_use] -pub fn criterion_config() -> Criterion { +pub(crate) fn criterion_config() -> Criterion { Criterion::default() .warm_up_time(Duration::from_secs(5)) .measurement_time(Duration::from_secs(15)) diff --git a/neqo-transport/src/packet/mod.rs b/neqo-transport/src/packet/mod.rs index dc35299a97..1c36fc1bf9 100644 --- a/neqo-transport/src/packet/mod.rs +++ b/neqo-transport/src/packet/mod.rs @@ -56,6 +56,9 @@ mod retry; )] pub use metadata::MetaData; +#[cfg(any(fuzzing, feature = "bench"))] +pub type Number = u64; +#[cfg(not(any(fuzzing, feature = "bench")))] pub(crate) type Number = u64; #[derive(Debug, Clone, Copy, PartialEq, Eq, Enum, EnumIter, FromRepr, Hash)] diff --git a/neqo-transport/src/recovery/mod.rs b/neqo-transport/src/recovery/mod.rs index 9fa0f4f4ad..4f32da4726 100644 --- a/neqo-transport/src/recovery/mod.rs +++ b/neqo-transport/src/recovery/mod.rs @@ -6,6 +6,9 @@ // Tracking of sent packets and detecting their loss. +#[cfg(feature = "bench")] +pub mod sent; +#[cfg(not(feature = "bench"))] pub(crate) mod sent; mod token; diff --git a/neqo-transport/src/recovery/sent.rs b/neqo-transport/src/recovery/sent.rs index 4a4f75f947..80cda06fa7 100644 --- a/neqo-transport/src/recovery/sent.rs +++ b/neqo-transport/src/recovery/sent.rs @@ -212,7 +212,14 @@ impl Packet { /// A collection for packets that we have sent that haven't been acknowledged. #[derive(Debug, Default)] -pub(crate) struct Packets { +#[cfg_attr( + not(feature = "bench"), + expect( + unreachable_pub, + reason = "exposed via `pub mod sent` under `feature = \"bench\"`" + ) +)] +pub struct Packets { /// The collection. packets: BTreeMap, } @@ -228,7 +235,14 @@ impl Packets { self.packets.len() } - pub(crate) fn track(&mut self, packet: Packet) { + #[cfg_attr( + not(feature = "bench"), + expect( + unreachable_pub, + reason = "exposed via `pub mod sent` under `feature = \"bench\"`" + ) + )] + pub fn track(&mut self, packet: Packet) { self.packets.insert(packet.pn, packet); } @@ -240,7 +254,14 @@ impl Packets { /// The values returned will be reversed, so that the most recent packet appears first. /// This is because ACK frames arrive with ranges starting from the largest acknowledged /// and we want to match that. - pub(crate) fn take_ranges(&mut self, acked_ranges: R) -> Vec + #[cfg_attr( + not(feature = "bench"), + expect( + unreachable_pub, + reason = "exposed via `pub mod sent` under `feature = \"bench\"`" + ) + )] + pub fn take_ranges(&mut self, acked_ranges: R) -> Vec where R: IntoIterator>, R::IntoIter: ExactSizeIterator,