aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/net
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/net')
-rw-r--r--libgo/go/net/dnsclient_unix.go6
-rw-r--r--libgo/go/net/dnsclient_unix_test.go2
-rw-r--r--libgo/go/net/http/transport.go6
-rw-r--r--libgo/go/net/http/transport_internal_test.go9
-rw-r--r--libgo/go/net/lookup_test.go69
-rw-r--r--libgo/go/net/net_test.go64
-rw-r--r--libgo/go/net/netip/netip.go2
-rw-r--r--libgo/go/net/smtp/auth.go3
-rw-r--r--libgo/go/net/udpsock_test.go9
9 files changed, 119 insertions, 51 deletions
diff --git a/libgo/go/net/dnsclient_unix.go b/libgo/go/net/dnsclient_unix.go
index 3278791e..ad121a6 100644
--- a/libgo/go/net/dnsclient_unix.go
+++ b/libgo/go/net/dnsclient_unix.go
@@ -30,6 +30,10 @@ const (
// to be used as a useTCP parameter to exchange
useTCPOnly = true
useUDPOrTCP = false
+
+ // Maximum DNS packet size.
+ // Value taken from https://dnsflagday.net/2020/.
+ maxDNSPacketSize = 1232
)
var (
@@ -82,7 +86,7 @@ func dnsPacketRoundTrip(c Conn, id uint16, query dnsmessage.Question, b []byte)
return dnsmessage.Parser{}, dnsmessage.Header{}, err
}
- b = make([]byte, 512) // see RFC 1035
+ b = make([]byte, maxDNSPacketSize)
for {
n, err := c.Read(b)
if err != nil {
diff --git a/libgo/go/net/dnsclient_unix_test.go b/libgo/go/net/dnsclient_unix_test.go
index e34c0a5..0ea2fae 100644
--- a/libgo/go/net/dnsclient_unix_test.go
+++ b/libgo/go/net/dnsclient_unix_test.go
@@ -881,7 +881,7 @@ func (f *fakeDNSPacketConn) Close() error {
func TestIgnoreDNSForgeries(t *testing.T) {
c, s := Pipe()
go func() {
- b := make([]byte, 512)
+ b := make([]byte, maxDNSPacketSize)
n, err := s.Read(b)
if err != nil {
t.Error(err)
diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go
index 5fe3e6e..e41b20a 100644
--- a/libgo/go/net/http/transport.go
+++ b/libgo/go/net/http/transport.go
@@ -606,6 +606,9 @@ func (t *Transport) roundTrip(req *Request) (*Response, error) {
} else if !pconn.shouldRetryRequest(req, err) {
// Issue 16465: return underlying net.Conn.Read error from peek,
// as we've historically done.
+ if e, ok := err.(nothingWrittenError); ok {
+ err = e.error
+ }
if e, ok := err.(transportReadFromServerError); ok {
err = e.err
}
@@ -2032,6 +2035,9 @@ func (pc *persistConn) mapRoundTripError(req *transportRequest, startBytesWritte
}
if _, ok := err.(transportReadFromServerError); ok {
+ if pc.nwrite == startBytesWritten {
+ return nothingWrittenError{err}
+ }
// Don't decorate
return err
}
diff --git a/libgo/go/net/http/transport_internal_test.go b/libgo/go/net/http/transport_internal_test.go
index 1cce272..2ed637e 100644
--- a/libgo/go/net/http/transport_internal_test.go
+++ b/libgo/go/net/http/transport_internal_test.go
@@ -52,8 +52,8 @@ func TestTransportPersistConnReadLoopEOF(t *testing.T) {
conn.Close() // simulate the server hanging up on the client
_, err = pc.roundTrip(treq)
- if !isTransportReadFromServerError(err) && err != errServerClosedIdle {
- t.Errorf("roundTrip = %#v, %v; want errServerClosedIdle or transportReadFromServerError", err, err)
+ if !isNothingWrittenError(err) && !isTransportReadFromServerError(err) && err != errServerClosedIdle {
+ t.Errorf("roundTrip = %#v, %v; want errServerClosedIdle, transportReadFromServerError, or nothingWrittenError", err, err)
}
<-pc.closech
@@ -63,6 +63,11 @@ func TestTransportPersistConnReadLoopEOF(t *testing.T) {
}
}
+func isNothingWrittenError(err error) bool {
+ _, ok := err.(nothingWrittenError)
+ return ok
+}
+
func isTransportReadFromServerError(err error) bool {
_, ok := err.(transportReadFromServerError)
return ok
diff --git a/libgo/go/net/lookup_test.go b/libgo/go/net/lookup_test.go
index 063d650..3a31f56 100644
--- a/libgo/go/net/lookup_test.go
+++ b/libgo/go/net/lookup_test.go
@@ -883,21 +883,66 @@ func TestLookupNonLDH(t *testing.T) {
func TestLookupContextCancel(t *testing.T) {
mustHaveExternalNetwork(t)
- defer dnsWaitGroup.Wait()
+ testenv.SkipFlakyNet(t)
- ctx, ctxCancel := context.WithCancel(context.Background())
- ctxCancel()
- _, err := DefaultResolver.LookupIPAddr(ctx, "google.com")
- if err.(*DNSError).Err != errCanceled.Error() {
- testenv.SkipFlakyNet(t)
- t.Fatal(err)
+ origTestHookLookupIP := testHookLookupIP
+ defer func() {
+ dnsWaitGroup.Wait()
+ testHookLookupIP = origTestHookLookupIP
+ }()
+
+ lookupCtx, cancelLookup := context.WithCancel(context.Background())
+ unblockLookup := make(chan struct{})
+
+ // Set testHookLookupIP to start a new, concurrent call to LookupIPAddr
+ // and cancel the original one, then block until the canceled call has returned
+ // (ensuring that it has performed any synchronous cleanup).
+ testHookLookupIP = func(
+ ctx context.Context,
+ fn func(context.Context, string, string) ([]IPAddr, error),
+ network string,
+ host string,
+ ) ([]IPAddr, error) {
+ select {
+ case <-unblockLookup:
+ default:
+ // Start a concurrent LookupIPAddr for the same host while the caller is
+ // still blocked, and sleep a little to give it time to be deduplicated
+ // before we cancel (and unblock) the caller.
+ // (If the timing doesn't quite work out, we'll end up testing sequential
+ // calls instead of concurrent ones, but the test should still pass.)
+ t.Logf("starting concurrent LookupIPAddr")
+ dnsWaitGroup.Add(1)
+ go func() {
+ defer dnsWaitGroup.Done()
+ _, err := DefaultResolver.LookupIPAddr(context.Background(), host)
+ if err != nil {
+ t.Error(err)
+ }
+ }()
+ time.Sleep(1 * time.Millisecond)
+ }
+
+ cancelLookup()
+ <-unblockLookup
+ // If the concurrent lookup above is deduplicated to this one
+ // (as we expect to happen most of the time), it is important
+ // that the original call does not cancel the shared Context.
+ // (See https://go.dev/issue/22724.) Explicitly check for
+ // cancellation now, just in case fn itself doesn't notice it.
+ if err := ctx.Err(); err != nil {
+ t.Logf("testHookLookupIP canceled")
+ return nil, err
+ }
+ t.Logf("testHookLookupIP performing lookup")
+ return fn(ctx, network, host)
}
- ctx = context.Background()
- _, err = DefaultResolver.LookupIPAddr(ctx, "google.com")
- if err != nil {
- testenv.SkipFlakyNet(t)
- t.Fatal(err)
+
+ _, err := DefaultResolver.LookupIPAddr(lookupCtx, "google.com")
+ if dnsErr, ok := err.(*DNSError); !ok || dnsErr.Err != errCanceled.Error() {
+ t.Errorf("unexpected error from canceled, blocked LookupIPAddr: %v", err)
}
+ close(unblockLookup)
}
// Issue 24330: treat the nil *Resolver like a zero value. Verify nothing
diff --git a/libgo/go/net/net_test.go b/libgo/go/net/net_test.go
index 7b16991..76a9c8b 100644
--- a/libgo/go/net/net_test.go
+++ b/libgo/go/net/net_test.go
@@ -9,7 +9,6 @@ package net
import (
"errors"
"fmt"
- "internal/testenv"
"io"
"net/internal/socktest"
"os"
@@ -515,35 +514,50 @@ func TestCloseUnblocksRead(t *testing.T) {
// Issue 24808: verify that ECONNRESET is not temporary for read.
func TestNotTemporaryRead(t *testing.T) {
- if runtime.GOOS == "freebsd" {
- testenv.SkipFlaky(t, 25289)
- }
- if runtime.GOOS == "aix" {
- testenv.SkipFlaky(t, 29685)
- }
t.Parallel()
- server := func(cs *TCPConn) error {
- cs.SetLinger(0)
- // Give the client time to get stuck in a Read.
- time.Sleep(50 * time.Millisecond)
+
+ ln := newLocalListener(t, "tcp")
+ serverDone := make(chan struct{})
+ dialed := make(chan struct{})
+ go func() {
+ defer close(serverDone)
+
+ cs, err := ln.Accept()
+ if err != nil {
+ return
+ }
+ <-dialed
+ cs.(*TCPConn).SetLinger(0)
cs.Close()
- return nil
+
+ ln.Close()
+ }()
+ defer func() { <-serverDone }()
+
+ ss, err := Dial("tcp", ln.Addr().String())
+ if err != nil {
+ t.Fatal(err)
}
- client := func(ss *TCPConn) error {
- _, err := ss.Read([]byte{0})
- if err == nil {
- return errors.New("Read succeeded unexpectedly")
- } else if err == io.EOF {
- // This happens on Plan 9.
- return nil
- } else if ne, ok := err.(Error); !ok {
- return fmt.Errorf("unexpected error %v", err)
- } else if ne.Temporary() {
- return fmt.Errorf("unexpected temporary error %v", err)
+ defer ss.Close()
+ close(dialed)
+ _, err = ss.Read([]byte{0})
+ if err == nil {
+ t.Fatal("Read succeeded unexpectedly")
+ } else if err == io.EOF {
+ // This happens on Plan 9, but for some reason (prior to CL 385314) it was
+ // accepted everywhere else too.
+ if runtime.GOOS == "plan9" {
+ return
}
- return nil
+ // TODO: during an open development cycle, try making this a failure
+ // and see whether it causes the test to become flaky anywhere else.
+ return
+ }
+ if ne, ok := err.(Error); !ok {
+ t.Errorf("Read error does not implement net.Error: %v", err)
+ } else if ne.Temporary() {
+ t.Errorf("Read error is unexpectedly temporary: %v", err)
}
- withTCPConnPair(t, client, server)
}
// The various errors should implement the Error interface.
diff --git a/libgo/go/net/netip/netip.go b/libgo/go/net/netip/netip.go
index 591d38a..f27984a 100644
--- a/libgo/go/net/netip/netip.go
+++ b/libgo/go/net/netip/netip.go
@@ -1288,7 +1288,7 @@ func (p Prefix) isZero() bool { return p == Prefix{} }
func (p Prefix) IsSingleIP() bool { return p.bits != 0 && int(p.bits) == p.ip.BitLen() }
// ParsePrefix parses s as an IP address prefix.
-// The string can be in the form "192.168.1.0/24" or "2001::db8::/32",
+// The string can be in the form "192.168.1.0/24" or "2001:db8::/32",
// the CIDR notation defined in RFC 4632 and RFC 4291.
//
// Note that masked address bits are not zeroed. Use Masked for that.
diff --git a/libgo/go/net/smtp/auth.go b/libgo/go/net/smtp/auth.go
index fd1a472..7a32ef6 100644
--- a/libgo/go/net/smtp/auth.go
+++ b/libgo/go/net/smtp/auth.go
@@ -16,8 +16,7 @@ type Auth interface {
// Start begins an authentication with a server.
// It returns the name of the authentication protocol
// and optionally data to include in the initial AUTH message
- // sent to the server. It can return proto == "" to indicate
- // that the authentication should be skipped.
+ // sent to the server.
// If it returns a non-nil error, the SMTP client aborts
// the authentication attempt and closes the connection.
Start(server *ServerInfo) (proto string, toServer []byte, err error)
diff --git a/libgo/go/net/udpsock_test.go b/libgo/go/net/udpsock_test.go
index 21f5af5..df1f7d1 100644
--- a/libgo/go/net/udpsock_test.go
+++ b/libgo/go/net/udpsock_test.go
@@ -415,19 +415,14 @@ func TestUDPReadSizeError(t *testing.T) {
if n != len(b1) {
t.Errorf("got %d; want %d", n, len(b1))
}
- c1.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
b2 := make([]byte, len(b1)-1)
if genericRead {
n, err = c1.(Conn).Read(b2)
} else {
n, _, err = c1.ReadFrom(b2)
}
- switch err {
- case nil: // ReadFrom succeeds
- default: // Read may timeout, it depends on the platform
- if nerr, ok := err.(Error); (!ok || !nerr.Timeout()) && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE
- t.Fatal(err)
- }
+ if err != nil && runtime.GOOS != "windows" { // Windows returns WSAEMSGSIZE
+ t.Fatal(err)
}
if n != len(b1)-1 {
t.Fatalf("got %d; want %d", n, len(b1)-1)