Skip to content

Commit

Permalink
feat(common): make Datagram generic over payload type
Browse files Browse the repository at this point in the history
Previously the payload type of `Datagram` was `Vec<u8>`, thus the `Datagram`
always owned the UDP datagram payload.

This change enables `Datagram` to represent both (a) an owned payload allocation
(i.e. `Vec<u8>`), but also represent (b) a view into an existing payload (e.g. a
long lived receive buffer via `&[u8]`).

The default payload type stays `Vec<u8>`, thus not breaking existing usage of
`Datagram`.
  • Loading branch information
mxinden committed Oct 21, 2024
1 parent 62415bf commit 0dcc9b2
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 18 deletions.
74 changes: 58 additions & 16 deletions neqo-common/src/datagram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,14 @@ use std::{net::SocketAddr, ops::Deref};
use crate::{hex_with_len, IpTos};

#[derive(Clone, PartialEq, Eq)]
pub struct Datagram {
pub struct Datagram<D = Vec<u8>> {
src: SocketAddr,
dst: SocketAddr,
tos: IpTos,
d: Vec<u8>,
d: D,
}

impl Datagram {
pub fn new<V: Into<Vec<u8>>>(src: SocketAddr, dst: SocketAddr, tos: IpTos, d: V) -> Self {
Self {
src,
dst,
tos,
d: d.into(),
}
}

impl<D> Datagram<D> {
#[must_use]
pub const fn source(&self) -> SocketAddr {
self.src
Expand All @@ -46,15 +37,43 @@ impl Datagram {
}
}

impl Deref for Datagram {
type Target = Vec<u8>;
impl<D: AsRef<[u8]>> Datagram<D> {
pub fn len(&self) -> usize {
self.d.as_ref().len()
}

pub fn is_empty(&self) -> bool {
self.len() == 0
}

Check warning on line 47 in neqo-common/src/datagram.rs

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L45-L47

Added lines #L45 - L47 were not covered by tests
}

// TODO: Needed?
impl<D: AsMut<[u8]> + AsRef<[u8]>> AsMut<[u8]> for Datagram<D> {
fn as_mut(&mut self) -> &mut [u8] {
self.d.as_mut()
}

Check warning on line 54 in neqo-common/src/datagram.rs

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L52-L54

Added lines #L52 - L54 were not covered by tests
}

impl Datagram<Vec<u8>> {
pub fn new<V: Into<Vec<u8>>>(src: SocketAddr, dst: SocketAddr, tos: IpTos, d: V) -> Self {
Self {
src,
dst,
tos,
d: d.into(),
}
}
}

impl<D: AsRef<[u8]>> Deref for Datagram<D> {
type Target = [u8];
#[must_use]
fn deref(&self) -> &Self::Target {
&self.d
AsRef::<[u8]>::as_ref(self)
}
}

impl std::fmt::Debug for Datagram {
impl<D: AsRef<[u8]>> std::fmt::Debug for Datagram<D> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
Expand All @@ -67,6 +86,29 @@ impl std::fmt::Debug for Datagram {
}
}

impl<'a> Datagram<&'a [u8]> {
#[must_use]
pub const fn from_slice(src: SocketAddr, dst: SocketAddr, tos: IpTos, d: &'a [u8]) -> Self {
Self { src, dst, tos, d }
}

Check warning on line 93 in neqo-common/src/datagram.rs

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L91-L93

Added lines #L91 - L93 were not covered by tests

#[must_use]
pub fn to_owned(&self) -> Datagram {
Datagram {
src: self.src,
dst: self.dst,
tos: self.tos,
d: self.d.to_vec(),
}
}

Check warning on line 103 in neqo-common/src/datagram.rs

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L96-L103

Added lines #L96 - L103 were not covered by tests
}

impl<D: AsRef<[u8]>> AsRef<[u8]> for Datagram<D> {
fn as_ref(&self) -> &[u8] {
self.d.as_ref()
}
}

#[cfg(test)]
use test_fixture::datagram;

Expand Down
4 changes: 2 additions & 2 deletions test-fixture/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ fn split_packet(buf: &[u8]) -> (&[u8], Option<&[u8]>) {
pub fn split_datagram(d: &Datagram) -> (Datagram, Option<Datagram>) {
let (a, b) = split_packet(&d[..]);
(
Datagram::new(d.source(), d.destination(), d.tos(), a),
b.map(|b| Datagram::new(d.source(), d.destination(), d.tos(), b)),
Datagram::new(d.source(), d.destination(), d.tos(), a.to_vec()),
b.map(|b| Datagram::new(d.source(), d.destination(), d.tos(), b.to_vec())),
)
}

Expand Down

0 comments on commit 0dcc9b2

Please sign in to comment.