From: Bryan C. Mills Date: Fri, 26 Jan 2024 17:23:01 +0000 (-0500) Subject: net: in the fake implementation, allow writes to buffer on closed connections X-Git-Tag: go1.23rc1~1355 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=47d240ccbb40425b49f14e21145d01dda542a21c;p=gostls13.git net: in the fake implementation, allow writes to buffer on closed connections This mimics the apparent behavior of writes on linux/amd64, in which a write on an already-closed connection silently succeeds — even if the connection has already been closed by the remote end — provided that the packet fits in the kernel's send buffer. I tested this by patching in CL 557437 and running the test on js/wasm and wasip1/wasm locally. Fixes #64317. Change-Id: I43f6a89e5059115cb61e4ffc33a8371057cb67a1 Reviewed-on: https://go-review.googlesource.com/c/go/+/558915 Auto-Submit: Bryan Mills Reviewed-by: Damien Neil Reviewed-by: Michael Pratt LUCI-TryBot-Result: Go LUCI --- diff --git a/src/net/net_fake.go b/src/net/net_fake.go index b7ecb39144..2d1e137b6d 100644 --- a/src/net/net_fake.go +++ b/src/net/net_fake.go @@ -460,16 +460,6 @@ func (pq *packetQueue) put(q packetQueueState) { func (pq *packetQueue) closeRead() error { q := pq.get() - - // Discard any unread packets. - for q.head != nil { - p := q.head - q.head = p.next - p.clear() - packetPool.Put(p) - } - q.nBytes = 0 - q.readClosed = true pq.put(q) return nil @@ -557,7 +547,7 @@ func (pq *packetQueue) send(dt *deadlineTimer, b []byte, from sockaddr, block bo } if q.writeClosed { return 0, ErrClosed - } else if q.readClosed { + } else if q.readClosed && q.nBytes >= q.readBufferBytes { return 0, os.NewSyscallError("send", syscall.ECONNRESET) } @@ -603,11 +593,13 @@ func (pq *packetQueue) recvfrom(dt *deadlineTimer, b []byte, wholePacket bool, c } defer func() { pq.put(q) }() + if q.readClosed { + return 0, nil, ErrClosed + } + p := q.head if p == nil { switch { - case q.readClosed: - return 0, nil, ErrClosed case q.writeClosed: if q.noLinger { return 0, nil, os.NewSyscallError("recvfrom", syscall.ECONNRESET)