From c7e5424e7cfb27c83630b402731b49761eba6e36 Mon Sep 17 00:00:00 2001 From: Michael Wolf Date: Wed, 5 Aug 2026 21:10:34 -0700 Subject: [PATCH] Support IPv6 service endpoints in trace plugin (#8410) Use net.JoinHostPort rather than string concatenation to support both ipv4, ipv6, and hostname service endpoints for the trace plugin. Previously, ipv6 bind addresses in the coredns configuration would fail to be parsed, as the ipv6 address was not surrounded in brackets. Signed-off-by: Michael Wolf Closes #8409 Co-authored-by: Michael Wolf --- plugin/trace/setup.go | 3 ++- plugin/trace/setup_test.go | 54 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/plugin/trace/setup.go b/plugin/trace/setup.go index c5fb04aa5..c3b07ebb9 100644 --- a/plugin/trace/setup.go +++ b/plugin/trace/setup.go @@ -2,6 +2,7 @@ package trace import ( "fmt" + "net" "strconv" "strings" "time" @@ -38,7 +39,7 @@ func traceParse(c *caddy.Controller) (*trace, error) { cfg := dnsserver.GetConfig(c) if len(cfg.ListenHosts) > 0 && cfg.ListenHosts[0] != "" { - tr.serviceEndpoint = cfg.ListenHosts[0] + ":" + cfg.Port + tr.serviceEndpoint = net.JoinHostPort(cfg.ListenHosts[0], cfg.Port) } for c.Next() { // trace diff --git a/plugin/trace/setup_test.go b/plugin/trace/setup_test.go index 19f2d9acb..cfe444a4c 100644 --- a/plugin/trace/setup_test.go +++ b/plugin/trace/setup_test.go @@ -5,6 +5,7 @@ import ( "time" "github.com/coredns/caddy" + "github.com/coredns/coredns/core/dnsserver" ) func TestTraceParse(t *testing.T) { @@ -87,3 +88,56 @@ func TestTraceParse(t *testing.T) { } } } + +func TestParseServiceEndpoint(t *testing.T) { + tests := []struct { + name string + listenHosts []string + port string + expectedServiceEndpoint string + }{ + { + name: "IPv4 address", + listenHosts: []string{"127.0.0.1"}, + port: "8053", + expectedServiceEndpoint: "127.0.0.1:8053", + }, + { + name: "IPv6 address", + listenHosts: []string{"3d47:98c0:b113::3"}, + port: "8853", + expectedServiceEndpoint: "[3d47:98c0:b113::3]:8853", + }, + { + name: "Hostname", + listenHosts: []string{"localhost"}, + port: "8053", + expectedServiceEndpoint: "localhost:8053", + }, + { + name: "Multiple addresses", + listenHosts: []string{"3d47:98c0:b113::3", "127.0.0.1"}, + port: "8853", + expectedServiceEndpoint: "[3d47:98c0:b113::3]:8853", + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + c := caddy.NewTestController("dns", "trace") + cfg := dnsserver.GetConfig(c) + cfg.ListenHosts = tc.listenHosts + cfg.Port = tc.port + + tr, err := traceParse(c) + if err != nil { + t.Errorf("Error parsing test input: %s", err) + return + } + + if tr.serviceEndpoint != tc.expectedServiceEndpoint { + t.Errorf("Expected serviceEndpoint %s, got %s", tc.expectedServiceEndpoint, tr.serviceEndpoint) + } + }) + } +}