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
This commit is contained in:
Jamil
2025-09-11 17:52:53 -04:00
committed by GitHub
parent 0b89959354
commit 1f130ad562
3 changed files with 15 additions and 0 deletions

View File

@@ -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

View File

@@ -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<u16, Error> {
let udp = unsafe { ref_mut_at::<UdpHdr>(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<u16, Error> {
let udp = unsafe { ref_mut_at::<UdpHdr>(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)?;

View File

@@ -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",