diff --git a/etcdmain/config_test.go b/etcdmain/config_test.go index fbda2d369..38c3ebb5f 100644 --- a/etcdmain/config_test.go +++ b/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() diff --git a/pkg/flags/flag.go b/pkg/flags/flag.go index bc0d7799d..3a281a262 100644 --- a/pkg/flags/flag.go +++ b/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) } diff --git a/pkg/flags/flag_test.go b/pkg/flags/flag_test.go index 678c59e0f..fcc2809f1 100644 --- a/pkg/flags/flag_test.go +++ b/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) diff --git a/pkg/flags/ipaddressport.go b/pkg/flags/ipaddressport.go index 1d5d79f74..b13818b6f 100644 --- a/pkg/flags/ipaddressport.go +++ b/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)) } diff --git a/pkg/flags/ipaddressport_test.go b/pkg/flags/ipaddressport_test.go index ad463b463..139d3759e 100644 --- a/pkg/flags/ipaddressport_test.go +++ b/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) + } } }