Commit 9e66463
fix: graceful TCP close to stop RST on early error responses (#185)
SLEdge frequently answers a request before it has finished reading it:
the short-circuit error responses (400/404/429/500/503) in the listener
thread write the response and close the socket while the client may still
be sending its request body.
tcp_session_close() did a bare close(). On Linux, close() with unread data
still in the kernel receive buffer discards that data and emits a TCP RST
instead of a graceful FIN. The client's HTTP stack reports this as
"connection reset by peer" or, on a pooled keepalive connection, as the Go
net/http warning "Unsolicited response received on idle HTTP channel" that
issue #185 describes.
Close gracefully instead: half-close the write side so the client receives
our FIN (and, holding a complete response, stops sending), then drain any
already-buffered inbound data so close() no longer sees unread data. The
drain is non-blocking and bounded (32 x 8 KiB) so the single listener
thread can never block or spin on a slow client.
Verified in the Docker dev environment with hey: POSTing a 100 KB body to a
rejected (404) route went from ~159 "connection reset by peer" errors per
2400 requests to 0, with no change to normal 200-response throughput
(~15k rps) or the bodyless GET -> 429/503 path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 6037e62 commit 9e66463
1 file changed
Lines changed: 42 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
15 | 24 | | |
16 | 25 | | |
17 | 26 | | |
| |||
20 | 29 | | |
21 | 30 | | |
22 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
23 | 65 | | |
24 | 66 | | |
25 | 67 | | |
| |||
0 commit comments