From 34f6b17b67096671532a9c81f22c155f8fff635f Mon Sep 17 00:00:00 2001 From: Nathan Perry Date: Tue, 15 Sep 2026 03:27:56 -0400 Subject: [PATCH 1/2] runtime/dataplane: improve logging for disco errs Main thing is to capture the sender pubkey and source endpoint; I was hitting some transient errors and this helped resolve. Signed-off-by: Nathan Perry Change-Id: I7e18d4bc60a3f755a0aaa30402087a626a6a6964 --- ts_runtime/src/dataplane.rs | 69 ++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/ts_runtime/src/dataplane.rs b/ts_runtime/src/dataplane.rs index d2107fcf..4d46c383 100644 --- a/ts_runtime/src/dataplane.rs +++ b/ts_runtime/src/dataplane.rs @@ -155,37 +155,52 @@ impl Message> for DataplaneActor { }; for mut buf in bufs { - let pkt = match Packet::from_encrypted_bytes_mut(buf.as_mut()) { - Ok(pkt) => pkt, - Err(e) => { - tracing::error!(error = %e, "parsing disco message:\n{}", - buf.iter().hexdump_string(Case::Lower) - ); - return; - } - }; - - if let Err(e) = pkt.decrypt_in_place(&self.env.keys.disco_keys.private) { - tracing::error!(error = %e, "decrypting disco message"); - return; - }; - - let pkt = yoke::Yoke::<&'static Packet, _>::try_attach_to_cart( - buf.freeze(), - // SAFETY: we just parsed this from the same buffer, so type/version are set correctly. - |buf| unsafe { Packet::from_bytes_unchecked(buf) }, + let pkt = tracing::debug_span!( + "disco_ingest", + ?transport_id, + ?ep, + sender_disco = tracing::field::Empty ) - .unwrap(); + .in_scope::<_, Option<IncomingDiscoMsg>>(|| { + let pkt = match Packet::from_encrypted_bytes_mut(buf.as_mut()) { + Ok(pkt) => pkt, + Err(e) => { + tracing::error!(error = %e, "parsing disco message:\n{}", + buf.iter().hexdump_string(Case::Lower) + ); + return None; + } + }; + + tracing::Span::current() + .record("sender_disco", tracing::field::display(pkt.sender_pubkey())); + + if let Err(e) = pkt.decrypt_in_place(&self.env.keys.disco_keys.private) { + tracing::error!(error = %e, "decrypting disco message"); + return None; + }; + + let pkt = yoke::Yoke::<&'static Packet<Plaintext>, _>::try_attach_to_cart( + buf.freeze(), + // SAFETY: we just parsed this from the same buffer, so type/version are set correctly. + |buf| unsafe { Packet::from_bytes_unchecked(buf) }, + ) + .unwrap(); - let pkt = IncomingDiscoMsg { - transport: transport_id, - sender: ep.clone(), - packet: pkt, - }; + let pkt = IncomingDiscoMsg { + transport: transport_id, + sender: ep.clone(), + packet: pkt, + }; + + tracing::trace!(?pkt, "decrypted disco message"); - tracing::trace!(?pkt, "decrypted disco message"); + Some(pkt) + }); - self.env.publish_noretain(pkt).await.unwrap(); + if let Some(pkt) = pkt { + self.env.publish_noretain(pkt).await.unwrap(); + } } } } From 1330438b164a947e74d1efb3681961aa730411cd Mon Sep 17 00:00:00 2001 From: Nathan Perry <nathan@tailscale.com> Date: Tue, 15 Sep 2026 03:27:56 -0400 Subject: [PATCH 2/2] disco: fix endpoint encoding Signed-off-by: Nathan Perry <nathan@tailscale.com> Change-Id: I78b1fcef9103bd08dfb1f50bb64da1ab6a6a6964 --- ts_disco_protocol/src/endpoint.rs | 35 +++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/ts_disco_protocol/src/endpoint.rs b/ts_disco_protocol/src/endpoint.rs index 74bebcf2..55f55143 100644 --- a/ts_disco_protocol/src/endpoint.rs +++ b/ts_disco_protocol/src/endpoint.rs @@ -87,7 +87,7 @@ impl Endpoint { }; Self { - addr: zerocopy::transmute!(ip.segments()), + addr: zerocopy::transmute!(ip.octets()), port: zerocopy::U16::new(sa.port()), } } @@ -120,7 +120,7 @@ impl From<Endpoint> for SocketAddr { impl From<SocketAddrV6> for Endpoint { fn from(value: SocketAddrV6) -> Self { Self { - addr: zerocopy::transmute!(value.ip().segments()), + addr: zerocopy::transmute!(value.ip().octets()), port: value.port().into(), } } @@ -131,3 +131,34 @@ impl From<SocketAddr> for Endpoint { Self::from_socket_addr(value) } } + +#[cfg(test)] +mod test { + use core::str::FromStr; + + use zerocopy::{FromBytes, IntoBytes}; + + use super::*; + + #[test] + fn convert_basic() { + const BYTES: [u8; 18] = [ + 0x26, 0x00, 0xab, 0xcd, 0xef, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0xa5, 0xb5, + ]; + + let addr = Ipv6Addr::from_str("2600:abcd:ef01:0203:0405:0607:0809:0a0b").unwrap(); + let ep = Endpoint::read_from_bytes(&BYTES).unwrap(); + + assert_eq!(ep.addr_v6(), addr); + assert_eq!(ep.port(), 0xa5b5); + + let sa = ep.socket_addr(); + assert_eq!(sa.ip(), IpAddr::V6(addr)); + assert_eq!(sa.port(), 0xa5b5); + + let ep2 = Endpoint::from(sa); + assert_eq!(ep2, ep); + assert_eq!(ep2.as_bytes(), BYTES); + } +}