test(06-08): add failing transition address regressions

- Cover private and public IPv4 embeddings across NAT64 and 6to4
- Exercise unsafe transition literals through the production dial control
- Require classifier-owned IPv4-mapped normalization
This commit is contained in:
Jakub Zych
2026-09-20 17:15:57 +02:00
parent 3601a0ab09
commit 1cd76fcd95
2 changed files with 62 additions and 7 deletions

View File

@@ -95,6 +95,36 @@ func TestFetchPrivateIPBlockedInBothModes(t *testing.T) {
})
}
func TestDialControlRejectsUnsafeIPv6Transitions(t *testing.T) {
tests := []struct {
name string
ip string
}{
{name: "nat64 well-known loopback", ip: "64:ff9b::7f00:1"},
{name: "nat64 well-known rfc1918", ip: "64:ff9b::a00:1"},
{name: "nat64 well-known metadata", ip: "64:ff9b::a9fe:a9fe"},
{name: "nat64 local-use loopback", ip: "64:ff9b:1:7f00:0:100::"},
{name: "nat64 local-use rfc1918", ip: "64:ff9b:1:a00:0:100::"},
{name: "nat64 local-use metadata", ip: "64:ff9b:1:a9fe:a9:fe00::"},
{name: "6to4 loopback", ip: "2002:7f00:1::"},
{name: "6to4 rfc1918", ip: "2002:a00:1::"},
{name: "6to4 metadata", ip: "2002:a9fe:a9fe::"},
}
control := dialControl(Policy{Mode: PublicOnlyMode})
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := control("tcp6", "["+tt.ip+"]:443", nil)
if !errors.Is(err, errPrivateIP) {
t.Fatalf("dialControl(%s) error = %v, want errPrivateIP", tt.ip, err)
}
if got := mapTransportError(err).Reason; got != ReasonPrivateIP {
t.Fatalf("mapTransportError(%s) reason = %q, want %q", tt.ip, got, ReasonPrivateIP)
}
})
}
}
func TestFetchDoesNotFollowRedirect(t *testing.T) {
var followed atomic.Bool
mux := http.NewServeMux()