mirror of
https://github.com/golang/go.git
synced 2025-11-10 13:41:05 +00:00
net: fix plan9 after context change, propagate contexts more
My previous https://golang.org/cl/22101 to add context throughout the net package broke Plan 9, which isn't currently tested (#15251). It also broke some old unsupported version of Windows (Windows 2000?) which doesn't have the ConnectEx function, but that was only found visually, since our minimum supported Windows version has ConnectEx. This change simplifies the Windows and deletes the non-ConnectEx code path. Windows 2000 will work even less now, if it even worked before. Windows XP remains our minimum supported version. Specifically, the previous CL stopped using the "dial" function, which 0intro noted: https://github.com/golang/go/issues/15333#issuecomment-210842761 This CL removes the dial function instead and makes plan9's net implementation respect contexts, which likely fixes a number of t.Skipped tests. I'm leaving that to 0intro to investigate. In the process of propagating and respecting contexts for plan9, I had to change some signatures to add contexts to more places and ended up pushing contexts down into the Go-based DNS resolution as well, replacing the pure-Go DNS implementation's use of "timeout time.Duration" with a context instead. Updates #11932 Updates #15328 Fixes #15333 Change-Id: I6ad1e62f38271cdd86b3f40921f2d0f23374936a Reviewed-on: https://go-review.googlesource.com/22144 Reviewed-by: David du Colombier <0intro@gmail.com> Reviewed-by: Mikio Hara <mikioh.mikioh@gmail.com> Reviewed-by: Ian Lance Taylor <iant@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
parent
a3c92c9db1
commit
f60fcca5f1
16 changed files with 199 additions and 197 deletions
|
|
@ -27,10 +27,10 @@ import (
|
|||
|
||||
// A dnsDialer provides dialing suitable for DNS queries.
|
||||
type dnsDialer interface {
|
||||
dialDNS(string, string) (dnsConn, error)
|
||||
dialDNS(ctx context.Context, network, addr string) (dnsConn, error)
|
||||
}
|
||||
|
||||
var testHookDNSDialer = func(d time.Duration) dnsDialer { return &Dialer{Timeout: d} }
|
||||
var testHookDNSDialer = func() dnsDialer { return &Dialer{} }
|
||||
|
||||
// A dnsConn represents a DNS transport endpoint.
|
||||
type dnsConn interface {
|
||||
|
|
@ -105,7 +105,7 @@ func (c *TCPConn) writeDNSQuery(msg *dnsMsg) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (d *Dialer) dialDNS(network, server string) (dnsConn, error) {
|
||||
func (d *Dialer) dialDNS(ctx context.Context, network, server string) (dnsConn, error) {
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6", "udp", "udp4", "udp6":
|
||||
default:
|
||||
|
|
@ -116,9 +116,9 @@ func (d *Dialer) dialDNS(network, server string) (dnsConn, error) {
|
|||
// call back here to translate it. The DNS config parser has
|
||||
// already checked that all the cfg.servers[i] are IP
|
||||
// addresses, which Dial will use without a DNS lookup.
|
||||
c, err := d.Dial(network, server)
|
||||
c, err := d.DialContext(ctx, network, server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
switch network {
|
||||
case "tcp", "tcp4", "tcp6":
|
||||
|
|
@ -130,8 +130,8 @@ func (d *Dialer) dialDNS(network, server string) (dnsConn, error) {
|
|||
}
|
||||
|
||||
// exchange sends a query on the connection and hopes for a response.
|
||||
func exchange(server, name string, qtype uint16, timeout time.Duration) (*dnsMsg, error) {
|
||||
d := testHookDNSDialer(timeout)
|
||||
func exchange(ctx context.Context, server, name string, qtype uint16) (*dnsMsg, error) {
|
||||
d := testHookDNSDialer()
|
||||
out := dnsMsg{
|
||||
dnsMsgHdr: dnsMsgHdr{
|
||||
recursion_desired: true,
|
||||
|
|
@ -141,21 +141,21 @@ func exchange(server, name string, qtype uint16, timeout time.Duration) (*dnsMsg
|
|||
},
|
||||
}
|
||||
for _, network := range []string{"udp", "tcp"} {
|
||||
c, err := d.dialDNS(network, server)
|
||||
c, err := d.dialDNS(ctx, network, server)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer c.Close()
|
||||
if timeout > 0 {
|
||||
c.SetDeadline(time.Now().Add(timeout))
|
||||
if d, ok := ctx.Deadline(); ok && !d.IsZero() {
|
||||
c.SetDeadline(d)
|
||||
}
|
||||
out.id = uint16(rand.Int()) ^ uint16(time.Now().UnixNano())
|
||||
if err := c.writeDNSQuery(&out); err != nil {
|
||||
return nil, err
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
in, err := c.readDNSResponse()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, mapErr(err)
|
||||
}
|
||||
if in.id != out.id {
|
||||
return nil, errors.New("DNS message ID mismatch")
|
||||
|
|
@ -170,16 +170,24 @@ func exchange(server, name string, qtype uint16, timeout time.Duration) (*dnsMsg
|
|||
|
||||
// Do a lookup for a single name, which must be rooted
|
||||
// (otherwise answer will not find the answers).
|
||||
func tryOneName(cfg *dnsConfig, name string, qtype uint16) (string, []dnsRR, error) {
|
||||
func tryOneName(ctx context.Context, cfg *dnsConfig, name string, qtype uint16) (string, []dnsRR, error) {
|
||||
if len(cfg.servers) == 0 {
|
||||
return "", nil, &DNSError{Err: "no DNS servers", Name: name}
|
||||
}
|
||||
|
||||
timeout := time.Duration(cfg.timeout) * time.Second
|
||||
deadline := time.Now().Add(timeout)
|
||||
if old, ok := ctx.Deadline(); !ok || deadline.Before(old) {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithDeadline(ctx, deadline)
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
var lastErr error
|
||||
for i := 0; i < cfg.attempts; i++ {
|
||||
for _, server := range cfg.servers {
|
||||
server = JoinHostPort(server, "53")
|
||||
msg, err := exchange(server, name, qtype, timeout)
|
||||
msg, err := exchange(ctx, server, name, qtype)
|
||||
if err != nil {
|
||||
lastErr = &DNSError{
|
||||
Err: err.Error(),
|
||||
|
|
@ -297,7 +305,7 @@ func (conf *resolverConfig) releaseSema() {
|
|||
<-conf.ch
|
||||
}
|
||||
|
||||
func lookup(name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
|
||||
func lookup(ctx context.Context, name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
|
||||
if !isDomainName(name) {
|
||||
return "", nil, &DNSError{Err: "invalid domain name", Name: name}
|
||||
}
|
||||
|
|
@ -306,7 +314,7 @@ func lookup(name string, qtype uint16) (cname string, rrs []dnsRR, err error) {
|
|||
conf := resolvConf.dnsConfig
|
||||
resolvConf.mu.RUnlock()
|
||||
for _, fqdn := range conf.nameList(name) {
|
||||
cname, rrs, err = tryOneName(conf, fqdn, qtype)
|
||||
cname, rrs, err = tryOneName(ctx, conf, fqdn, qtype)
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
|
|
@ -467,7 +475,7 @@ func goLookupIPOrder(ctx context.Context, name string, order hostLookupOrder) (a
|
|||
for _, fqdn := range conf.nameList(name) {
|
||||
for _, qtype := range qtypes {
|
||||
go func(qtype uint16) {
|
||||
_, rrs, err := tryOneName(conf, fqdn, qtype)
|
||||
_, rrs, err := tryOneName(ctx, conf, fqdn, qtype)
|
||||
lane <- racer{fqdn, rrs, err}
|
||||
}(qtype)
|
||||
}
|
||||
|
|
@ -510,8 +518,8 @@ func goLookupIPOrder(ctx context.Context, name string, order hostLookupOrder) (a
|
|||
// Normally we let cgo use the C library resolver instead of
|
||||
// depending on our lookup code, so that Go and C get the same
|
||||
// answers.
|
||||
func goLookupCNAME(name string) (cname string, err error) {
|
||||
_, rrs, err := lookup(name, dnsTypeCNAME)
|
||||
func goLookupCNAME(ctx context.Context, name string) (cname string, err error) {
|
||||
_, rrs, err := lookup(ctx, name, dnsTypeCNAME)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
@ -524,7 +532,7 @@ func goLookupCNAME(name string) (cname string, err error) {
|
|||
// only if cgoLookupPTR is the stub in cgo_stub.go).
|
||||
// Normally we let cgo use the C library resolver instead of depending
|
||||
// on our lookup code, so that Go and C get the same answers.
|
||||
func goLookupPTR(addr string) ([]string, error) {
|
||||
func goLookupPTR(ctx context.Context, addr string) ([]string, error) {
|
||||
names := lookupStaticAddr(addr)
|
||||
if len(names) > 0 {
|
||||
return names, nil
|
||||
|
|
@ -533,7 +541,7 @@ func goLookupPTR(addr string) ([]string, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, rrs, err := lookup(arpa, dnsTypePTR)
|
||||
_, rrs, err := lookup(ctx, arpa, dnsTypePTR)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue