net: net remove completed return from cgo lookup functions

After CL 487196 there is no need anymore to return
completed == false from the cgo lookup functions and
then fallback to to go resolver.  (Before CL 487196 this
change would cause the (only?) tests to fail)
Now the cgoAvailable constant guards that correctly.

This change will cause a panic when the cgo resolver is being
used without the cgo support, so it will be easier to
detect bug while changing the code in the net package.

I am leaving the completed return from cgoLookupCNAME,
because it is super broken now.

Change-Id: I2661b9a3725de2b1a229847c12adf64b3f62b136
GitHub-Last-Rev: 2a6501a53e
GitHub-Pull-Request: golang/go#59925
Reviewed-on: https://go-review.googlesource.com/c/go/+/491275
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Mateusz Poliwczak <mpoliwczak34@gmail.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
Mateusz Poliwczak 2023-05-02 14:17:54 +00:00 committed by Gopher Robot
parent 1596aeec8e
commit 2c49bf89ed
5 changed files with 41 additions and 98 deletions

View file

@ -18,22 +18,22 @@ import "context"
// is not available on this system. // is not available on this system.
const cgoAvailable = false const cgoAvailable = false
func cgoLookupHost(ctx context.Context, name string) (addrs []string, err error, completed bool) { func cgoLookupHost(ctx context.Context, name string) (addrs []string, err error) {
return nil, nil, false panic("cgo stub: cgo not available")
} }
func cgoLookupPort(ctx context.Context, network, service string) (port int, err error, completed bool) { func cgoLookupPort(ctx context.Context, network, service string) (port int, err error) {
return 0, nil, false panic("cgo stub: cgo not available")
} }
func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error, completed bool) { func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error) {
return nil, nil, false panic("cgo stub: cgo not available")
} }
func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) { func cgoLookupCNAME(ctx context.Context, name string) (cname string, err error, completed bool) {
return "", nil, false panic("cgo stub: cgo not available")
} }
func cgoLookupPTR(ctx context.Context, addr string) (ptrs []string, err error, completed bool) { func cgoLookupPTR(ctx context.Context, addr string) (ptrs []string, err error) {
return nil, nil, false panic("cgo stub: cgo not available")
} }

View file

