From 973a9eb8bf883b3856d94624138ecfe30cac3ea0 Mon Sep 17 00:00:00 2001 From: Mateusz Poliwczak Date: Tue, 25 Feb 2025 08:23:26 +0000 Subject: [PATCH] net: properly wrap context cancellation errors and return DNSErrors consistently Fixes #71939 Change-Id: Id7cd720fcca2812ffca2b1b20fe923914422d994 GitHub-Last-Rev: 4671f338c91b5826c669fbd113c176e22f5020e5 GitHub-Pull-Request: golang/go#71941 Reviewed-on: https://go-review.googlesource.com/c/go/+/652275 Commit-Queue: Ian Lance Taylor LUCI-TryBot-Result: Go LUCI Reviewed-by: Ian Lance Taylor Auto-Submit: Ian Lance Taylor Reviewed-by: Damien Neil --- src/net/cgo_unix.go | 12 ++-------- src/net/ipsock_plan9.go | 2 ++ src/net/lookup_plan9.go | 20 +++++++--------- src/net/lookup_windows.go | 50 +++++++-------------------------------- 4 files changed, 21 insertions(+), 63 deletions(-) diff --git a/src/net/cgo_unix.go b/src/net/cgo_unix.go index e866150f29..3afa014b6f 100644 --- a/src/net/cgo_unix.go +++ b/src/net/cgo_unix.go @@ -47,11 +47,7 @@ func (eai addrinfoErrno) isAddrinfoErrno() {} func doBlockingWithCtx[T any](ctx context.Context, lookupName string, blocking func() (T, error)) (T, error) { if err := acquireThread(ctx); err != nil { var zero T - return zero, &DNSError{ - Name: lookupName, - Err: mapErr(err).Error(), - IsTimeout: err == context.DeadlineExceeded, - } + return zero, newDNSError(mapErr(err), lookupName, "") } if ctx.Done() == nil { @@ -77,11 +73,7 @@ func doBlockingWithCtx[T any](ctx context.Context, lookupName string, blocking f return r.res, r.err case <-ctx.Done(): var zero T - return zero, &DNSError{ - Name: lookupName, - Err: mapErr(ctx.Err()).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return zero, newDNSError(mapErr(ctx.Err()), lookupName, "") } } diff --git a/src/net/ipsock_plan9.go b/src/net/ipsock_plan9.go index c8d0180436..6ae9cf3cc1 100644 --- a/src/net/ipsock_plan9.go +++ b/src/net/ipsock_plan9.go @@ -10,6 +10,7 @@ import ( "internal/itoa" "io/fs" "os" + "strconv" "syscall" ) @@ -128,6 +129,7 @@ func startPlan9(ctx context.Context, net string, addr Addr) (ctl *os.File, dest, clone, dest, err := queryCS1(ctx, proto, ip, port) if err != nil { + err = handlePlan9DNSError(err, net+":"+ip.String()+":"+strconv.Itoa(port)) return } f, err := os.OpenFile(clone, os.O_RDWR, 0) diff --git a/src/net/lookup_plan9.go b/src/net/lookup_plan9.go index e3e371611f..0e179d31df 100644 --- a/src/net/lookup_plan9.go +++ b/src/net/lookup_plan9.go @@ -65,11 +65,7 @@ func query(ctx context.Context, filename, query string, bufSize int) (addrs []st case r := <-ch: return r.addrs, r.err case <-ctx.Done(): - return nil, &DNSError{ - Name: query, - Err: ctx.Err().Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return nil, mapErr(err) } } @@ -143,7 +139,7 @@ func toLower(in string) string { func lookupProtocol(ctx context.Context, name string) (proto int, err error) { lines, err := query(ctx, netdir+"/cs", "!protocol="+toLower(name), 128) if err != nil { - return 0, err + return 0, newDNSError(err, name, "") } if len(lines) == 0 { return 0, UnknownNetworkError(name) @@ -229,16 +225,16 @@ func (*Resolver) lookupPortWithNetwork(ctx context.Context, network, errNetwork, lines, err := queryCS(ctx, network, "127.0.0.1", toLower(service)) if err != nil { if stringslite.HasSuffix(err.Error(), "can't translate service") { - return 0, &DNSError{Err: "unknown port", Name: errNetwork + "/" + service, IsNotFound: true} + return 0, newDNSError(errUnknownPort, errNetwork+"/"+service, "") } - return + return 0, newDNSError(err, errNetwork+"/"+service, "") } if len(lines) == 0 { - return 0, &DNSError{Err: "unknown port", Name: errNetwork + "/" + service, IsNotFound: true} + return 0, newDNSError(errUnknownPort, errNetwork+"/"+service, "") } f := getFields(lines[0]) if len(f) < 2 { - return 0, &DNSError{Err: "unknown port", Name: errNetwork + "/" + service, IsNotFound: true} + return 0, newDNSError(errUnknownPort, errNetwork+"/"+service, "") } s := f[1] if i := bytealg.IndexByteString(s, '!'); i >= 0 { @@ -247,7 +243,7 @@ func (*Resolver) lookupPortWithNetwork(ctx context.Context, network, errNetwork, if n, _, ok := dtoi(s); ok { return n, nil } - return 0, &DNSError{Err: "unknown port", Name: errNetwork + "/" + service, IsNotFound: true} + return 0, newDNSError(errUnknownPort, errNetwork+"/"+service, "") } func (r *Resolver) lookupCNAME(ctx context.Context, name string) (cname string, err error) { @@ -269,7 +265,7 @@ func (r *Resolver) lookupCNAME(ctx context.Context, name string) (cname string, return f[2] + ".", nil } } - return "", errors.New("bad response from ndb/dns") + return "", &DNSError{Err: "bad response from ndb/dns", Name: name} } func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*SRV, err error) { diff --git a/src/net/lookup_windows.go b/src/net/lookup_windows.go index 7d415bee4f..7a8fda0a30 100644 --- a/src/net/lookup_windows.go +++ b/src/net/lookup_windows.go @@ -77,7 +77,7 @@ func lookupProtocol(ctx context.Context, name string) (int, error) { } return r.proto, r.err case <-ctx.Done(): - return 0, mapErr(ctx.Err()) + return 0, newDNSError(mapErr(ctx.Err()), name, "") } } @@ -110,11 +110,7 @@ func (r *Resolver) lookupIP(ctx context.Context, network, name string) ([]IPAddr getaddr := func() ([]IPAddr, error) { if err := acquireThread(ctx); err != nil { - return nil, &DNSError{ - Name: name, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return nil, newDNSError(mapErr(err), name, "") } defer releaseThread() hints := syscall.AddrinfoW{ @@ -197,11 +193,7 @@ func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int // TODO(bradfitz): finish ctx plumbing if err := acquireThread(ctx); err != nil { - return 0, &DNSError{ - Name: network + "/" + service, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return 0, newDNSError(mapErr(err), network+"/"+service, "") } defer releaseThread() @@ -265,11 +257,7 @@ func (r *Resolver) lookupCNAME(ctx context.Context, name string) (string, error) // TODO(bradfitz): finish ctx plumbing if err := acquireThread(ctx); err != nil { - return "", &DNSError{ - Name: name, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return "", newDNSError(mapErr(err), name, "") } defer releaseThread() var rec *syscall.DNSRecord @@ -295,11 +283,7 @@ func (r *Resolver) lookupSRV(ctx context.Context, service, proto, name string) ( } // TODO(bradfitz): finish ctx plumbing if err := acquireThread(ctx); err != nil { - return "", nil, &DNSError{ - Name: name, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return "", nil, newDNSError(mapErr(err), name, "") } defer releaseThread() var target string @@ -330,11 +314,7 @@ func (r *Resolver) lookupMX(ctx context.Context, name string) ([]*MX, error) { } // TODO(bradfitz): finish ctx plumbing. if err := acquireThread(ctx); err != nil { - return nil, &DNSError{ - Name: name, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return nil, newDNSError(mapErr(err), name, "") } defer releaseThread() var rec *syscall.DNSRecord @@ -359,11 +339,7 @@ func (r *Resolver) lookupNS(ctx context.Context, name string) ([]*NS, error) { } // TODO(bradfitz): finish ctx plumbing. if err := acquireThread(ctx); err != nil { - return nil, &DNSError{ - Name: name, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return nil, newDNSError(mapErr(err), name, "") } defer releaseThread() var rec *syscall.DNSRecord @@ -387,11 +363,7 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error) } // TODO(bradfitz): finish ctx plumbing. if err := acquireThread(ctx); err != nil { - return nil, &DNSError{ - Name: name, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return nil, newDNSError(mapErr(err), name, "") } defer releaseThread() var rec *syscall.DNSRecord @@ -420,11 +392,7 @@ func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error // TODO(bradfitz): finish ctx plumbing. if err := acquireThread(ctx); err != nil { - return nil, &DNSError{ - Name: addr, - Err: mapErr(err).Error(), - IsTimeout: ctx.Err() == context.DeadlineExceeded, - } + return nil, newDNSError(mapErr(err), addr, "") } defer releaseThread() arpa, err := reverseaddr(addr) -- 2.51.0