From a82bfb41f2fa8122da0aeea203f441318f61de3a Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 22 Sep 2026 17:58:50 +0200 Subject: [PATCH] Leave an IPv6 loopback mapping out of what a container publishes, reading ports from the end (hq ADR 0100) --- internal/catalogue/adoption.go | 18 +++++------------- internal/catalogue/adoption_test.go | 12 ++++++++++++ 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/internal/catalogue/adoption.go b/internal/catalogue/adoption.go index c165944..7b8c827 100644 --- a/internal/catalogue/adoption.go +++ b/internal/catalogue/adoption.go @@ -123,22 +123,14 @@ func Published(resources []map[string]any) map[string]map[int]int { protocol := "tcp" if cut := strings.LastIndex(written, "/"); cut >= 0 { protocol = written[cut+1:] - written = written[:cut] } - parts := strings.Split(written, ":") - if len(parts) < 2 { + // Indexed from the end, so an IPv6 address's own colons never shift the ports. + outer, inner, address, ok := mapping(written) + if !ok { continue } - if len(parts) == 3 && (parts[0] == "127.0.0.1" || parts[0] == "localhost" || - parts[0] == "[::1]") { - continue - } - outer, err := strconv.Atoi(parts[len(parts)-2]) - if err != nil { - continue - } - inner, err := strconv.Atoi(parts[len(parts)-1]) - if err != nil { + switch strings.Trim(address, "[]") { + case "127.0.0.1", "localhost", "::1": continue } if out[protocol] == nil { diff --git a/internal/catalogue/adoption_test.go b/internal/catalogue/adoption_test.go index 01aa720..da2dc78 100644 --- a/internal/catalogue/adoption_test.go +++ b/internal/catalogue/adoption_test.go @@ -336,3 +336,15 @@ func TestTheGuardIsDerivedFromTakenModulesOnly(t *testing.T) { t.Fatalf("the guard does not follow the given ports:\n%s", got) } } + +// A mapping bound to loopback is not published to anything off the machine — in either address +// family — and an address's own colons never shift the ports. +func TestPublishedLeavesOutLoopbackInBothFamilies(t *testing.T) { + got := Published([]map[string]any{{"type": "container", "ports": []any{ + "127.0.0.1:15672:15672", "[::1]:8080:80", "localhost:9090:90", + "[::]:8443:443", "0.0.0.0:5000:5000", "5353:53/udp"}}}) + want := map[string]map[int]int{"tcp": {8443: 443, 5000: 5000}, "udp": {5353: 53}} + if !reflect.DeepEqual(got, want) { + t.Fatalf("published is %v, want %v", got, want) + } +}