Links, channels, and resources
Overview
Above raw destination packets, Reticulum provides encrypted links for session-oriented communication. On a link you can use:
- Request and response paths
- Reliable channel messages
- Stream buffers (bzip2 compressed)
- Multi-part resource (file) transfers
Packages: pkg/link, pkg/channel, pkg/buffer, pkg/resource.
Links
A link is a bidirectional encrypted session between two destinations.
Establishing links
Outbound. Application opens a link to a destination hash that is already known from an announce or path table. The initiator stores expected_hops from the path table (PATHFINDER_M when unknown). Link-request proofs are accepted only when the proof hop count matches, or when hops were unknown at creation (RNS 1.3.8).
Inbound. Peer sends a link request. Transport dispatches to:
link.HandleIncomingLinkRequest(...)
The responder records expected_hops from the RTT packet hop field when the link becomes active.
There is no separate Transport.CreateIncomingLink helper. Incoming link requests use HandleIncomingLinkRequest directly.
Link lifecycle
LINKREQUEST -> LINKIDENTIFY -> LINKREADY -> data / channel / resource
|
+-> teardown -> LINKCLOSE
Links track RTT, keepalive, and proof exchange per protocol rules. Link.Reestablish and WatchAndReconnect support automatic recovery when Node.EnableLinkAutoReconnect or equivalent options are set.
Request and response
Register a request path on the link or destination. Handlers receive payload bytes and return a response. Timeouts apply if the handler blocks too long.
The control API bridges requests to WebSocket requestIncomingEvent and requestRespondCommand.
Path recovery
pkg/link/link_path_recovery.go handles path loss during an active link session where the protocol allows recovery.
Channel
pkg/channel provides reliable ordered message delivery inside a link.
| Concept | Description |
|---|---|
Channel |
Session over an established link |
Envelope |
Wire wrapper for channel messages |
MessageBase |
Base type for message payloads |
Python 1.3.0 fixed ghost envelopes on failing outlets. Go matches that behavior: sequence allocation and tx-ring emplace happen only after a successful outlet send, with rewind on failure. Channel accepts both transport wrapper ACTIVE status and real link ACTIVE (0x02).
Typical pattern:
- Establish link
- Create channel on link
- Send and receive
Envelopemessages
Buffer
pkg/buffer implements a stream buffer over a channel.
Use cases:
- Streaming data larger than a single packet
- bzip2-compressed streams with bomb limits matching Python 1.1.9
Entry point:
buf, err := buffer.CreateBidirectionalBuffer(link, ...)
Decompression limits protect against malicious compressed payloads. Same limits as Python reference.
Resources
pkg/resource implements multi-part file transfer.
Features:
- Advertisement phase (
Advertisement) - Hash map of parts
- RESOURCE_PRF proof flow
- bzip2 compression optional (
bzip2_compress.go) - Split advertisements when the payload exceeds
MaxEfficientSize(~1 MiB), matching Python segment chaining
Python utility rncp is ported as rgocp (CLI utilities). The primitives remain available in this package for Go applications.
See examples/resources for a minimal send/receive demo and examples/filetransfer for a directory browser.
Transfer flow at a high level:
Sender Receiver
| |
|-- resource advertisement ------->|
|<-- proof / acceptance -----------|
|-- parts ------------------------>|
|<-- proof ------------------------|
|-- next segment (if split) ------>|
|-- completion -------------------->|
Interaction with transport
Link packets use PacketTypeLink. Data packets for link payloads use contexts handled in Transport.handleTransportPacket and forwardLinkData.
The transport link table tracks which local link object owns each session hash.
Blackhole
Python 1.3.2 tears down links at LINKIDENTIFY when the remote identity is blackholed. Reticulum-Go does the same via pkg/blackhole during link identify. Federation publish and remote blackhole sources are not implemented. See Compatibility.
Testing
| Area | Location |
|---|---|
| Wire parity | tests/crossref (links, channel, buffer, resource) |
| Live link interop | tests/interop/link_live_test.go |
| Property tests | pkg/buffer/*_pbt_test.go, pkg/resource/*_pbt_test.go |
| Fuzz | pkg/link/*_fuzz_test.go |
Application guidance
Keep handlers short. Request handlers run on link goroutines. Long work should offload to worker pools and respond before timeout.
One link per peer session. Multiplex logical streams with channel or buffer instead of opening redundant links.
Check path before link open. Outbound links require a known path or successful path request.
Resource size. Respect MTU and part sizing. Large files use many parts over the same link.
Related documents
- API reference
- Identity and destinations
- Transport
- Control API for link commands over WebSocket
- Examples for file transfer and link demos
- CLI utilities for
rgocp