Skip to content

Commit 35dc94b

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 bce9653 commit 35dc94b

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();
@@ -523,6 +524,8 @@ impl Endpoint {
523524
buf: &mut Vec<u8>,
524525
server_config: Option<Arc<ServerConfig>>,
525526
) -> Result<(ConnectionHandle, Connection), AcceptError> {
527+
let buf_start = buf.len();
528+
let mut buf = DatagramBuffer::new(buf, buf_start, MIN_INITIAL_SIZE.into());
526529
let remote_address_validated = incoming.remote_address_validated();
527530
incoming.improper_drop_warner.dismiss();
528531
let incoming_buffer = self.incoming_buffers.remove(incoming.incoming_idx);
@@ -564,7 +567,7 @@ impl Endpoint {
564567
&incoming.crypto,
565568
&src_cid,
566569
TransportError::CONNECTION_REFUSED(""),
567-
buf,
570+
&mut buf,
568571
)),
569572
});
570573
}
@@ -662,7 +665,7 @@ impl Endpoint {
662665
&incoming.crypto,
663666
&src_cid,
664667
e.clone(),
665-
buf,
668+
&mut buf,
666669
)),
667670
_ => None,
668671
};
@@ -706,13 +709,15 @@ impl Endpoint {
706709
self.clean_up_incoming(&incoming);
707710
incoming.improper_drop_warner.dismiss();
708711

712+
let start_pos = buf.len();
713+
let mut buf = DatagramBuffer::new(buf, start_pos, MIN_INITIAL_SIZE.into());
709714
self.initial_close(
710715
incoming.packet.header.version,
711716
incoming.addresses,
712717
&incoming.crypto,
713718
&incoming.packet.header.src_cid,
714719
TransportError::CONNECTION_REFUSED(""),
715-
buf,
720+
&mut buf,
716721
)
717722
}
718723

@@ -750,14 +755,16 @@ impl Endpoint {
750755
version: incoming.packet.header.version,
751756
};
752757

753-
let encode = header.encode(buf);
758+
let start_pos = buf.len();
759+
let mut buf = DatagramBuffer::new(buf, start_pos, MIN_INITIAL_SIZE.into());
760+
let encode = header.encode(&mut buf);
754761
buf.put_slice(&token);
755-
buf.extend_from_slice(&server_config.crypto.retry_tag(
762+
buf.put_slice(&server_config.crypto.retry_tag(
756763
incoming.packet.header.version,
757764
&incoming.packet.header.dst_cid,
758-
buf,
765+
&buf,
759766
));
760-
encode.finish(buf, &*incoming.crypto.header.local, None);
767+
encode.finish(&mut buf, &*incoming.crypto.header.local, None);
761768

762769
Ok(Transmit {
763770
destination: incoming.addresses.remote,
@@ -852,7 +859,7 @@ impl Endpoint {
852859
crypto: &Keys,
853860
remote_id: &ConnectionId,
854861
reason: TransportError,
855-
buf: &mut Vec<u8>,
862+
buf: &mut DatagramBuffer<'_>,
856863
) -> Transmit {
857864
// We don't need to worry about CID collisions in initial closes because the peer
858865
// shouldn't respond, and if it does, and the CID collides, we'll just drop the
@@ -871,7 +878,7 @@ impl Endpoint {
871878
let max_len =
872879
INITIAL_MTU as usize - partial_encode.header_len - crypto.packet.local.tag_len();
873880
frame::Close::from(reason).encode(buf, max_len);
874-
buf.resize(buf.len() + crypto.packet.local.tag_len(), 0);
881+
buf.put_bytes(0, crypto.packet.local.tag_len());
875882
partial_encode.finish(buf, &*crypto.header.local, Some((0, &*crypto.packet.local)));
876883
Transmit {
877884
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)