review-003: the assembly-layer full review — F-1/F-2 fixed, the residue dispositioned

- Review 003 written (docs/reviews/003-assembly-layer-implementation-
  review.md): the batch-2 assembly layer post-landing, the review-002
  template — correctness/security/smells/coverage over the five
  batch-2 modules + the batch-2 consumer/producer diff surface.
  Baseline: 375 default / 620 all-features green, clippy/fmt/doc
  clean, both wasm checks clean, publish dry-run completes,
  llvm-cov 93.68% lines / 91.01% functions.

- F-1 (major, fixed): the cred-bearing door swallowed every in-band
  refusal's mapped reply code (the CONNECT/BIND session-open errors
  and the accept-stage Err were bare closes) — a vanilla client got
  no reply where ADR-007 pins a reply-code-shaped refusal. Fixed with
  a write_refusal_reply helper (the door's boundary codec, RFC
  placeholder BND.ADDR) at all three sites, pinned by
  cred_door_in_band_refusal_surfaces_the_reply_code.

- F-2 (major, fixed): UdpFrontDoor::serve_on returned Ok(()) on a
  fatal relay-socket I/O failure against its own doc contract —
  the Io exit now surfaces as Err; the idle/association/session
  exits stay clean.

- Findings recorded, not fixed (the release-polish round's residue):
  D-1 (associate_with_token 0% covered), D-2 (the composed-egress
  failure matrix), D-3 (the io-kind refusal-table arms), S-1 (the
  UDP door's learned client address), N-1..N-8 (doc lines, posture
  notes, coverage residue).

Verification: cargo test (375) + --all-features (620) green,
clippy --all-targets --all-features -D warnings clean, fmt --check
clean, doc --no-deps clean, both wasm checks clean, publish
dry-run completes.
This commit is contained in:
glm-5.3-flash committed 2026-09-26 11:14:04 +00:00
1 parent 04c76e3a41
commit 2db05172ef
3 files changed
+797 -8

No files matched your search

+42 -8
View File
@@ -480,7 +480,14 @@ async fn cred_bearing(
.await
{
Ok(session) => session,
Err(err) => return DoorExit::Open(err.to_string()),
Err(err) => {
// The in-band refusal's mapped code is re-encoded to
// the vanilla client (the RFC codec at the door
// boundary — ADR-003): a dial refusal is reply#1's
// code, never a bare EOF.
write_refusal_reply(&mut stream, &err).await;
return DoorExit::Open(err.to_string());
}
};
pipe_connect_plane(stream, session).await
}
@@ -490,7 +497,10 @@ async fn cred_bearing(
.await
{
Ok(session) => session,
Err(err) => return DoorExit::Open(err.to_string()),
Err(err) => {
write_refusal_reply(&mut stream, &err).await;
return DoorExit::Open(err.to_string());
}
};
pipe_bind_plane(stream, session).await
}
@@ -663,11 +673,13 @@ async fn bind_quiet_and_pipe(
let plane = match session.await_inbound().await {
Ok(Some(plane)) => plane,
Ok(None) => return DoorExit::PlaneEnded,
// An accept-stage refusal (reply#2's mapped code was written
// in-band; the producer's pump ended the session): the door
// closes the vanilla connection — the conversation ends where
// the in-band one did.
Err(_) => {
// An accept-stage refusal (the mapped reply#2 code): the
// vanilla client gets that code re-encoded door-side (the RFC
// codec at the boundary — never a bare EOF), then the
// connection closes — the conversation ends where the in-band
// one did.
Err(err) => {
write_refusal_reply(&mut stream, &err).await;
session.close().await;
return DoorExit::PlaneEnded;
}
@@ -699,6 +711,22 @@ async fn write_vanilla_reply(stream: &mut TcpStream, reply: &[u8]) -> std::io::R
stream.flush().await
}
/// Re-encode an in-band session error's refusal to the vanilla client
/// (the door's RFC codec at the boundary): an error carrying an RFC
/// reply code gets that code as the command's reply (`Succeeded`-form
/// encoding with the error's code + the placeholder BND.ADDR — a
/// refused reply carries a zero address per the RFC); any other error
/// shape (open/transport/I-O) stays a bare close (nothing to encode).
/// Best-effort: a failed write means the client is gone either way.
async fn write_refusal_reply(stream: &mut TcpStream, err: &SocksSessionError) {
let code = match err {
SocksSessionError::Rfc(SocksError::ReplyError(code)) => *code,
_ => return,
};
let reply = new_reply(&code, SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0));
let _ = write_vanilla_reply(stream, &reply).await;
}
/// The UDP front door (feature `local`, the POC #2 test-8 shape): the
/// ASSOCIATE door — a real UDP relay socket bridged onto one in-band
/// association. See the module docs for the shape and the codec
@@ -908,7 +936,13 @@ impl UdpFrontDoor {
};
tracing::debug!("udp front door: association ended: {exit}");
let _ = association.shutdown().await;
Ok(())
// A socket I/O failure is the door's fatal outcome (surfaced to
// the caller); the idle bound, the association's end, and a
// session error are the association's own ends — a clean return.
match exit {
UdpDoorExit::Io(err) => Err(err),
_ => Ok(()),
}
}
}