Skip to content

Commit 7facdc4

Browse files
committed
ts_packet: support yoke
This will enable e.g. a decrypted derp packet to carry its backing `Packet` around. Signed-off-by: Nathan Perry <nathan@tailscale.com> Change-Id: Ic26833761832d03d372d4331723d422d6a6a6964
1 parent de40ca6 commit 7facdc4

3 files changed

Lines changed: 41 additions & 1 deletion

File tree

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ts_packet/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,8 @@ bytes.workspace = true
1515
crypto_box.workspace = true
1616
ts_hexdump.workspace = true
1717

18+
stable_deref_trait = "1.2"
19+
yoke.workspace = true
20+
1821
[lints]
1922
workspace = true

ts_packet/src/lib.rs

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use alloc::{borrow::ToOwned, string::String, vec::Vec};
77
use core::{
88
fmt::{self, LowerHex, UpperHex},
99
net::IpAddr,
10-
ops::{Index, IndexMut},
10+
ops::{Deref, DerefMut, Index, IndexMut},
1111
slice::{Iter, IterMut, SliceIndex},
1212
};
1313

@@ -524,6 +524,41 @@ impl AsRef<[u8]> for PacketMut {
524524
}
525525
}
526526

527+
impl Deref for Packet {
528+
type Target = [u8];
529+
fn deref(&self) -> &Self::Target {
530+
&self.contents
531+
}
532+
}
533+
534+
impl Deref for PacketMut {
535+
type Target = [u8];
536+
fn deref(&self) -> &Self::Target {
537+
&self.contents
538+
}
539+
}
540+
541+
impl DerefMut for PacketMut {
542+
fn deref_mut(&mut self) -> &mut Self::Target {
543+
&mut self.contents
544+
}
545+
}
546+
547+
// SAFETY: the underlying buf ptr is on the heap, hence stable. This is only valid because
548+
// PacketMut's DerefMut::Target is [u8], meaning that the underlying ptr can't be modified through
549+
// the `deref_mut`ed ref, and `split_to` (which does modify the heap pointer) takes `&mut self`,
550+
// which is called out by StableDeref docs as being unrestricted other than for DerefMut and Drop.
551+
unsafe impl stable_deref_trait::StableDeref for PacketMut {}
552+
553+
// SAFETY: the underlying buf ptr is on the heap, hence stable. While the underlying Bytes does also
554+
// provide split_to, Packet does not, so the pointer can't be modified. But even if it did, this
555+
// wouldn't cause issues for StableDeref since Packet only implements Deref, and in that case the
556+
// restriction is that the pointer can't change through &Self (split_to takes &mut self).
557+
unsafe impl stable_deref_trait::StableDeref for Packet {}
558+
559+
// SAFETY: cloning the underlying bytes just increments a refcount.
560+
unsafe impl yoke::CloneableCart for Packet {}
561+
527562
impl Buf for PacketMut {
528563
fn remaining(&self) -> usize {
529564
self.contents.remaining_mut()

0 commit comments

Comments
 (0)