Skip to content

fix(dnstap source): unwrap IPv4-mapped IPv6 client addresses reported as INET#25540

Open
xfocus3 wants to merge 1 commit into
vectordotdev:masterfrom
xfocus3:fix/dnstap-ipv4-mapped-inet-25181
Open

fix(dnstap source): unwrap IPv4-mapped IPv6 client addresses reported as INET#25540
xfocus3 wants to merge 1 commit into
vectordotdev:masterfrom
xfocus3:fix/dnstap-ipv4-mapped-inet-25181

Conversation

@xfocus3
Copy link
Copy Markdown

@xfocus3 xfocus3 commented May 31, 2026

Summary

Closes #25181.

The dnstap source rendered sourceAddress (and responseAddress) as 0.0.0.0 for some producers. The reporter and a community investigator decoded the raw dnstap frame and pinned the root cause: CoreDNS (via Go's net.IP) can send the client address as a 16-byte IPv4-mapped IPv6 value (::ffff:a.b.c.d) while still reporting socket_family = INET.

The parser keyed the address width off socket_family alone:

let source_address = if socket_family == 1 {
    let address_buffer: [u8; 4] = query_address[0..4].try_into()?;  // first 4 bytes
    IpAddr::V4(Ipv4Addr::from(address_buffer))
} else {
    ...
};

For an IPv4-mapped buffer the leading four bytes are zeros, so the address became 0.0.0.0 even though sourcePort (a separate field) was correct.

Change

  • Extracted a parse_dnstap_address(socket_family, address) helper shared by both the query- and response-address parsing paths.
  • When socket_family == INET and the buffer is 16 bytes, the address is interpreted as IPv6 and, if it is IPv4-mapped, unwrapped to the real IPv4 address via Ipv6Addr::to_ipv4_mapped. Standard 4-byte INET and 16-byte INET6 addresses are parsed exactly as before, so existing behavior is unchanged.

Testing

  • cargo test -p dnstap-parser — 14 passed (added test_parse_dnstap_address_handles_ipv4_mapped_inet covering standard IPv4, the IPv4-mapped-as-INET regression, standard IPv6, and too-short buffers).
  • cargo check -p dnstap-parser, cargo clippy -p dnstap-parser --all-targets -- -D warnings, cargo fmt -p dnstap-parser --check — all clean.
  • Changelog fragment added and validated with ./scripts/check_changelog_fragments.sh.

… as INET

Some dnstap producers (notably CoreDNS, via Go's net.IP) send the client
address as a 16-byte IPv4-mapped IPv6 value (::ffff:a.b.c.d) while still
setting socket_family to INET. The parser keyed the address width off
socket_family alone and read only the leading 4 (zero) bytes, so
sourceAddress and responseAddress were rendered as 0.0.0.0.

Detect the mapped form and unwrap it to the real IPv4 address. Extracted a
parse_dnstap_address helper shared by both query and response parsing, and
added a regression test.

Fixes vectordotdev#25181
@xfocus3 xfocus3 requested a review from a team as a code owner May 31, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dnstap sourceAddress: "0.0.0.0" instead of real client IP when using TCP transport

1 participant