1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
//! Connection admission barrier (post-allowlist).
//!
//! After the server admits a peer — its node-id is on the allowlist (or `--allow-any`) — it opens a
//! bi-stream and writes a single ADMIT byte; the client awaits it. This is **not** authentication:
//! the peer's node-id is already authenticated by iroh's QUIC/TLS handshake, and the allowlist is the
//! authorization gate. The ack exists only as a synchronization point so the **client** can cleanly
//! distinguish "admitted" from a deliberate server rejection (which closes the connection). Without
//! it a rejected client would re-dial in the reconnect loop forever instead of failing fast with the
//! server's close reason.
//!
//! Stream direction is deliberate: the **server opens** the bi-stream and the **client accepts** it —
//! inverting that deadlocks both sides on their `*_bi()` calls.
use io;
use Connection;
/// The single byte the server writes once a peer is authorized.
const ADMIT: u8 = 1;
/// Errors awaiting admission on the client.
/// Server side: signal admission after the allowlist check passes.
///
/// Non-blocking in practice — opening a QUIC stream and buffering one byte does not wait on the
/// client — so a client that never accepts the stream cannot stall the server here.
pub async
/// Client side: await the server's admission ack. A closed connection (the server rejected us) or a
/// missing/unexpected byte surfaces as an error the caller turns into a clean "not authorized".
pub async