@ -66,15 +66,18 @@ func doBlockingWithCtx[T any](ctx context.Context, blocking func() (T, error)) (
} }
} }
func cgoLookupHost(ctx context.Context, name string) (hosts []string, err error, completed bool) { func cgoLookupHost(ctx context.Context, name string) (hosts []string, err error) {
addrs, err, completed := cgoLookupIP(ctx, "ip", name) addrs, err := cgoLookupIP(ctx, "ip", name)
if err != nil {
return nil, err
}
for _, addr := range addrs { for _, addr := range addrs {
hosts = append(hosts, addr.String()) hosts = append(hosts, addr.String())
} }
return return hosts, nil
} }
func cgoLookupPort(ctx context.Context, network, service string) (port int, err error, completed bool) { func cgoLookupPort(ctx context.Context, network, service string) (port int, err error) {
var hints _C_struct_addrinfo var hints _C_struct_addrinfo
switch network { switch network {
case "": // no hints case "": // no hints
@ -85,7 +88,7 @@ func cgoLookupPort(ctx context.Context, network, service string) (port int, err
*_C_ai_socktype(&hints) = _C_SOCK_DGRAM *_C_ai_socktype(&hints) = _C_SOCK_DGRAM
*_C_ai_protocol(&hints) = _C_IPPROTO_UDP *_C_ai_protocol(&hints) = _C_IPPROTO_UDP
default: default:
return 0, &DNSError{Err: "unknown network", Name: network + "/" + service}, true return 0, &DNSError{Err: "unknown network", Name: network + "/" + service}
} }
switch ipVersion(network) { switch ipVersion(network) {
case '4': case '4':
@ -94,10 +97,9 @@ func cgoLookupPort(ctx context.Context, network, service string) (port int, err
*_C_ai_family(&hints) = _C_AF_INET6 *_C_ai_family(&hints) = _C_AF_INET6
} }
port, err = doBlockingWithCtx(ctx, func() (int, error) { return doBlockingWithCtx(ctx, func() (int, error) {
return cgoLookupServicePort(&hints, network, service) return cgoLookupServicePort(&hints, network, service)
}) })
return port, err, true
} }
func cgoLookupServicePort(hints *_C_struct_addrinfo, network, service string) (port int, err error) { func cgoLookupServicePort(hints *_C_struct_addrinfo, network, service string) (port int, err error) {
@ -208,11 +210,10 @@ func cgoLookupHostIP(network, name string) (addrs []IPAddr, err error) {
return addrs, nil return addrs, nil
} }
func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error, completed bool) { func cgoLookupIP(ctx context.Context, network, name string) (addrs []IPAddr, err error) {
addrs, err = doBlockingWithCtx(ctx, func() ([]IPAddr, error) { return doBlockingWithCtx(ctx, func() ([]IPAddr, error) {
return cgoLookupHostIP(network, name) return cgoLookupHostIP(network, name)
}) })
return addrs, err, true
} }
// These are roughly enough for the following: // These are roughly enough for the following:
@ -228,20 +229,19 @@ const (
maxNameinfoLen = 4096 maxNameinfoLen = 4096
) )
func cgoLookupPTR(ctx context.Context, addr string) (names []string, err error, completed bool) { func cgoLookupPTR(ctx context.Context, addr string) (names []string, err error) {
ip, err := netip.ParseAddr(addr) ip, err := netip.ParseAddr(addr)
if err != nil { if err != nil {
return nil, &DNSError{Err: "invalid address", Name: addr}, true return nil, &DNSError{Err: "invalid address", Name: addr}
} }
sa, salen := cgoSockaddr(IP(ip.AsSlice()), ip.Zone()) sa, salen := cgoSockaddr(IP(ip.AsSlice()), ip.Zone())
if sa == nil { if sa == nil {
return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}, true return nil, &DNSError{Err: "invalid address " + ip.String(), Name: addr}
} }
names, err = doBlockingWithCtx(ctx, func() ([]string, error) { return doBlockingWithCtx(ctx, func() ([]string, error) {
return cgoLookupAddrPTR(addr, sa, salen) return cgoLookupAddrPTR(addr, sa, salen)
}) })
return names, err, true
} }
func cgoLookupAddrPTR(addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) (names []string, err error) { func cgoLookupAddrPTR(addr string, sa *_C_struct_sockaddr, salen _C_socklen_t) (names []string, err error) {

View file

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
//go:build (cgo || darwin) && !netgo && unix //go:build !netgo && ((cgo && unix) || darwin)
package net package net
@ -14,10 +14,7 @@ import (
func TestCgoLookupIP(t *testing.T) { func TestCgoLookupIP(t *testing.T) {
defer dnsWaitGroup.Wait() defer dnsWaitGroup.Wait()
ctx := context.Background() ctx := context.Background()
_, err, ok := cgoLookupIP(ctx, "ip", "localhost") _, err := cgoLookupIP(ctx, "ip", "localhost")
if !ok {
t.Errorf("cgoLookupIP must not be a placeholder")
}
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -27,10 +24,7 @@ func TestCgoLookupIPWithCancel(t *testing.T) {
defer dnsWaitGroup.Wait() defer dnsWaitGroup.Wait()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
_, err, ok := cgoLookupIP(ctx, "ip", "localhost") _, err := cgoLookupIP(ctx, "ip", "localhost")
if !ok {
t.Errorf("cgoLookupIP must not be a placeholder")
}
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -39,10 +33,7 @@ func TestCgoLookupIPWithCancel(t *testing.T) {
func TestCgoLookupPort(t *testing.T) { func TestCgoLookupPort(t *testing.T) {
defer dnsWaitGroup.Wait() defer dnsWaitGroup.Wait()
ctx := context.Background() ctx := context.Background()
_, err, ok := cgoLookupPort(ctx, "tcp", "smtp") _, err := cgoLookupPort(ctx, "tcp", "smtp")
if !ok {
t.Errorf("cgoLookupPort must not be a placeholder")
}
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -52,10 +43,7 @@ func TestCgoLookupPortWithCancel(t *testing.T) {
defer dnsWaitGroup.Wait() defer dnsWaitGroup.Wait()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
_, err, ok := cgoLookupPort(ctx, "tcp", "smtp") _, err := cgoLookupPort(ctx, "tcp", "smtp")
if !ok {
t.Errorf("cgoLookupPort must not be a placeholder")
}
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -64,10 +52,7 @@ func TestCgoLookupPortWithCancel(t *testing.T) {
func TestCgoLookupPTR(t *testing.T) { func TestCgoLookupPTR(t *testing.T) {
defer dnsWaitGroup.Wait() defer dnsWaitGroup.Wait()
ctx := context.Background() ctx := context.Background()
_, err, ok := cgoLookupPTR(ctx, "127.0.0.1") _, err := cgoLookupPTR(ctx, "127.0.0.1")
if !ok {
t.Errorf("cgoLookupPTR must not be a placeholder")
}
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
@ -77,10 +62,7 @@ func TestCgoLookupPTRWithCancel(t *testing.T) {
defer dnsWaitGroup.Wait() defer dnsWaitGroup.Wait()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() defer cancel()
_, err, ok := cgoLookupPTR(ctx, "127.0.0.1") _, err := cgoLookupPTR(ctx, "127.0.0.1")
if !ok {
t.Errorf("cgoLookupPTR must not be a placeholder")
}
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }

View file

@ -56,11 +56,7 @@ func lookupProtocol(_ context.Context, name string) (int, error) {
func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) { func (r *Resolver) lookupHost(ctx context.Context, host string) (addrs []string, err error) {
order, conf := systemConf().hostLookupOrder(r, host) order, conf := systemConf().hostLookupOrder(r, host)
if order == hostLookupCgo { if order == hostLookupCgo {
if addrs, err, ok := cgoLookupHost(ctx, host); ok { return cgoLookupHost(ctx, host)
return addrs, err
}
// cgo not available (or netgo); fall back to Go's DNS resolver
order = hostLookupFilesDNS
} }
return r.goLookupHostOrder(ctx, host, order, conf) return r.goLookupHostOrder(ctx, host, order, conf)
} }
@ -71,11 +67,7 @@ func (r *Resolver) lookupIP(ctx context.Context, network, host string) (addrs []
} }
order, conf := systemConf().hostLookupOrder(r, host) order, conf := systemConf().hostLookupOrder(r, host)
if order == hostLookupCgo { if order == hostLookupCgo {
if addrs, err, ok := cgoLookupIP(ctx, network, host); ok { return cgoLookupIP(ctx, network, host)
return addrs, err
}
// cgo not available (or netgo); fall back to Go's DNS resolver
order = hostLookupFilesDNS
} }
ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf) ips, _, err := r.goLookupIPCNAMEOrder(ctx, network, host, order, conf)
return ips, err return ips, err
@ -85,16 +77,15 @@ func (r *Resolver) lookupPort(ctx context.Context, network, service string) (int
// Port lookup is not a DNS operation. // Port lookup is not a DNS operation.
// Prefer the cgo resolver if possible. // Prefer the cgo resolver if possible.
if !systemConf().mustUseGoResolver(r) { if !systemConf().mustUseGoResolver(r) {
if port, err, ok := cgoLookupPort(ctx, network, service); ok { port, err := cgoLookupPort(ctx, network, service)
if err != nil { if err != nil {
// Issue 18213: if cgo fails, first check to see whether we // Issue 18213: if cgo fails, first check to see whether we
// have the answer baked-in to the net package. // have the answer baked-in to the net package.
if port, err := goLookupPort(network, service); err == nil { if port, err := goLookupPort(network, service); err == nil {
return port, nil return port, nil
}
} }
return port, err
} }
return port, err
} }
return goLookupPort(network, service) return goLookupPort(network, service)
} }
@ -128,9 +119,7 @@ func (r *Resolver) lookupTXT(ctx context.Context, name string) ([]string, error)
func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) { func (r *Resolver) lookupAddr(ctx context.Context, addr string) ([]string, error) {
order, conf := systemConf().hostLookupOrder(r, "") order, conf := systemConf().hostLookupOrder(r, "")
if order == hostLookupCgo { if order == hostLookupCgo {
if ptrs, err, ok := cgoLookupPTR(ctx, addr); ok { return cgoLookupPTR(ctx, addr)
return ptrs, err
}
} }
return r.goLookupPTR(ctx, addr, conf) return r.goLookupPTR(ctx, addr, conf)
} }

View file

@ -1,28 +0,0 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build (!cgo || netgo) && (dragonfly || freebsd || linux || netbsd || openbsd || solaris)
package net
import (
"context"
"testing"
)
func TestGoLookupIP(t *testing.T) {
defer dnsWaitGroup.Wait()
host := "localhost"
ctx := context.Background()
_, err, ok := cgoLookupIP(ctx, "ip", host)
if ok {
t.Errorf("cgoLookupIP must be a placeholder")
}
if err != nil {
t.Error(err)
}
if _, err := DefaultResolver.goLookupIP(ctx, "ip", host); err != nil {
t.Error(err)
}
}