2 Commits
Author SHA1 Message Date
clawbot 11a6f5a60a Read a blocked_networks entry in the IPv4-mapped form as its IPv4 range (closes #301)
check / check (push) Canceled after 0s
The fetcher matches an IPv4-mapped address (::ffff:a.b.c.d) as the
IPv4 address it holds, so a blocked_networks entry written in that form
was accepted and matched nothing. Such an entry is now kept as the IPv4
range it covers: ::ffff:10.0.0.0/104 becomes 10.0.0.0/8. One shorter
than /96 covers more than IPv4 addresses and aborts startup naming the
setting. trusted_proxies shares the list parser and is unchanged.
README.md says both.

Model: opus-5-5
2026-10-19 00:31:43 +00:00
clawbot 9c47f11fd6 Test that a blocked_networks entry in the IPv4-mapped form is read as its IPv4 range
Two new tests, failing until the fix. Entries such as
::ffff:10.0.0.0/104 and ::ffff:0:0/96 must load as 10.0.0.0/8 and
0.0.0.0/0, since the fetcher matches an IPv4-mapped address as the IPv4
address it holds. An entry in that form shorter than /96, such as
::ffff:0:0/95, must abort startup naming blocked_networks.

Model: opus-5-5
2026-10-19 00:31:43 +00:00
@@ -92,25 +92,29 @@ func TestBlockedNetworksInvalidAbortsStartup(t *testing.T) {
// TestBlockedNetworksMappedEntryIsIPv4Range checks that an entry written in
// the IPv4-mapped form (::ffff:a.b.c.d) is kept as the IPv4 range it covers,
// since the fetcher matches an IPv4-mapped address as the IPv4 address it
// holds.
// holds. /96, the shortest such entry, covers every IPv4 address.
func TestBlockedNetworksMappedEntryIsIPv4Range(t *testing.T) {
t.Parallel()
yamlContent := signingKeyLine + `blocked_networks:
- "::ffff:10.0.0.0/104"
- "::ffff:0:0/96"
`
c, err := configFromYAML(t, yamlContent)
if err != nil {
t.Fatalf("an IPv4-mapped blocked_networks entry should load, got error: %v", err)
t.Fatalf("IPv4-mapped blocked_networks entries should load, got error: %v", err)
}
if len(c.BlockedNetworks) != 1 {
t.Fatalf("BlockedNetworks = %v, want 1 entry", c.BlockedNetworks)
want := []string{"10.0.0.0/8", "0.0.0.0/0"}
if len(c.BlockedNetworks) != len(want) {
t.Fatalf("BlockedNetworks = %v, want %d entries", c.BlockedNetworks, len(want))
}
if got := c.BlockedNetworks[0].String(); got != "10.0.0.0/8" {
t.Errorf("BlockedNetworks[0] = %q, want %q", got, "10.0.0.0/8")
for i, w := range want {
if got := c.BlockedNetworks[i].String(); got != w {
t.Errorf("BlockedNetworks[%d] = %q, want %q", i, got, w)
}
}
}
@@ -128,5 +132,12 @@ func TestBlockedNetworksMappedEntryShorterThan96AbortsStartup(t *testing.T) {
`,
wantErrSubstrings: []string{keyBlockedNetworks, "::ffff:0.0.0.0/80"},
},
{
name: "mapped-95",
yaml: signingKeyLine + `blocked_networks:
- "::ffff:0:0/95"
`,
wantErrSubstrings: []string{keyBlockedNetworks},
},
})
}