package net
/*
+#define _GNU_SOURCE
+
#cgo CFLAGS: -fno-stack-protector
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
+#ifndef EAI_NODATA
+#define EAI_NODATA -5
+#endif
+
// If nothing else defined EAI_OVERFLOW, make sure it has a value.
#ifndef EAI_OVERFLOW
#define EAI_OVERFLOW -12
_C_AF_INET6 = C.AF_INET6
_C_AF_UNSPEC = C.AF_UNSPEC
_C_EAI_AGAIN = C.EAI_AGAIN
+ _C_EAI_NODATA = C.EAI_NODATA
_C_EAI_NONAME = C.EAI_NONAME
_C_EAI_OVERFLOW = C.EAI_OVERFLOW
_C_EAI_SYSTEM = C.EAI_SYSTEM
_C_AF_UNSPEC = syscall.AF_UNSPEC
_C_EAI_AGAIN = unix.EAI_AGAIN
_C_EAI_NONAME = unix.EAI_NONAME
+ _C_EAI_NODATA = unix.EAI_NODATA
_C_EAI_OVERFLOW = unix.EAI_OVERFLOW
_C_EAI_SYSTEM = unix.EAI_SYSTEM
_C_IPPROTO_TCP = syscall.IPPROTO_TCP
import (
"context"
+ "errors"
"fmt"
"internal/testenv"
"net/netip"
checkErr(err2)
cancel()
}
+
+func TestLookupNoData(t *testing.T) {
+ if runtime.GOOS == "plan9" {
+ t.Skip("not supported on plan9")
+ }
+
+ mustHaveExternalNetwork(t)
+
+ testLookupNoData(t, "default resolver")
+
+ func() {
+ defer forceGoDNS()()
+ testLookupNoData(t, "forced go resolver")
+ }()
+
+ func() {
+ defer forceCgoDNS()()
+ testLookupNoData(t, "forced cgo resolver")
+ }()
+}
+
+func testLookupNoData(t *testing.T, prefix string) {
+ attempts := 0
+ for {
+ // Domain that doesn't have any A/AAAA RRs, but has different one (in this case a TXT),
+ // so that it returns an empty response without any error codes (NXDOMAIN).
+ _, err := LookupHost("golang.rsc.io")
+ if err == nil {
+ t.Errorf("%v: unexpected success", prefix)
+ return
+ }
+
+ var dnsErr *DNSError
+ if errors.As(err, &dnsErr) {
+ succeeded := true
+ if !dnsErr.IsNotFound {
+ succeeded = false
+ t.Logf("%v: IsNotFound is set to false", prefix)
+ }
+
+ if dnsErr.Err != errNoSuchHost.Error() {
+ succeeded = false
+ t.Logf("%v: error message is not equal to: %v", prefix, errNoSuchHost.Error())
+ }
+
+ if succeeded {
+ return
+ }
+ }
+
+ testenv.SkipFlakyNet(t)
+ if attempts < len(backoffDuration) {
+ dur := backoffDuration[attempts]
+ t.Logf("%v: backoff %v after failure %v\n", prefix, dur, err)
+ time.Sleep(dur)
+ attempts++
+ continue
+ }
+
+ t.Errorf("%v: unexpected error: %v", prefix, err)
+ return
+ }
+}