Files
coredns/plugin/dnstap/msg/msg_test.go
2026-06-25 15:49:32 -07:00

92 lines
2.9 KiB
Go

package msg
import (
"net"
"testing"
tap "github.com/dnstap/golang-dnstap"
)
// ipv4MappedINET is the 16-byte IPv4-mapped IPv6 form of 192.0.2.1
// (::ffff:192.0.2.1). Dual-stack listeners report IPv4 clients this way, and
// Go's net.IP.To4 still recognizes them as IPv4.
var ipv4MappedINET = net.IP{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 0, 2, 1}
// An IPv4 client reported as an IPv4-mapped IPv6 address must be stored as a
// 4-octet address with SocketFamily INET, otherwise the dnstap message parser
// could get confused when expecting only 4 bytes but is presented with 16 bytes.
func TestSetAddressIPv4MappedReportedAsINET(t *testing.T) {
assertINET := func(t *testing.T, family tap.SocketFamily, addr []byte) {
t.Helper()
if family != tap.SocketFamily_INET {
t.Errorf("SocketFamily = %v, want INET", family)
}
if len(addr) != 4 {
t.Errorf("address length = %d, want 4 octets for INET", len(addr))
}
if got := net.IP(addr).String(); got != "192.0.2.1" {
t.Errorf("address = %q, want %q", got, "192.0.2.1")
}
}
t.Run("query/udp", func(t *testing.T) {
m := new(tap.Message)
if err := SetQueryAddress(m, &net.UDPAddr{IP: ipv4MappedINET}); err != nil {
t.Fatal(err)
}
assertINET(t, m.GetSocketFamily(), m.GetQueryAddress())
})
t.Run("query/tcp", func(t *testing.T) {
m := new(tap.Message)
if err := SetQueryAddress(m, &net.TCPAddr{IP: ipv4MappedINET}); err != nil {
t.Fatal(err)
}
assertINET(t, m.GetSocketFamily(), m.GetQueryAddress())
})
t.Run("response/udp", func(t *testing.T) {
m := new(tap.Message)
if err := SetResponseAddress(m, &net.UDPAddr{IP: ipv4MappedINET}); err != nil {
t.Fatal(err)
}
assertINET(t, m.GetSocketFamily(), m.GetResponseAddress())
})
t.Run("response/tcp", func(t *testing.T) {
m := new(tap.Message)
if err := SetResponseAddress(m, &net.TCPAddr{IP: ipv4MappedINET}); err != nil {
t.Fatal(err)
}
assertINET(t, m.GetSocketFamily(), m.GetResponseAddress())
})
}
// Native IPv4 addresses keep SocketFamily INET and a 4-octet address.
func TestSetAddressNativeIPv4(t *testing.T) {
m := new(tap.Message)
if err := SetQueryAddress(m, &net.UDPAddr{IP: net.IP{192, 0, 2, 1}}); err != nil {
t.Fatal(err)
}
if m.GetSocketFamily() != tap.SocketFamily_INET {
t.Errorf("SocketFamily = %v, want INET", m.GetSocketFamily())
}
if got := len(m.GetQueryAddress()); got != 4 {
t.Errorf("address length = %d, want 4 octets for INET", got)
}
}
// Genuine IPv6 addresses keep SocketFamily INET6 and a 16-octet address.
func TestSetAddressNativeIPv6(t *testing.T) {
m := new(tap.Message)
if err := SetQueryAddress(m, &net.UDPAddr{IP: net.ParseIP("2001:db8::1")}); err != nil {
t.Fatal(err)
}
if m.GetSocketFamily() != tap.SocketFamily_INET6 {
t.Errorf("SocketFamily = %v, want INET6", m.GetSocketFamily())
}
if got := len(m.GetQueryAddress()); got != 16 {
t.Errorf("address length = %d, want 16 octets for INET6", got)
}
}