]> Cypherpunks repositories - gostls13.git/commitdiff
net: in the fake implementation, allow writes to buffer on closed connections
authorBryan C. Mills <bcmills@google.com>
Fri, 26 Jan 2024 17:23:01 +0000 (12:23 -0500)
committerGopher Robot <gobot@golang.org>
Mon, 29 Jan 2024 21:29:57 +0000 (21:29 +0000)
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 <bcmills@google.com>
Reviewed-by: Damien Neil <dneil@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>

src/net/net_fake.go

index b7ecb391448a2c75c16bf2f7d28fc0cde00a5dd5..2d1e137b6dbadab6c579e48f368f0f2100d8de4b 100644 (file)
@@ -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)