Skip to content

Commit c380db1

Browse files
committed
Use DatagramBuffer directly, remove BufSlice trait
This uses the DatagramBuffer type directly, in favour of having the BufSlice trait that is only used once. This meanse Header::encode now takes &mut DatagramBuffer and all the callers have to construct this. Previously they used `&mut Vec<u8>` for this. The DatagramBuffer type is still kept crate-internal. Endpoint::handle and friends still use `&mut Vec<u8>` for the buffer in which to build the response packet, to not change the public API.
1 parent a4d214b commit c380db1

File tree

5 files changed

+40
-60
lines changed

5 files changed

+40
-60
lines changed

quinn-proto/src/connection/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ mod timer;
8989
use timer::{Timer, TimerTable};
9090

9191
mod transmit_builder;
92-
pub(crate) use transmit_builder::BufSlice;
92+
pub(crate) use transmit_builder::DatagramBuffer;
9393
use transmit_builder::TransmitBuilder;
9494

9595
/// Protocol state and logic for a single QUIC connection

quinn-proto/src/connection/packet_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use tracing::{trace, trace_span};
55
use super::{Connection, SentFrames, TransmitBuilder, spaces::SentPacket};
66
use crate::{
77
ConnectionId, Instant, TransportError, TransportErrorCode,
8-
connection::{BufSlice, ConnectionSide},
8+
connection::ConnectionSide,
99
frame::{self, Close},
1010
packet::{FIXED_BIT, Header, InitialHeader, LongType, PacketNumber, PartialEncode, SpaceId},
1111
};

quinn-proto/src/connection/transmit_builder.rs

