From 0662a181e8f60ee74baba780ebce514cb968391e Mon Sep 17 00:00:00 2001 From: Tim Gross Date: Tue, 17 Dec 2024 20:49:40 +0000 Subject: [PATCH] backport of commit 30e57c39b03619143fbf122598440113774f0f4e --- .changelog/24649.txt | 3 +++ client/rpc.go | 20 ++++++++++++++++++-- client/rpc_test.go | 12 +++++++++--- 3 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 .changelog/24649.txt diff --git a/.changelog/24649.txt b/.changelog/24649.txt new file mode 100644 index 00000000000..1b1e4701b18 --- /dev/null +++ b/.changelog/24649.txt @@ -0,0 +1,3 @@ +```release-note:bug +discovery: Fixed a bug where IPv6 addresses would not be accepted from cloud autojoin +``` diff --git a/client/rpc.go b/client/rpc.go index 5427bb76254..bfdf051c121 100644 --- a/client/rpc.go +++ b/client/rpc.go @@ -445,14 +445,30 @@ func (c *Client) handleStreamingConn(conn net.Conn) { // net.Addr or an error. func resolveServer(s string) (net.Addr, error) { const defaultClientPort = "4647" // default client RPC port + host, port, err := net.SplitHostPort(s) if err != nil { - if strings.Contains(err.Error(), "missing port") { + switch { + case strings.Contains(err.Error(), "missing port"): // with IPv6 addresses the `host` variable will have brackets // removed, so send the original value thru again with only the // correct port suffix return resolveServer(s + ":" + defaultClientPort) - } else { + case strings.Contains(err.Error(), "too many colons"): + // note: we expect IPv6 address strings to be RFC5952 compliant to + // disambiguate port numbers from the address. Because the port number + // is typically 4 decimal digits, the same size as an IPv6 address + // segment, there's no way to disambiguate this. See + // https://www.rfc-editor.org/rfc/rfc5952 + ip := net.ParseIP(s) + if ip.To4() == nil && ip.To16() != nil { + if !strings.HasPrefix(s, "[") { + return resolveServer("[" + s + "]:" + defaultClientPort) + } + } + return nil, err + + default: return nil, err } } else if port == "" { diff --git a/client/rpc_test.go b/client/rpc_test.go index 3762f6108ca..5b4e26b1116 100644 --- a/client/rpc_test.go +++ b/client/rpc_test.go @@ -130,9 +130,15 @@ func Test_resolveServer(t *testing.T) { expectErr string }{ { - name: "ipv6 no brackets", - addr: "2001:db8::1", - expectErr: "address 2001:db8::1: too many colons in address", + name: "ipv6 no brackets", + addr: "2001:db8::1", + expect: "[2001:db8::1]:4647", + }, + { + // expected bad result + name: "ambiguous ipv6 no brackets with port", + addr: "2001:db8::1:4647", + expect: "[2001:db8::1:4647]:4647", }, { name: "ipv6 no port",