From a3892221eea4804f58ce83934c91964e83f4f30c Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Mon, 30 Mar 2015 13:30:40 -0700 Subject: [PATCH 1/3] *: stop using resolved tcp addr We start to resolve host into tcp addrs since we generate tcp based initial-cluster during srv discovery. However it creates problems around tls and cluster verification. The srv discovery only needs to use resolved the tcp addr to find the local node. It does not have to resolve everything and use the resolved addrs. This fixes #2488 and #2226 --- discovery/srv.go | 4 ++-- etcdmain/config.go | 10 ---------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/discovery/srv.go b/discovery/srv.go index da82bbc37..86365f065 100644 --- a/discovery/srv.go +++ b/discovery/srv.go @@ -68,8 +68,8 @@ func SRVGetCluster(name, dns string, defaultToken string, apurls types.URLs) (st n = fmt.Sprintf("%d", tempName) tempName += 1 } - stringParts = append(stringParts, fmt.Sprintf("%s=%s%s", n, prefix, tcpAddr.String())) - log.Printf("discovery: Got bootstrap from DNS for %s at host %s to %s%s", service, host, prefix, tcpAddr.String()) + stringParts = append(stringParts, fmt.Sprintf("%s=%s%s", n, prefix, host)) + log.Printf("discovery: Got bootstrap from DNS for %s at %s%s", service, prefix, host) } return nil } diff --git a/etcdmain/config.go b/etcdmain/config.go index 71d693810..6c209271b 100644 --- a/etcdmain/config.go +++ b/etcdmain/config.go @@ -15,7 +15,6 @@ package etcdmain import ( - "errors" "flag" "fmt" "log" @@ -26,7 +25,6 @@ import ( "github.com/coreos/etcd/etcdserver" "github.com/coreos/etcd/pkg/cors" "github.com/coreos/etcd/pkg/flags" - "github.com/coreos/etcd/pkg/netutil" "github.com/coreos/etcd/pkg/transport" "github.com/coreos/etcd/version" ) @@ -260,10 +258,6 @@ func (cfg *config) Parse(arguments []string) error { return err } - if err := cfg.resolveUrls(); err != nil { - return errors.New("cannot resolve DNS hostnames.") - } - if 5*cfg.TickMs > cfg.ElectionMs { return fmt.Errorf("-election-timeout[%vms] should be at least as 5 times as -heartbeat-interval[%vms]", cfg.ElectionMs, cfg.TickMs) } @@ -279,10 +273,6 @@ func initialClusterFromName(name string) string { return fmt.Sprintf("%s=http://localhost:2380,%s=http://localhost:7001", n, n) } -func (cfg *config) resolveUrls() error { - return netutil.ResolveTCPAddrs(cfg.lpurls, cfg.apurls, cfg.lcurls, cfg.acurls) -} - func (cfg config) isNewCluster() bool { return cfg.clusterState.String() == clusterStateFlagNew } func (cfg config) isProxy() bool { return cfg.proxy.String() != proxyFlagOff } func (cfg config) isReadonlyProxy() bool { return cfg.proxy.String() == proxyFlagReadonly } From f5d4c86153e2063de4499a17b952cbed325a8f42 Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Tue, 31 Mar 2015 10:39:46 -0700 Subject: [PATCH 2/3] discovery: add a test case for srv During srv discovery, it should try to match local member with resolved addr and return unresolved hostnames for the cluster. --- discovery/srv.go | 7 ++++--- discovery/srv_test.go | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/discovery/srv.go b/discovery/srv.go index 86365f065..63c7deabc 100644 --- a/discovery/srv.go +++ b/discovery/srv.go @@ -25,7 +25,8 @@ import ( var ( // indirection for testing - lookupSRV = net.LookupSRV + lookupSRV = net.LookupSRV + resolveTCPAddr = net.ResolveTCPAddr ) // TODO(barakmich): Currently ignores priority and weight (as they don't make as much sense for a bootstrap) @@ -38,7 +39,7 @@ func SRVGetCluster(name, dns string, defaultToken string, apurls types.URLs) (st // First, resolve the apurls for _, url := range apurls { - tcpAddr, err := net.ResolveTCPAddr("tcp", url.Host) + tcpAddr, err := resolveTCPAddr("tcp", url.Host) if err != nil { log.Printf("discovery: Couldn't resolve host %s during SRV discovery", url.Host) return "", "", err @@ -53,7 +54,7 @@ func SRVGetCluster(name, dns string, defaultToken string, apurls types.URLs) (st } for _, srv := range addrs { host := net.JoinHostPort(srv.Target, fmt.Sprintf("%d", srv.Port)) - tcpAddr, err := net.ResolveTCPAddr("tcp", host) + tcpAddr, err := resolveTCPAddr("tcp", host) if err != nil { log.Printf("discovery: Couldn't resolve host %s during SRV discovery", host) continue diff --git a/discovery/srv_test.go b/discovery/srv_test.go index f523adb7b..de44682fd 100644 --- a/discovery/srv_test.go +++ b/discovery/srv_test.go @@ -23,19 +23,26 @@ import ( ) func TestSRVGetCluster(t *testing.T) { - defer func() { lookupSRV = net.LookupSRV }() + defer func() { + lookupSRV = net.LookupSRV + resolveTCPAddr = net.ResolveTCPAddr + }() name := "dnsClusterTest" tests := []struct { withSSL []*net.SRV withoutSSL []*net.SRV urls []string - expected string + dns map[string]string + + expected string }{ { []*net.SRV{}, []*net.SRV{}, nil, + nil, + "", }, { @@ -46,6 +53,8 @@ func TestSRVGetCluster(t *testing.T) { }, []*net.SRV{}, nil, + nil, + "0=https://10.0.0.1:2480,1=https://10.0.0.2:2480,2=https://10.0.0.3:2480", }, { @@ -58,6 +67,7 @@ func TestSRVGetCluster(t *testing.T) { &net.SRV{Target: "10.0.0.1", Port: 2380}, }, nil, + nil, "0=https://10.0.0.1:2480,1=https://10.0.0.2:2480,2=https://10.0.0.3:2480,3=http://10.0.0.1:2380", }, { @@ -70,8 +80,22 @@ func TestSRVGetCluster(t *testing.T) { &net.SRV{Target: "10.0.0.1", Port: 2380}, }, []string{"https://10.0.0.1:2480"}, + nil, "dnsClusterTest=https://10.0.0.1:2480,0=https://10.0.0.2:2480,1=https://10.0.0.3:2480,2=http://10.0.0.1:2380", }, + // matching local member with resolved addr and return unresolved hostnames + { + []*net.SRV{ + &net.SRV{Target: "1.example.com.", Port: 2480}, + &net.SRV{Target: "2.example.com.", Port: 2480}, + &net.SRV{Target: "3.example.com.", Port: 2480}, + }, + nil, + []string{"https://10.0.0.1:2480"}, + map[string]string{"1.example.com:2480": "10.0.0.1:2480", "2.example.com:2480": "10.0.0.2:2480", "3.example.com:2480": "10.0.0.3:2480"}, + + "dnsClusterTest=https://1.example.com:2480,0=https://2.example.com:2480,1=https://3.example.com:2480", + }, } for i, tt := range tests { @@ -84,6 +108,12 @@ func TestSRVGetCluster(t *testing.T) { } return "", nil, errors.New("Unkown service in mock") } + resolveTCPAddr = func(network, addr string) (*net.TCPAddr, error) { + if tt.dns == nil || tt.dns[addr] == "" { + return net.ResolveTCPAddr(network, addr) + } + return net.ResolveTCPAddr(network, tt.dns[addr]) + } urls := testutil.MustNewURLs(t, tt.urls) str, token, err := SRVGetCluster(name, "example.com", "token", urls) if err != nil { From 9b65ff6959ef59330a004aa3f7c3a41e5795253e Mon Sep 17 00:00:00 2001 From: Xiang Li Date: Thu, 9 Apr 2015 07:08:22 -0700 Subject: [PATCH 3/3] discovery: drop trailing . from srv target --- discovery/srv.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/discovery/srv.go b/discovery/srv.go index 63c7deabc..6ad79feeb 100644 --- a/discovery/srv.go +++ b/discovery/srv.go @@ -53,7 +53,8 @@ func SRVGetCluster(name, dns string, defaultToken string, apurls types.URLs) (st return err } for _, srv := range addrs { - host := net.JoinHostPort(srv.Target, fmt.Sprintf("%d", srv.Port)) + target := strings.TrimSuffix(srv.Target, ".") + host := net.JoinHostPort(target, fmt.Sprintf("%d", srv.Port)) tcpAddr, err := resolveTCPAddr("tcp", host) if err != nil { log.Printf("discovery: Couldn't resolve host %s during SRV discovery", host)