Skip to content

Commit ced0646

Browse files
danpbradfitz
authored andcommitted
net: make DNSError.Temporary return true on SERVFAIL
Fixes #8434 Change-Id: I323222b4160f3aba35cac1de7f6df93c524b72ec Reviewed-on: https://go-review.googlesource.com/14169 Reviewed-by: Brad Fitzpatrick <[email protected]> Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]>
1 parent 6fd82d8 commit ced0646

File tree

3 files changed

+38
-7
lines changed

3 files changed

+38
-7
lines changed

src/net/dnsclient.go

+7-2
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,13 @@ func answer(name, server string, dns *dnsMsg, qtype uint16) (cname string, addrs
4747
// None of the error codes make sense
4848
// for the query we sent. If we didn't get
4949
// a name error and we didn't get success,
50-
// the server is behaving incorrectly.
51-
return "", nil, &DNSError{Err: "server misbehaving", Name: name, Server: server}
50+
// the server is behaving incorrectly or
51+
// having temporary trouble.
52+
err := &DNSError{Err: "server misbehaving", Name: name, Server: server}
53+
if dns.rcode == dnsRcodeServerFailure {
54+
err.IsTemporary = true
55+
}
56+
return "", nil, err
5257
}
5358

5459
// Look for the name.

src/net/dnsclient_test.go

+25
Original file line numberDiff line numberDiff line change
@@ -67,3 +67,28 @@ func testWeighting(t *testing.T, margin float64) {
6767
func TestWeighting(t *testing.T) {
6868
testWeighting(t, 0.05)
6969
}
70+
71+
// Issue 8434: verify that Temporary returns true on an error when rcode
72+
// is SERVFAIL
73+
func TestIssue8434(t *testing.T) {
74+
msg := &dnsMsg{
75+
dnsMsgHdr: dnsMsgHdr{
76+
rcode: dnsRcodeServerFailure,
77+
},
78+
}
79+
80+
_, _, err := answer("golang.org", "foo:53", msg, uint16(dnsTypeSRV))
81+
if err == nil {
82+
t.Fatal("expected an error")
83+
}
84+
if ne, ok := err.(Error); !ok {
85+
t.Fatalf("err = %#v; wanted something supporting net.Error", err)
86+
} else if !ne.Temporary() {
87+
t.Fatalf("Temporary = false for err = %#v; want Temporary == true", err)
88+
}
89+
if de, ok := err.(*DNSError); !ok {
90+
t.Fatalf("err = %#v; wanted a *net.DNSError", err)
91+
} else if !de.IsTemporary {
92+
t.Fatalf("IsTemporary = false for err = %#v; want IsTemporary == true", err)
93+
}
94+
}

src/net/net.go

+6-5
Original file line numberDiff line numberDiff line change
@@ -520,10 +520,11 @@ var (
520520

521521
// DNSError represents a DNS lookup error.
522522
type DNSError struct {
523-
Err string // description of the error
524-
Name string // name looked for
525-
Server string // server used
526-
IsTimeout bool // if true, timed out; not all timeouts set this
523+
Err string // description of the error
524+
Name string // name looked for
525+
Server string // server used
526+
IsTimeout bool // if true, timed out; not all timeouts set this
527+
IsTemporary bool // if true, error is temporary; not all errors set this
527528
}
528529

529530
func (e *DNSError) Error() string {
@@ -546,7 +547,7 @@ func (e *DNSError) Timeout() bool { return e.IsTimeout }
546547
// Temporary reports whether the DNS error is known to be temporary.
547548
// This is not always known; a DNS lookup may fail due to a temporary
548549
// error and return a DNSError for which Temporary returns false.
549-
func (e *DNSError) Temporary() bool { return e.IsTimeout }
550+
func (e *DNSError) Temporary() bool { return e.IsTimeout || e.IsTemporary }
550551

551552
type writerOnly struct {
552553
io.Writer

0 commit comments

Comments
 (0)