Repository navigation
Description
Summary
bin/proxy-relay.mjs never times out an accepted client connection. The only socket timeout in the file guards the outbound tunnel CONNECT (10s, proxy-relay.mjs:93, cleared at :116); the accepted client socket gets none — not while the relay waits for the first request line, and not after the connection is piped upstream.
Evidence (main 24901e7b)
bin/proxy-relay.mjs:155-184— thenet.createServerhandler buffers the first line inonData(headEnd === -1 && buf.length < 8192→ keep waiting). Noclient.setTimeout(...)is ever called on the accepted socket;grep setTimeout bin/proxy-relay.mjsreturns only lines 93 and 116, both on the upstream socket.- Probe (this run, sandbox, relay on loopback :18999, target 18745): opened (1) a TCP connection that sent nothing, and (2) a connection that sent a partial request line
GET /heawith no CRLF. After 12s — longer than the upstream CONNECT timeout — both sockets were still open (idleClosed=false partialClosed=false, neither destroyed). The partial-line socket was still holding its buffered bytes in the peek stage. Nothing in the code ever reaps either state, so they live until the client or the OS gives up. - After the peek stage the same gap continues:
client.pipe(upstream); upstream.pipe(client)(:178-179) with no idle timeout on either side, and the upstream's CONNECT timeout is explicitly cleared (sock.setTimeout(0),:116) once the tunnel is up.
Why it matters
The relay is a long-lived loopback forwarder supervised for fleet proxies. Any local client that connects and stalls — a hung OpenCode/proxy client, a crashed process that left a half-open socket, a health prober that connects but never writes — pins a file descriptor and its buffered bytes in the relay forever. Enough of them accumulate into fd exhaustion on a process whose whole job is to stay up, and the failure mode is silent: nothing logs, nothing expires. Every other timeout-sensitive surface in this fleet has been pinned down one by one (upstream CONNECT here included); the accepted-socket side is the unguarded one.
Acceptance criteria
- An accepted client connection that does not deliver a complete first line within a bounded time is closed by the relay (triage pins the value; the upstream CONNECT timeout of 10s is the in-file precedent).
- The timeout behaviour after piping (idle forwarded connections) is decided explicitly — either an idle timeout is applied, or the code comments why forwarded connections are intentionally exempt.
- A test (alongside
bin/proxy-relaycoverage or a scripted probe) shows an idle connection and a partial-line connection are both reaped within the bound, while a normal/healthanswer and a forwarded request still work. - No change to target selection,
/healthlocal answering, or endpoint publishing behaviour.
Found by new-issue-creator-code-b (lane B) this run; probe in the goal's hidden_files probe-2026-10-29-relayidle/ (probe.mjs + relay.log), main 24901e7b.
Activity
developing-today commentedon Oct 29, 2026
CODE-1105
dezren39 commentedon Oct 29, 2026
🤖 Agent note · filed
probe-2026-10-29-relayidle/in the goal's hidden_files (idle + partial-line sockets still open at 12s, main 24901e7)2 remaining items
dezren39 commentedon Nov 2, 2026
agent-note:v1 — state: picked-up at=2026-11-02T02:45:51Z (OpenChamber scheduled lane)
dezren39 commentedon Nov 2, 2026
agent-note:v1 — state: done at=2026-11-02T02:55:14Z (OpenChamber scheduled lane)
Merge pull request #4137 from developing-today/queue/5230-2234-proxy-…