From 1f130ad5628375bb5bff35673ed1f771461f1750 Mon Sep 17 00:00:00 2001 From: Jamil Date: Thu, 11 Sep 2025 17:52:53 -0400 Subject: [PATCH] fix(relay): XDP_PASS DNS replies (#10330) DNS replies are UDP packets often arriving to our ephemeral range. As such, these get dropped because we attempt to look up a channel map for them and fail to find anything. To fix this, we assume all UDP packets arriving with a source port of 53 are DNS packets, and pass them up the stack. There are likely other types of UDP traffic this could be problematic for (QUIC comes to mind), but this fixes the immediate issue at hand for now, as detecting STUN probes is somewhat complex. Fixes #10329 --- rust/relay/ebpf-turn-router/src/main.rs | 1 + rust/relay/ebpf-turn-router/src/try_handle_turn.rs | 12 ++++++++++++ .../ebpf-turn-router/src/try_handle_turn/error.rs | 2 ++ 3 files changed, 15 insertions(+) diff --git a/rust/relay/ebpf-turn-router/src/main.rs b/rust/relay/ebpf-turn-router/src/main.rs index 91c3aba9c..10f7e42c7 100644 --- a/rust/relay/ebpf-turn-router/src/main.rs +++ b/rust/relay/ebpf-turn-router/src/main.rs @@ -28,6 +28,7 @@ pub fn handle_turn(ctx: aya_ebpf::programs::XdpContext) -> u32 { Err(Error::NotIp | Error::NotUdp) => xdp_action::XDP_PASS, Err( e @ (Error::PacketTooShort + | Error::DnsPacket | Error::NotTurn | Error::NotAChannelDataMessage | Error::UdpChecksumMissing diff --git a/rust/relay/ebpf-turn-router/src/try_handle_turn.rs b/rust/relay/ebpf-turn-router/src/try_handle_turn.rs index 225f4589d..a34a1cbdf 100644 --- a/rust/relay/ebpf-turn-router/src/try_handle_turn.rs +++ b/rust/relay/ebpf-turn-router/src/try_handle_turn.rs @@ -38,6 +38,8 @@ const UPPER_PORT: u16 = 65535; const CHAN_START: u16 = 0x4000; /// Channel number end const CHAN_END: u16 = 0x7FFF; +/// DNS port +const DNS_PORT: u16 = 53; #[inline(always)] pub fn try_handle_turn(ctx: &XdpContext) -> Result<(), Error> { @@ -72,6 +74,11 @@ fn try_handle_turn_ipv4(ctx: &XdpContext) -> Result { let udp = unsafe { ref_mut_at::(ctx, EthHdr::LEN + Ipv4Hdr::LEN)? }; let udp_payload_len = udp.len() - UdpHdr::LEN as u16; + // We do not want to handle DNS packets + if udp.source() == DNS_PORT { + return Err(Error::DnsPacket); + } + if (LOWER_PORT..=UPPER_PORT).contains(&udp.dest()) { try_handle_from_ipv4_udp(ctx)?; @@ -100,6 +107,11 @@ fn try_handle_turn_ipv6(ctx: &XdpContext) -> Result { let udp = unsafe { ref_mut_at::(ctx, EthHdr::LEN + Ipv6Hdr::LEN)? }; let udp_payload_len = udp.len() - UdpHdr::LEN as u16; + // We do not want to handle DNS packets + if udp.source() == DNS_PORT { + return Err(Error::DnsPacket); + } + if (LOWER_PORT..=UPPER_PORT).contains(&udp.dest()) { try_handle_from_ipv6_udp(ctx)?; diff --git a/rust/relay/ebpf-turn-router/src/try_handle_turn/error.rs b/rust/relay/ebpf-turn-router/src/try_handle_turn/error.rs index 00ee9efa0..68a89f9a8 100644 --- a/rust/relay/ebpf-turn-router/src/try_handle_turn/error.rs +++ b/rust/relay/ebpf-turn-router/src/try_handle_turn/error.rs @@ -7,6 +7,7 @@ pub enum Error { UdpChecksumMissing, PacketTooShort, NotUdp, + DnsPacket, NotTurn, NotIp, Ipv4PacketWithOptions, @@ -34,6 +35,7 @@ impl aya_log_ebpf::WriteToBuf for Error { Error::UdpChecksumMissing => "UDP checksum is missing", Error::PacketTooShort => "Packet is too short", Error::NotUdp => "Not a UDP packet", + Error::DnsPacket => "DNS packet", Error::NotTurn => "Not TURN traffic", Error::NotIp => "Not an IP packet", Error::Ipv4PacketWithOptions => "IPv4 packet has options",