brokerd: close the connection after the final frame again

hold_open (d21baa2) kept each connection open for up to two seconds
after its final frame, reading and dropping anything the peer sent, to
hide a test client that set a read timeout after the handler had closed.
On macOS that call fails with EINVAL; the clients now allow for it
(00a85c1, d7009dc), so the handler goes back to closing at once.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-22 18:32:31 -07:00
co-authored by Claude Opus 5.5
parent d7009dc488
commit 57dc7899a9
2 changed files with 1 additions and 26 deletions
-23
View File
@@ -25,10 +25,6 @@ use crate::runner::Runtime;
/// The failure message sent when a peer leaves at the last look, after the table entry is taken.
pub const GONE: &str = "the requester went away";
/// How long to keep a socket open after the final frame, so the peer can finish reading before its
/// end of the pair is half-closed.
const HOLD_OPEN: Duration = Duration::new(2, 0);
/// A line printer: one line per call, owned by the broker.
pub type Log = Box<dyn Fn(&str) + Send + Sync>;
@@ -189,23 +185,6 @@ pub fn alive(stream: &UnixStream) -> bool {
}
}
/// Keep the socket open after the final frame, until the peer closes it or the timeout elapses.
/// Dropping the peer's end makes its next `set_read_timeout` fail on macOS, so we hold the read
/// half open for as long as the peer might still be reading.
pub(crate) fn hold_open(stream: &mut UnixStream) {
if stream.set_read_timeout(Some(HOLD_OPEN)).is_err() {
return;
}
let mut byte = [0u8; 1];
loop {
match stream.read(&mut byte) {
Ok(0) => break, // the peer closed
Ok(_) => continue,
Err(_) => break,
}
}
}
/// Answer one call: decide, and either answer it or wait for an approval.
pub fn handle(mut stream: UnixStream, broker: &Broker) {
let Some(envelope) = read_request(&mut stream) else {
@@ -215,7 +194,6 @@ pub fn handle(mut stream: UnixStream, broker: &Broker) {
let msg = envelope.msg;
let Message::ToolRequest(request) = msg else {
forbid(broker, &mut stream, id, &msg, "broker.sock"); // 2. not a tool request
hold_open(&mut stream);
return;
};
@@ -230,7 +208,6 @@ pub fn handle(mut stream: UnixStream, broker: &Broker) {
};
if let Some(answer) = answer {
let _ = send(&mut stream, id, true, Message::ToolResponse(answer)); // 4. the final frame
hold_open(&mut stream);
}
}