Browse Source

Merge pull request #16950 from cpuguy83/support_ipv6_in_host_parser

Allow API to bind to ipv6 addresses
Antonio Murdaca 9 years ago
parent
commit
4fc97e40c9
2 changed files with 46 additions and 22 deletions
  1. 18 10
      pkg/parsers/parsers.go
  2. 28 12
      pkg/parsers/parsers_test.go

+ 18 - 10
pkg/parsers/parsers.go

@@ -5,6 +5,7 @@ package parsers
 
 import (
 	"fmt"
+	"net"
 	"net/url"
 	"path"
 	"runtime"
@@ -74,26 +75,33 @@ func ParseTCPAddr(tryAddr string, defaultAddr string) (string, error) {
 	if err != nil {
 		return "", err
 	}
-	hostParts := strings.Split(u.Host, ":")
-	if len(hostParts) != 2 {
+
+	host, port, err := net.SplitHostPort(u.Host)
+	if err != nil {
 		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
 	}
-	defaults := strings.Split(defaultAddr, ":")
-	if len(defaults) != 3 {
-		return "", fmt.Errorf("Invalid defaults address format: %s", defaultAddr)
+
+	defaultAddr = strings.TrimPrefix(defaultAddr, "tcp://")
+	defaultHost, defaultPort, err := net.SplitHostPort(defaultAddr)
+	if err != nil {
+		return "", err
 	}
 
-	host := hostParts[0]
 	if host == "" {
-		host = strings.TrimPrefix(defaults[1], "//")
+		host = defaultHost
 	}
-	if hostParts[1] == "" {
-		hostParts[1] = defaults[2]
+	if port == "" {
+		port = defaultPort
 	}
-	p, err := strconv.Atoi(hostParts[1])
+	p, err := strconv.Atoi(port)
 	if err != nil && p == 0 {
 		return "", fmt.Errorf("Invalid bind address format: %s", tryAddr)
 	}
+
+	if net.ParseIP(host).To4() == nil && strings.Contains(host, ":") {
+		// This is either an ipv6 address
+		host = "[" + host + "]"
+	}
 	return fmt.Sprintf("tcp://%s:%d%s", host, p, u.Path), nil
 }
 

+ 28 - 12
pkg/parsers/parsers_test.go

@@ -28,9 +28,13 @@ func TestParseDockerDaemonHost(t *testing.T) {
 		"fd":   "Invalid bind address format: fd",
 	}
 	valids := map[string]string{
-		"0.0.0.1:":                "tcp://0.0.0.1:2376",
-		"0.0.0.1:5555":            "tcp://0.0.0.1:5555",
-		"0.0.0.1:5555/path":       "tcp://0.0.0.1:5555/path",
+		"0.0.0.1:":                    "tcp://0.0.0.1:2376",
+		"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]:2376",
+		"[::1]:5555/path":             "tcp://[::1]:5555/path",
+		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2376",
+		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
 		":6666":                   "tcp://127.0.0.1:6666",
 		":6666/path":              "tcp://127.0.0.1:6666/path",
 		"":                        defaultHOST,
@@ -44,6 +48,9 @@ func TestParseDockerDaemonHost(t *testing.T) {
 		"unix://":                 "unix:///var/run/docker.sock",
 		"fd://":                   "fd://",
 		"fd://something":          "fd://something",
+		"localhost:":              "tcp://localhost:2376",
+		"localhost:5555":          "tcp://localhost:5555",
+		"localhost:5555/path":     "tcp://localhost:5555/path",
 	}
 	for invalidAddr, expectedError := range invalids {
 		if addr, err := ParseDockerDaemonHost(defaultHTTPHost, defaultUnix, invalidAddr); err == nil || err.Error() != expectedError {
@@ -69,15 +76,24 @@ func TestParseTCP(t *testing.T) {
 		"udp://127.0.0.1:2375": "Invalid proto, expected tcp: udp://127.0.0.1:2375",
 	}
 	valids := map[string]string{
-		"":                  defaultHTTPHost,
-		"tcp://":            defaultHTTPHost,
-		"0.0.0.1:":          "tcp://0.0.0.1:2376",
-		"0.0.0.1:5555":      "tcp://0.0.0.1:5555",
-		"0.0.0.1:5555/path": "tcp://0.0.0.1:5555/path",
-		":6666":             "tcp://127.0.0.1:6666",
-		":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",
+		"":                            defaultHTTPHost,
+		"tcp://":                      defaultHTTPHost,
+		"0.0.0.1:":                    "tcp://0.0.0.1:2376",
+		"0.0.0.1:5555":                "tcp://0.0.0.1:5555",
+		"0.0.0.1:5555/path":           "tcp://0.0.0.1:5555/path",
+		":6666":                       "tcp://127.0.0.1:6666",
+		":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]:5555":                  "tcp://[::1]:5555",
+		"[::1]:5555/path":             "tcp://[::1]:5555/path",
+		"[0:0:0:0:0:0:0:1]:":          "tcp://[0:0:0:0:0:0:0:1]:2376",
+		"[0:0:0:0:0:0:0:1]:5555":      "tcp://[0:0:0:0:0:0:0:1]:5555",
+		"[0:0:0:0:0:0:0:1]:5555/path": "tcp://[0:0:0:0:0:0:0:1]:5555/path",
+		"localhost:":                  "tcp://localhost:2376",
+		"localhost:5555":              "tcp://localhost:5555",
+		"localhost:5555/path":         "tcp://localhost:5555/path",
 	}
 	for invalidAddr, expectedError := range invalids {
 		if addr, err := ParseTCPAddr(invalidAddr, defaultHTTPHost); err == nil || err.Error() != expectedError {