From f2de83684feee03e7e697c5860626e2251f8f7a2 Mon Sep 17 00:00:00 2001 From: Imanol-Mikel Barba Date: Wed, 5 May 2021 04:48:40 +0100 Subject: [PATCH] Adding IsNotFound to DNSError returned from cgo reverse resolution The UNIX cgo resolver code didn't set IsNotFound on the DNSError returned when the `getnameinfo` call used for reverse resolution in `cgoNameinfoPTR` returns `EAI_NONAME`. This diff sets IsNotFound to true in that case. EAI_NONAME is set by `getnameinfo` when the address resolution fails, and is defined in Solaris, OpenBSD, AIX, Darwin, Linux, NetBSD and DragonflyBSD according to online manpages. I have only tested on Darwin though. ``` $ ./all.bash [...] ALL TESTS PASSED ``` Then, I made a small go program to verify the behaviour: ``` package main import ( "fmt" "net" ) func main() { names, err := net.LookupAddr("::2") fmt.Printf("names: %+v\n", names) if dnsErr, ok := err.(*net.DNSError); ok { fmt.Printf("error: %+v\n", *dnsErr) } } ``` Before changes: ``` ./dnstest names: [] error: {Err:nodename nor servname provided, or not known Name:::2 Server: IsTimeout:false IsTemporary:false IsNotFound:false} ``` After changes: ``` $ ./dnstest names: [] error: {Err:no such host Name:::2 Server: IsTimeout:false IsTemporary:false IsNotFound:true} ``` --- src/net/cgo_unix.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go index 2ea86e074fb943..a9067c877b82d8 100644 --- a/src/net/cgo_unix.go +++ b/src/net/cgo_unix.go @@ -305,17 +305,21 @@ func cgoLookupAddrPTR(addr string, sa *C.struct_sockaddr, salen C.socklen_t) (na } } if gerrno != 0 { + isErrorNoSuchHost := false isTemporary := false switch gerrno { case C.EAI_SYSTEM: if err == nil { // see golang.org/issue/6232 err = syscall.EMFILE } + case C.EAI_NONAME: + err = errNoSuchHost + isErrorNoSuchHost = true default: err = addrinfoErrno(gerrno) isTemporary = addrinfoErrno(gerrno).Temporary() } - return nil, &DNSError{Err: err.Error(), Name: addr, IsTemporary: isTemporary} + return nil, &DNSError{Err: err.Error(), Name: addr, IsTemporary: isTemporary, IsNotFound: isErrorNoSuchHost} } for i := 0; i < len(b); i++ { if b[i] == 0 {