diff --git a/opts/hosts.go b/opts/hosts.go index dcbbb7e78166..79634d1d1d90 100644 --- a/opts/hosts.go +++ b/opts/hosts.go @@ -123,8 +123,13 @@ func ParseTCPAddr(tryAddr string, defaultAddr string) (string, error) { } host, port, err := net.SplitHostPort(u.Host) if err != nil { - // try port addition once - host, port, err = net.SplitHostPort(net.JoinHostPort(u.Host, defaultPort)) + // try port addition once; JoinHostPort adds its own brackets around + // IPv6 literals, so strip the ones url.Parse left on u.Host. + bare := u.Host + if len(bare) > 1 && bare[0] == '[' && bare[len(bare)-1] == ']' { + bare = bare[1 : len(bare)-1] + } + host, port, err = net.SplitHostPort(net.JoinHostPort(bare, defaultPort)) } if err != nil { return "", fmt.Errorf("invalid bind address format: %s", tryAddr) diff --git a/opts/hosts_test.go b/opts/hosts_test.go index 28f4eb6fab9e..fc427294c74c 100644 --- a/opts/hosts_test.go +++ b/opts/hosts_test.go @@ -66,6 +66,8 @@ func TestParseDockerDaemonHost(t *testing.T) { "0.0.0.1:": "tcp://0.0.0.1:2375", "0.0.0.1:5555": "tcp://0.0.0.1:5555", "0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path", + "[::1]": "tcp://[::1]:2375", + "[0:0:0:0:0:0:0:1]": "tcp://[0:0:0:0:0:0:0:1]:2375", "[::1]:": "tcp://[::1]:2375", "[::1]:5555/path": "tcp://[::1]:5555/path", "[0:0:0:0:0:0:0:1]:": "tcp://[0:0:0:0:0:0:0:1]:2375", @@ -113,6 +115,8 @@ func TestParseTCP(t *testing.T) { ":6666/path": "tcp://127.0.0.1:6666/path", "tcp://:7777": "tcp://127.0.0.1:7777", "tcp://:7777/path": "tcp://127.0.0.1:7777/path", + "[::1]": "tcp://[::1]:2376", + "[::1]/path": "tcp://[::1]:2376/path", "[::1]:": "tcp://[::1]:2376", "[::1]:5555": "tcp://[::1]:5555", "[::1]:5555/path": "tcp://[::1]:5555/path",