mirror of https://github.com/grpc/grpc-go.git
dns: ignore TXT errors unless GRPC_GO_IGNORE_TXT_ERRORS=false (#3299)
This commit is contained in:
parent
cf9eb4f51c
commit
b91517cd56
|
@ -25,11 +25,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
prefix = "GRPC_GO_"
|
prefix = "GRPC_GO_"
|
||||||
retryStr = prefix + "RETRY"
|
retryStr = prefix + "RETRY"
|
||||||
|
txtErrIgnoreStr = prefix + "IGNORE_TXT_ERRORS"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on".
|
// Retry is set if retry is explicitly enabled via "GRPC_GO_RETRY=on".
|
||||||
Retry = strings.EqualFold(os.Getenv(retryStr), "on")
|
Retry = strings.EqualFold(os.Getenv(retryStr), "on")
|
||||||
|
// TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false").
|
||||||
|
TXTErrIgnore = !strings.EqualFold(os.Getenv(retryStr), "false")
|
||||||
)
|
)
|
||||||
|
|
|
@ -33,6 +33,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"google.golang.org/grpc/grpclog"
|
"google.golang.org/grpc/grpclog"
|
||||||
|
"google.golang.org/grpc/internal/envconfig"
|
||||||
"google.golang.org/grpc/internal/grpcrand"
|
"google.golang.org/grpc/internal/grpcrand"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
|
@ -278,6 +279,9 @@ func handleDNSError(err error, lookupType string) error {
|
||||||
func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult {
|
func (d *dnsResolver) lookupTXT() *serviceconfig.ParseResult {
|
||||||
ss, err := d.resolver.LookupTXT(d.ctx, txtPrefix+d.host)
|
ss, err := d.resolver.LookupTXT(d.ctx, txtPrefix+d.host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if envconfig.TXTErrIgnore {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if err = handleDNSError(err, "TXT"); err != nil {
|
if err = handleDNSError(err, "TXT"); err != nil {
|
||||||
return &serviceconfig.ParseResult{Err: err}
|
return &serviceconfig.ParseResult{Err: err}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"google.golang.org/grpc/internal/envconfig"
|
||||||
"google.golang.org/grpc/internal/leakcheck"
|
"google.golang.org/grpc/internal/leakcheck"
|
||||||
"google.golang.org/grpc/resolver"
|
"google.golang.org/grpc/resolver"
|
||||||
"google.golang.org/grpc/serviceconfig"
|
"google.golang.org/grpc/serviceconfig"
|
||||||
|
@ -830,7 +831,11 @@ func mutateTbl(target string) func() {
|
||||||
hostLookupTbl.tbl[target] = oldHostTblEntry
|
hostLookupTbl.tbl[target] = oldHostTblEntry
|
||||||
hostLookupTbl.Unlock()
|
hostLookupTbl.Unlock()
|
||||||
txtLookupTbl.Lock()
|
txtLookupTbl.Lock()
|
||||||
txtLookupTbl.tbl[txtPrefix+target] = oldTxtTblEntry
|
if len(oldTxtTblEntry) == 0 {
|
||||||
|
delete(txtLookupTbl.tbl, txtPrefix+target)
|
||||||
|
} else {
|
||||||
|
txtLookupTbl.tbl[txtPrefix+target] = oldTxtTblEntry
|
||||||
|
}
|
||||||
txtLookupTbl.Unlock()
|
txtLookupTbl.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1039,6 +1044,38 @@ func TestDisableServiceConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTXTError(t *testing.T) {
|
||||||
|
defer leakcheck.Check(t)
|
||||||
|
defer func(v bool) { envconfig.TXTErrIgnore = v }(envconfig.TXTErrIgnore)
|
||||||
|
for _, ignore := range []bool{false, true} {
|
||||||
|
envconfig.TXTErrIgnore = ignore
|
||||||
|
b := NewBuilder()
|
||||||
|
cc := &testClientConn{target: "ipv4.single.fake"} // has A records but not TXT records.
|
||||||
|
r, err := b.Build(resolver.Target{Endpoint: "ipv4.single.fake"}, cc, resolver.BuildOptions{})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("%v\n", err)
|
||||||
|
}
|
||||||
|
defer r.Close()
|
||||||
|
var cnt int
|
||||||
|
var state resolver.State
|
||||||
|
for i := 0; i < 2000; i++ {
|
||||||
|
state, cnt = cc.getState()
|
||||||
|
if cnt > 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
|
}
|
||||||
|
if cnt == 0 {
|
||||||
|
t.Fatalf("UpdateState not called after 2s; aborting")
|
||||||
|
}
|
||||||
|
if !ignore && (state.ServiceConfig == nil || state.ServiceConfig.Err == nil) {
|
||||||
|
t.Errorf("state.ServiceConfig = %v; want non-nil error", state.ServiceConfig)
|
||||||
|
} else if ignore && state.ServiceConfig != nil {
|
||||||
|
t.Errorf("state.ServiceConfig = %v; want nil", state.ServiceConfig)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDNSResolverRetry(t *testing.T) {
|
func TestDNSResolverRetry(t *testing.T) {
|
||||||
b := NewBuilder()
|
b := NewBuilder()
|
||||||
target := "ipv4.single.fake"
|
target := "ipv4.single.fake"
|
||||||
|
|
Loading…
Reference in New Issue