lib/reticulum/src/node/transport/root.zig

daab053ee43316e1809a84551d573ddd1e5bf3d2

  1 //! The state and the steps a node needs to work out where destinations are from
  2 //! the broadcasts it hears, and to move traffic toward them.
  3 //!
  4 //! A node has to find out where destinations are with no directory to ask. A
  5 //! node that carries traffic for others carries it toward destinations for
  6 //! neighbors that cannot reach them directly, and answers a neighbor that
  7 //! asks about a destination it knows. The node also passes another pair's
  8 //! encrypted session across itself.
  9 //!
 10 //! What a node knows arrives as broadcasts, so the same broadcast reaches it
 11 //! more than once, by more than one route, and out of order, and the node needs
 12 //! a rule that picks one without a clock shared with the sender. Repeating
 13 //! every broadcast would flood the mesh. A forwarded packet has to say which
 14 //! node passed it on for any answer to come back. Storage is a fixed number of
 15 //! entries the caller fixes before the node starts, so every store states which
 16 //! entry a new one takes over, and a store that refuses a new entry when it is
 17 //! full says so. The node performs no input or output and reads no clock, so
 18 //! each step takes the current second from its caller and returns the frames to
 19 //! send and the timers to arm.
 20 //!
 21 //! Reticulum 1.5.0, the reference implementation this package is a port of,
 22 //! answers each of these forces, and this subtree is a port of those answers.
 23 //! Every module here cites the reference by file and line. The lineage is
 24 //! checkable in this tree: the package README pins the upstream commit the port
 25 //! follows, and the conformance corpus under src/conformance is generated from
 26 //! that release and drives the differential tests.
 27 //!
 28 //! A destination makes itself known with a broadcast carrying its public keys,
 29 //! a signature and ten random bytes holding the instant it was stamped (an
 30 //! *announce*), so any node that hears the announce learns that destination and
 31 //! how far away it sits. That instant orders two announces from the same
 32 //! destination without a shared clock. The node keeps what it learns from
 33 //! announces about reaching one destination, the network interface to send on,
 34 //! the neighbor to name as the next hop, and how many hops away the
 35 //! destination sits (a *path*). A path keeps the announces it has already
 36 //! taken, so a repeat is recognized and an older one loses. A node that carries
 37 //! traffic for others sends an announce it accepted onward at most twice, stops
 38 //! at 128 hops, and stops as soon as it hears neighbors carrying the same one.
 39 //! A forwarded packet's header grows a field that names the node passing it on
 40 //! by that node's 16-byte hash, and two header shapes, of 19 and of 35 bytes,
 41 //! tell a packet in transport from one at its last hop. The node keeps a record
 42 //! for each packet it forwards, tying it to the network interface it arrived on
 43 //! and the one it left on, so the signed answer that confirms the packet (a
 44 //! *proof*) travels the way the packet came. A node asks its neighbors for a
 45 //! way to reach a destination by sending requests to one well-known
 46 //! destination.
 47 //!
 48 //! Every store here (a *table*) lives in bytes the caller hands over and the
 49 //! node hands back at teardown, with its entry maximum fixed before the node
 50 //! starts and its replacement rule written in the code. Reticulum 1.5.0 grows
 51 //! dictionaries and culls them on a periodic pass. Time is whole seconds, so
 52 //! the reference's fractional waits become the nearest whole second. Nothing
 53 //! sweeps on a fixed interval: an entry stops counting at its own deadline when
 54 //! it is looked up, and for relayed sessions the node asks its caller to wake
 55 //! it at each session's deadline (a *node timer*). A step that turns a packet
 56 //! away names the reason in a record for its caller to read (a *diagnostic*).
 57 //! Reticulum 1.5.0 writes such a reason to a log or raises a protocol
 58 //! violation.
 59 //!
 60 //! The modules below divide the work: `path` holds what the node learned about
 61 //! reaching destinations, `announces` and `retransmit` hold the queue of
 62 //! announces to send on and the sweep that sends them, `relay` with `rewrite`
 63 //! and `reverse` carry one packet onward and bring its proof back, `requests`
 64 //! with `inflight` and `discoveries` ask for a path and answer when asked,
 65 //! `link` and `links` hold the sessions the node carries and the ones it holds
 66 //! an end of, and `state` carves all eight stores from one block of caller
 67 //! storage.
 68 //!
 69 //! - *destination*: the 16-byte hash that names one addressable endpoint on the
 70 //!   network.
 71 //! - *transport node*: a node that carries traffic on behalf of other nodes, as
 72 //!   well as sending and receiving its own.
 73 //! - *link*: an encrypted session between two endpoints, named by a 16-byte
 74 //!   link id that both ends derive from the request packet.
 75 //! - *emission time*: the instant the originator stamped into the ten random
 76 //!   bytes an announce carries, which orders two announces from the same
 77 //!   destination.
 78 //! - *carrier*: one network interface the node sends and receives over, named
 79 //!   by a small integer index.
 80 //! - *transport identity hash*: the 16 bytes a transport node writes into a
 81 //!   packet header so the next node along sees who passed it on.
 82 //! - *next hop*: the neighboring node a packet is handed to on its way, named
 83 //!   in the packet header by its transport identity hash.
 84 //! - *rebroadcast*: the sending onward of an announce a transport node
 85 //!   accepted, so the mesh learns the destination beyond this node.
 86 //! - *hop count*: the byte in the packet header that rises by one at every node
 87 //!   the packet passes through.
 88 //! - *pathfinder maximum*: the hop count of 128, at and above which a packet is
 89 //!   refused.
 90 //! - *reverse entry*: the record that ties a relayed packet to the carrier it
 91 //!   arrived on and the carrier it left on, so the answering proof travels the
 92 //!   way the packet came.
 93 //! - *effect*: a record the node appends to send a frame on a carrier or arm a
 94 //!   timer.
 95 //! - *path request*: a packet asking any node that knows a path to a
 96 //!   destination to answer with one.
 97 //! - *HEADER_1*: the 19-byte header shape, carried by a packet that names no
 98 //!   node it is passing through.
 99 //! - *HEADER_2*: the 35-byte header shape, which carries the 16-byte hash of
100 //!   the node the packet is passing through.
101 
102 pub const announces = @import("announces.zig");
103 pub const discoveries = @import("discoveries.zig");
104 pub const inflight = @import("inflight.zig");
105 pub const link = @import("link/root.zig");
106 pub const links = @import("links.zig");
107 pub const path = @import("path.zig");
108 pub const relay = @import("relay.zig");
109 pub const requests = @import("requests.zig");
110 pub const retransmit = @import("retransmit.zig");
111 pub const reverse = @import("reverse.zig");
112 pub const rewrite = @import("rewrite.zig");
113 pub const State = @import("state.zig").State;