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 17, 2024
1 parent 62415bf commit c2520e2
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 15 deletions.
75 changes: 62 additions & 13 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,6 +37,27 @@ impl Datagram {
}
}

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(),
}
}

#[must_use]
pub fn borrow(&self) -> Datagram<&[u8]> {
Datagram {
src: self.src,
dst: self.dst,
tos: self.tos,
d: self.d.as_ref(),
}
}

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

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L51-L58

Added lines #L51 - L58 were not covered by tests
}

impl Deref for Datagram {
type Target = Vec<u8>;
#[must_use]
Expand All @@ -54,7 +66,7 @@ impl Deref for Datagram {
}
}

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 +79,43 @@ impl std::fmt::Debug for Datagram {
}
}

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

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

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L85-L87

Added lines #L85 - L87 were not covered by tests
}

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 94 in neqo-common/src/datagram.rs

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L92-L94

Added lines #L92 - L94 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 104 in neqo-common/src/datagram.rs

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L97-L104

Added lines #L97 - L104 were not covered by tests
}

impl<'a> From<&'a Datagram> for Datagram<&'a [u8]> {
fn from(value: &'a Datagram) -> Self {
value.borrow()
}

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

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L108-L110

Added lines #L108 - L110 were not covered by tests
}

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

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

View check run for this annotation

Codecov / codecov/patch

neqo-common/src/datagram.rs#L114-L116

Added lines #L114 - L116 were not covered by tests
}

#[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 c2520e2

Please sign in to comment.