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:
@@ -4,7 +4,7 @@
|
|||||||
use std::os::unix::net::UnixStream;
|
use std::os::unix::net::UnixStream;
|
||||||
|
|
||||||
use crate::approvals::Entry;
|
use crate::approvals::Entry;
|
||||||
use crate::broker::{Broker, forbid, hold_open, read_request, send};
|
use crate::broker::{Broker, forbid, read_request, send};
|
||||||
use crate::grants;
|
use crate::grants;
|
||||||
use crate::ledger::{Answer, Answered};
|
use crate::ledger::{Answer, Answered};
|
||||||
use proto::{
|
use proto::{
|
||||||
@@ -120,12 +120,10 @@ pub fn handle(mut stream: UnixStream, broker: &Broker) {
|
|||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
forbid(broker, &mut stream, id, &other, "admin.sock");
|
forbid(broker, &mut stream, id, &other, "admin.sock");
|
||||||
hold_open(&mut stream);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 3. The final frame; a failed send is ignored.
|
// 3. The final frame; a failed send is ignored.
|
||||||
let _ = send(&mut stream, id, true, response);
|
let _ = send(&mut stream, id, true, response);
|
||||||
hold_open(&mut stream);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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.
|
/// 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";
|
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.
|
/// A line printer: one line per call, owned by the broker.
|
||||||
pub type Log = Box<dyn Fn(&str) + Send + Sync>;
|
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.
|
/// Answer one call: decide, and either answer it or wait for an approval.
|
||||||
pub fn handle(mut stream: UnixStream, broker: &Broker) {
|
pub fn handle(mut stream: UnixStream, broker: &Broker) {
|
||||||
let Some(envelope) = read_request(&mut stream) else {
|
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 msg = envelope.msg;
|
||||||
let Message::ToolRequest(request) = msg else {
|
let Message::ToolRequest(request) = msg else {
|
||||||
forbid(broker, &mut stream, id, &msg, "broker.sock"); // 2. not a tool request
|
forbid(broker, &mut stream, id, &msg, "broker.sock"); // 2. not a tool request
|
||||||
hold_open(&mut stream);
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -230,7 +208,6 @@ pub fn handle(mut stream: UnixStream, broker: &Broker) {
|
|||||||
};
|
};
|
||||||
if let Some(answer) = answer {
|
if let Some(answer) = answer {
|
||||||
let _ = send(&mut stream, id, true, Message::ToolResponse(answer)); // 4. the final frame
|
let _ = send(&mut stream, id, true, Message::ToolResponse(answer)); // 4. the final frame
|
||||||
hold_open(&mut stream);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user