test(06-04): add failing test for private/reserved IP table

- Table-driven cases port PHP PRIVATE_V4_CIDRS/PRIVATE_V6_PREFIXES
- Document Unmap() as the caller responsibility for v4-mapped literals
This commit is contained in:
Jakub Zych
2026-09-19 18:57:18 +02:00
parent ecab09c37a
commit f7e7ca7fa3

54
fetchguard/ip_test.go Normal file
View File

@@ -0,0 +1,54 @@
package fetchguard
import (
"net/netip"
"testing"
)
func TestIsReservedOrPrivate(t *testing.T) {
tests := []struct {
name string
ip string
want bool
// unmap documents that IPv4-mapped IPv6 literals are the CALLER's
// responsibility to Unmap() before classification (fetch.go dial hook).
unmap bool
}{
{name: "loopback v4", ip: "127.0.0.1", want: true},
{name: "rfc1918 10/8", ip: "10.1.2.3", want: true},
{name: "rfc1918 172.16/12 start", ip: "172.16.0.1", want: true},
{name: "rfc1918 172.16/12 end", ip: "172.31.255.255", want: true},
{name: "rfc1918 192.168/16", ip: "192.168.1.1", want: true},
{name: "cloud metadata link-local", ip: "169.254.169.254", want: true},
{name: "cgnat 100.64/10", ip: "100.64.0.1", want: true},
{name: "this-network 0.0.0.0/8", ip: "0.0.0.1", want: true},
{name: "public 8.8.8.8", ip: "8.8.8.8", want: false},
{name: "public 1.1.1.1", ip: "1.1.1.1", want: false},
{name: "public 93.184.216.34", ip: "93.184.216.34", want: false},
{name: "loopback v6", ip: "::1", want: true},
{name: "link-local v6", ip: "fe80::1", want: true},
{name: "unique-local v6", ip: "fc00::1", want: true},
{name: "public v6", ip: "2606:4700:4700::1111", want: false},
{name: "v4-mapped metadata after Unmap", ip: "::ffff:169.254.169.254", want: true, unmap: true},
{name: "multicast v4", ip: "224.0.0.1", want: true},
{name: "unspecified v4", ip: "0.0.0.0", want: true},
{name: "just below 172.16.0.0/12", ip: "172.15.255.255", want: false},
{name: "just above 172.16.0.0/12", ip: "172.32.0.0", want: false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
addr, err := netip.ParseAddr(tt.ip)
if err != nil {
t.Fatalf("ParseAddr(%q): %v", tt.ip, err)
}
if tt.unmap {
addr = addr.Unmap()
}
got := isReservedOrPrivate(addr)
if got != tt.want {
t.Fatalf("isReservedOrPrivate(%s) = %v, want %v", addr, got, tt.want)
}
})
}
}