Browse Source

Merge pull request #2478 from kmeaw/master

Support IPv6 address for ETCD_ADDR and ETCD_PEER_ADDR
Yicheng Qin 10 years ago
parent
commit
f9ee8ecb3a

+ 2 - 2
etcdmain/config_test.go

@@ -157,9 +157,9 @@ func TestConfigParsingV1Flags(t *testing.T) {
 		"-addr=127.0.0.1:4001",
 	}
 	wcfg := NewConfig()
-	wcfg.lpurls = []url.URL{{Scheme: "http", Host: "0.0.0.0:7001"}}
+	wcfg.lpurls = []url.URL{{Scheme: "http", Host: "[::]:7001"}}
 	wcfg.apurls = []url.URL{{Scheme: "http", Host: "127.0.0.1:7001"}}
-	wcfg.lcurls = []url.URL{{Scheme: "http", Host: "0.0.0.0:4001"}}
+	wcfg.lcurls = []url.URL{{Scheme: "http", Host: "[::]:4001"}}
 	wcfg.acurls = []url.URL{{Scheme: "http", Host: "127.0.0.1:4001"}}
 
 	cfg := NewConfig()

+ 2 - 2
pkg/flags/flag.go

@@ -88,13 +88,13 @@ func SetFlagsFromEnv(fs *flag.FlagSet) error {
 // SetBindAddrFromAddr sets the value of bindAddr flag from the value
 // of addr flag. Both flags' Value must be of type IPAddressPort. If the
 // bindAddr flag is set and the addr flag is unset, it will set bindAddr to
-// 0.0.0.0:port of addr. Otherwise, it keeps the original values.
+// [::]:port of addr. Otherwise, it keeps the original values.
 func SetBindAddrFromAddr(fs *flag.FlagSet, bindAddrFlagName, addrFlagName string) {
 	if IsSet(fs, bindAddrFlagName) || !IsSet(fs, addrFlagName) {
 		return
 	}
 	addr := *fs.Lookup(addrFlagName).Value.(*IPAddressPort)
-	addr.IP = "0.0.0.0"
+	addr.IP = "::"
 	if err := fs.Set(bindAddrFlagName, addr.String()); err != nil {
 		log.Panicf("etcdmain: unexpected flags set error: %v", err)
 	}

+ 6 - 1
pkg/flags/flag_test.go

@@ -94,7 +94,7 @@ func TestSetBindAddrFromAddr(t *testing.T) {
 		// addr flag set
 		{
 			args:  []string{"-addr=192.0.3.17:4001"},
-			waddr: &IPAddressPort{IP: "0.0.0.0", Port: 4001},
+			waddr: &IPAddressPort{IP: "::", Port: 4001},
 		},
 		// bindAddr flag set
 		{
@@ -106,6 +106,11 @@ func TestSetBindAddrFromAddr(t *testing.T) {
 			args:  []string{"-bind-addr=127.0.0.1:4001", "-addr=192.0.3.17:4001"},
 			waddr: &IPAddressPort{IP: "127.0.0.1", Port: 4001},
 		},
+		// both addr flags set, IPv6
+		{
+			args:  []string{"-bind-addr=[2001:db8::4:9]:4001", "-addr=[2001:db8::4:f0]:4001"},
+			waddr: &IPAddressPort{IP: "2001:db8::4:9", Port: 4001},
+		},
 	}
 	for i, tt := range tests {
 		fs := flag.NewFlagSet("test", flag.PanicOnError)

+ 7 - 8
pkg/flags/ipaddressport.go

@@ -16,7 +16,6 @@ package flags
 
 import (
 	"errors"
-	"fmt"
 	"net"
 	"strconv"
 	"strings"
@@ -32,26 +31,26 @@ type IPAddressPort struct {
 func (a *IPAddressPort) Set(arg string) error {
 	arg = strings.TrimSpace(arg)
 
-	parts := strings.SplitN(arg, ":", 2)
-	if len(parts) != 2 {
-		return errors.New("bad format in address specification")
+	host, portStr, err := net.SplitHostPort(arg)
+	if err != nil {
+		return err
 	}
 
-	if net.ParseIP(parts[0]) == nil {
+	if net.ParseIP(host) == nil {
 		return errors.New("bad IP in address specification")
 	}
 
-	port, err := strconv.Atoi(parts[1])
+	port, err := strconv.Atoi(portStr)
 	if err != nil {
 		return errors.New("bad port in address specification")
 	}
 
-	a.IP = parts[0]
+	a.IP = host
 	a.Port = port
 
 	return nil
 }
 
 func (a *IPAddressPort) String() string {
-	return fmt.Sprintf("%s:%d", a.IP, a.Port)
+	return net.JoinHostPort(a.IP, strconv.Itoa(a.Port))
 }

+ 16 - 7
pkg/flags/ipaddressport_test.go

@@ -22,6 +22,7 @@ func TestIPAddressPortSet(t *testing.T) {
 	pass := []string{
 		"1.2.3.4:8080",
 		"10.1.1.1:80",
+		"[2001:db8::1]:8080",
 	}
 
 	fail := []string{
@@ -40,6 +41,8 @@ func TestIPAddressPortSet(t *testing.T) {
 		"234#$",
 		"file://foo/bar",
 		"http://hello",
+		"2001:db8::1",
+		"2001:db8::1:1",
 	}
 
 	for i, tt := range pass {
@@ -58,14 +61,20 @@ func TestIPAddressPortSet(t *testing.T) {
 }
 
 func TestIPAddressPortString(t *testing.T) {
-	f := &IPAddressPort{}
-	if err := f.Set("127.0.0.1:4001"); err != nil {
-		t.Fatalf("unexpected error: %v", err)
+	addresses := []string{
+		"[2001:db8::1:1234]:4001",
+		"127.0.0.1:4001",
 	}
+	for i, tt := range addresses {
+		f := &IPAddressPort{}
+		if err := f.Set(tt); err != nil {
+			t.Errorf("#%d: unexpected error: %v", i, err)
+		}
 
-	want := "127.0.0.1:4001"
-	got := f.String()
-	if want != got {
-		t.Fatalf("IPAddressPort.String() value should be %q, got %q", want, got)
+		want := tt
+		got := f.String()
+		if want != got {
+			t.Errorf("#%d: IPAddressPort.String() value should be %q, got %q", i, want, got)
+		}
 	}
 }