Skip to main content

Module drain_consumer

Module drain_consumer 

Source
Expand description

Core drain consumer (A2 / A3): core dials C2, drains one node stream, and answers on the same stream. C2 never dials core and never sees plaintext.

Per stream: Noise_NK msg1 arrives as a DATA envelope, core answers msg2 as downlink DATA, then every envelope is Noise transport. Each plaintext goes to a CoreHandler together with the node id taken from the stream (never from the payload); the reply is encrypted back down. Every processed seq is ACKed, and a reconnect RESUMEs after the last ACK.

Restart safety: the last ACK per node/channel is persisted (see CursorStore) so a restarted core does not replay the node’s stream from zero. When a replay still happens (no cursor, C2 reset), only the newest Handshake1 of the backlog is answered: a Handshake1 is held until the backlog goes idle, a newer one replaces it, and transport frames queued behind an unanswered Handshake1 belong to an older session and are dropped. If no handshake lands for a while after resuming from a persisted cursor (C2 restarted and its seqs restarted), the cursor is reset to zero. A node does not notice a core restart (its C2 uplink stays up), so when core holds no session it sends an undecryptable transport frame; the node drops its stale keys and re-handshakes.

Structs§

CursorStore
File-backed last-ACK cursor for one node stream. Writes are atomic (tmp + rename).
DrainConsumer
NodeStream

Constants§

DRAIN_STATE_DIR_ENV
Env var naming the directory for persisted drain cursors (absolute path).

Type Aliases§

CoreHandler
Core logic for one decrypted inner message. Blocking work is fine: it runs on a blocking thread. Return None for messages that need no reply.