Lines changed: 7 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,6 @@ impl<'a> TransmitBuilder<'a> {
149149
/// This buffer implements [`BufSlice`] and thus allows writing into the buffer using
150150
/// [`BufMut`] and both reading and modifying the already written data in the buffer
151151
/// using [`Deref`] and [`DerefMut`]. The buffer also enforces a maximum size.
152-
// This returns a concrete type since `impl BufSlice` would need a `+ use<'_>` lifetime
153-
// bound, which is only supported since Rust 1.82.
154152
pub(super) fn datagram_mut(&mut self) -> DatagramBuffer<'_> {
155153
DatagramBuffer::new(
156154
self.buf,
@@ -196,32 +194,6 @@ impl<'a> TransmitBuilder<'a> {
196194
}
197195
}
198196

199-
/// A writable buffer with a capacity and access to the already written bytes
200-
///
201-
/// This is a writable buffer, using the [`BufMut`] trait, which also has a maximum capacity.
202-
/// If more bytes are written than the buffer can contain a panic will occur.
203-
///
204-
/// The [`Deref`] impl must return the already written bytes as a slice. [`DerefMut`] must
205-
/// allow modification of these already written bytes.
206-
pub(crate) trait BufSlice: BufMut + Deref<Target = [u8]> + DerefMut {
207-
/// Returns the number of already written bytes in the buffer
208-
fn len(&self) -> usize;
209-
210-
/// Returns the maximum size of the buffer
211-
fn capacity(&self) -> usize;
212-
}
213-
214-
impl BufSlice for Vec<u8> {
215-
fn len(&self) -> usize {
216-
self.len()
217-
}
218-
219-
/// For `Vec<u8>` the capacity is the same as the maximum vec size
220-
fn capacity(&self) -> usize {
221-
isize::MAX as usize
222-
}
223-
}
224-
225197
/// A [`BufSlice`] implementation for a datagram
226198
#[derive(Debug)]
227199
pub(crate) struct DatagramBuffer<'a> {
@@ -235,6 +207,10 @@ pub(crate) struct DatagramBuffer<'a> {
235207

236208
impl<'a> DatagramBuffer<'a> {
237209
pub(crate) fn new(buf: &'a mut Vec<u8>, start_offset: usize, max_size: usize) -> Self {
210+
// Make sure that at least this datagram is allocated. Does nothing if, like for a
211+
// transmit, already more has been allocated.
212+
buf.reserve(max_size);
213+
238214
let max_offset = start_offset + max_size;
239215
DatagramBuffer {
240216
buf,
@@ -272,21 +248,16 @@ impl DerefMut for DatagramBuffer<'_> {
272248
}
273249
}
274250

275-
impl BufSlice for DatagramBuffer<'_> {
276-
/// Returns the number of already written bytes in the buffer
277-
fn len(&self) -> usize {
278-
self.buf.len() - self.start_offset
279-
}
280-
251+
impl DatagramBuffer<'_> {
281252
/// Returns the maximum size of the buffer
282-
fn capacity(&self) -> usize {
253+
pub(crate) fn capacity(&self) -> usize {
283254
self.max_offset - self.start_offset
284255
}
285256
}
286257

287258
// Temporary compatibility with the BufLen trait. To be removed in follow-up commits.
288259
impl BufLen for DatagramBuffer<'_> {
289260
fn len(&self) -> usize {
290-
<Self as BufSlice>::len(self)
261+
self.deref().len()
291262
}
292263
}

quinn-proto/src/endpoint.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
cid_generator::ConnectionIdGenerator,
2121
coding::BufMutExt,
2222
config::{ClientConfig, EndpointConfig, ServerConfig},
23-
connection::{Connection, ConnectionError, SideArgs},
23+
connection::{Connection, ConnectionError, DatagramBuffer, SideArgs},
2424
crypto::{self, Keys, UnsupportedVersion},
2525
frame,
2626
packet::{
@@ -146,6 +146,8 @@ impl Endpoint {
146146
data: BytesMut,
147147
buf: &mut Vec<u8>,
148148
) -> Option<DatagramEvent> {
149+
let start_pos = buf.len();
150+
let buf = &mut DatagramBuffer::new(buf, start_pos, MIN_INITIAL_SIZE.into());
149151
// Partially decode packet or short-circuit if unable
150152
let datagram_len = data.len();
151153
let event = match PartialDecode::new(
@@ -264,7 +266,7 @@ impl Endpoint {
264266
inciting_dgram_len: usize,
265267
addresses: FourTuple,
266268
dst_cid: ConnectionId,
267-
buf: &mut Vec<u8>,
269+
buf: &mut DatagramBuffer<'_>,
268270
) -> Option<Transmit> {
269271
if self
270272
.last_stateless_reset
@@ -303,11 +305,10 @@ impl Endpoint {
303305
self.rng
304306
.random_range(IDEAL_MIN_PADDING_LEN..max_padding_len)
305307
};
306-
buf.reserve(padding_len + RESET_TOKEN_SIZE);
307-
buf.resize(padding_len, 0);
308+
buf.put_bytes(0, padding_len);
308309
self.rng.fill_bytes(&mut buf[0..padding_len]);
309310
buf[0] = 0b0100_0000 | (buf[0] >> 2);
310-
buf.extend_from_slice(&ResetToken::new(&*self.config.reset_key, dst_cid));
311+
buf.put_slice(&ResetToken::new(&*self.config.reset_key, dst_cid));
311312

312313
debug_assert!(buf.len() < inciting_dgram_len);
313314

@@ -419,7 +420,7 @@ impl Endpoint {
419420
datagram_len: usize,
420421
event: DatagramConnectionEvent,
421422
addresses: FourTuple,
422-
buf: &mut Vec<u8>,
423+
buf: &mut DatagramBuffer<'_>,
423424
) -> Option<DatagramEvent> {
424425
let dst_cid = event.first_decode.dst_cid();
425426
let header = event.first_decode.initial_header().unwrap();
@@ -525,6 +526,8 @@ impl Endpoint {
525526
buf: &mut Vec<u8>,
526527
server_config: Option<Arc<ServerConfig>>,
527528
) -> Result<(ConnectionHandle, Connection), AcceptError> {
529+
let buf_start = buf.len();
530+
let mut buf = DatagramBuffer::new(buf, buf_start, MIN_INITIAL_SIZE.into());
528531
let remote_address_validated = incoming.remote_address_validated();
529532
incoming.improper_drop_warner.dismiss();
530533
let incoming_buffer = self.incoming_buffers.remove(incoming.incoming_idx);
@@ -566,7 +569,7 @@ impl Endpoint {
566569
&incoming.crypto,
567570
&src_cid,
568571
TransportError::CONNECTION_REFUSED(""),
569-
buf,
572+
&mut buf,
570573
)),
571574
});
572575
}
@@ -664,7 +667,7 @@ impl Endpoint {
664667
&incoming.crypto,
665668
&src_cid,
666669
e.clone(),
667-
buf,
670+
&mut buf,
668671
)),
669672
_ => None,
670673
};
@@ -708,13 +711,15 @@ impl Endpoint {
708711
self.clean_up_incoming(&incoming);
709712
incoming.improper_drop_warner.dismiss();
710713

714+
let start_pos = buf.len();
715+
let mut buf = DatagramBuffer::new(buf, start_pos, MIN_INITIAL_SIZE.into());
711716
self.initial_close(
712717
incoming.packet.header.version,
713718
incoming.addresses,
714719
&incoming.crypto,
715720
&incoming.packet.header.src_cid,
716721
TransportError::CONNECTION_REFUSED(""),
717-
buf,
722+
&mut buf,
718723
)
719724
}
720725

@@ -752,14 +757,16 @@ impl Endpoint {
752757
version: incoming.packet.header.version,
753758
};
754759

755-
let encode = header.encode(buf);
760+
let start_pos = buf.len();
761+
let mut buf = DatagramBuffer::new(buf, start_pos, MIN_INITIAL_SIZE.into());
762+
let encode = header.encode(&mut buf);
756763
buf.put_slice(&token);
757-
buf.extend_from_slice(&server_config.crypto.retry_tag(
764+
buf.put_slice(&server_config.crypto.retry_tag(
758765
incoming.packet.header.version,
759766
&incoming.packet.header.dst_cid,
760-
buf,
767+
&buf,
761768
));
762-
encode.finish(buf, &*incoming.crypto.header.local, None);
769+
encode.finish(&mut buf, &*incoming.crypto.header.local, None);
763770

764771
Ok(Transmit {
765772
destination: incoming.addresses.remote,
@@ -854,7 +861,7 @@ impl Endpoint {
854861
crypto: &Keys,
855862
remote_id: &ConnectionId,
856863
reason: TransportError,
857-
buf: &mut Vec<u8>,
864+
buf: &mut DatagramBuffer<'_>,
858865
) -> Transmit {
859866
// We don't need to worry about CID collisions in initial closes because the peer
860867
// shouldn't respond, and if it does, and the CID collides, we'll just drop the
@@ -873,7 +880,7 @@ impl Endpoint {
873880
let max_len =
874881
INITIAL_MTU as usize - partial_encode.header_len - crypto.packet.local.tag_len();
875882
frame::Close::from(reason).encode(buf, max_len);
876-
buf.resize(buf.len() + crypto.packet.local.tag_len(), 0);
883+
buf.put_bytes(0, crypto.packet.local.tag_len());
877884
partial_encode.finish(buf, &*crypto.header.local, Some((0, &*crypto.packet.local)));
878885
Transmit {
879886
destination: addresses.remote,

quinn-proto/src/packet.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use thiserror::Error;
66
use crate::{
77
ConnectionId,
88
coding::{self, BufExt, BufMutExt},
9-
connection::BufSlice,
9+
connection::DatagramBuffer,
1010
crypto,
1111
};
1212

@@ -286,7 +286,7 @@ impl Header {
286286
///
287287
/// The current position of the buffer is stored in the [`PartialEncode`] as the start
288288
/// of the packet in the buffer.
289-
pub(crate) fn encode(&self, w: &mut impl BufSlice) -> PartialEncode {
289+
pub(crate) fn encode(&self, w: &mut DatagramBuffer<'_>) -> PartialEncode {
290290
use Header::*;
291291
let start = w.len();
292292
match *self {
@@ -943,8 +943,10 @@ mod tests {
943943
#[cfg(any(feature = "rustls-aws-lc-rs", feature = "rustls-ring"))]
944944
#[test]
945945
fn header_encoding() {
946-
use crate::Side;
946+
use std::ops::Deref;
947+
947948
use crate::crypto::rustls::{initial_keys, initial_suite_from_provider};
949+
use crate::{MIN_INITIAL_SIZE, Side};
948950
#[cfg(all(feature = "rustls-aws-lc-rs", not(feature = "rustls-ring")))]
949951
use rustls::crypto::aws_lc_rs::default_provider;
950952
#[cfg(feature = "rustls-ring")]
@@ -957,6 +959,7 @@ mod tests {
957959
let suite = initial_suite_from_provider(&std::sync::Arc::new(provider)).unwrap();
958960
let client = initial_keys(Version::V1, dcid, Side::Client, &suite);
959961
let mut buf = Vec::new();
962+
let mut buf = DatagramBuffer::new(&mut buf, 0, MIN_INITIAL_SIZE.into());
960963
let header = Header::Initial(InitialHeader {
961964
number: PacketNumber::U8(0),
962965
src_cid: ConnectionId::new(&[]),
@@ -965,15 +968,14 @@ mod tests {
965968
version: crate::DEFAULT_SUPPORTED_VERSIONS[0],
966969
});
967970
let encode = header.encode(&mut buf);
968-
let header_len = buf.len();
969-
buf.resize(header_len + 16 + client.packet.local.tag_len(), 0);
971+
buf.put_bytes(0, 16 + client.packet.local.tag_len());
970972
encode.finish(
971973
&mut buf,
972974
&*client.header.local,
973975
Some((0, &*client.packet.local)),
974976
);
975977

976-
for byte in &buf {
978+
for byte in buf.deref() {
977979
print!("{byte:02x}");
978980
}
979981
println!();
@@ -988,7 +990,7 @@ mod tests {
988990
let server = initial_keys(Version::V1, dcid, Side::Server, &suite);
989991
let supported_versions = crate::DEFAULT_SUPPORTED_VERSIONS.to_vec();
990992
let decode = PartialDecode::new(
991-
buf.as_slice().into(),
993+
buf.deref().into(),
992994
&FixedLengthConnectionIdParser::new(0),
993995
&supported_versions,
994996
false,

0 commit comments

Comments
 (0)