I'm d̶o̶n̶e̶ not even playing the game by rules I can't win at.
High-performance standalone Reticulum node & NomadNet server for embedded Linux devices, routers, SBCs, and servers
clevnode is an optimized standalone hybrid monolith (pure C + static Rust library) designed for continuous 24/7 operation as a gateway and transit router of the Reticulum network, as well as a lightweight NomadNet (Micron) page server on resource-constrained embedded routers, single-board computers (SBCs), and Linux servers (MIPS, MIPSEL, ARMv7, ARM64, x86_64, i686).
|
Etymology: C-Lev-Node = C (high-performance C wrapper) + Leviculum (network stack) + Node (standalone node). Additional wordplay: Clever Node.
- Full Reticulum Stack: Packet routing, link establishment (Links), announces, and path building.
- Asynchronous Rust Core (
leviculum): Cross-compiled with staticmusl libc, featuring dedicated low-level optimizations for 32-bit embedded architectures without an FPU (-msoft-float), as well as full native support for modern ARM and x86 systems. - C Monolith (
clevnode.c): Asynchronous worker, task queue for request processing, and pre-caching of MsgPack pages in RAM. - Traffic Transports: Operates as a transit node and gateway via the persistent I2P SAM Bridge (port 7656).
- NomadNet / Micron: Serves lightweight pages (requests for
/page/index.mu) with automatic fallback to multi-part Resource transfers when the page size exceeds the packet MTU.
The project is distributed under the terms of the AGPL-3.0-or-later license (GNU Affero General Public License v3 or any later version).
- Base parent project: Leviculum
- Original core author: Lew Palm
- Source commit of the parent repository:
808908b12b802e76e08b4a9067137061087a0d05(Sept 10, 2026) - Author of the architectural adaptation and C monolith: Ivan Svarkovsky ([email protected])
Note on source code compatibility: Significant architectural changes, optimizations, and patches have been introduced into the original
leviculumcodebase to make it run on 32-bit embedded MIPS processors without an FPU. As a result, the core source code is no longer backward compatible with the current master branch of the Leviculum repository. The modified Rust core sources are shipped directly as part of this repository (theleviculum/directory) together with the C wrapperclevnode.cand build scripts.Latest Updates in Source Code:
The most recent, cutting-edge fixes, memory optimizations, and stability patches are maintained directly in the repository source tree (mainbranch). Pre-compiled binaries in GitHub Releases represent stable milestones and may lag behind the continuous development branch. For the freshest improvements and targeted hardware tuning, compiling directly from source via./build_mips_be.shis recommended.
Note: System metrics in the tables below were measured directly on real MIPS hardware: a physical ASUS RT-AC57U V3 router (Qualcomm Atheros QCA9563 SoC, 32-bit MIPS 74Kc 775 MHz, 128 MB RAM, OpenWrt ath79, Linux kernel 3.4.103-rt119) operating 24/7 under sustained multi-peer Reticulum, clearnet, and I2P traffic with 5,000 active network identities and 18,000+ deduplication hashes.
- Process Uptime: 198,000 seconds (over 55.0 hours of uninterrupted execution).
- System Uptime: 200,000 seconds (~55.6 hours).
- Average CPU Utilization: ~22.83% under regular mesh packet forwarding, background I2P SAM sessions, and live NomadNet resource requests. Zero CPU lockups or runaway threads.
- Reliability: Confirmed absence of memory leaks, zero Out-of-Memory (OOM) kills, zero
SIGBUSexceptions, and zero Rust runtime panics.
| Metric | Measured Value | Description |
|---|---|---|
| Exact Executable Size | ~2.43 MB | Static binary with musl libc (2,432,596 bytes / 2.32 MiB) |
| VmRSS (Cold Start) | 3.7 MB | Measured right after network initialization |
| VmRSS (Under Continuous 24/7 Load) | 18.5 ‑ 22.0 MB | Stabilized resident memory under 20-30 peers and 5,000 destinations |
| VmSize / VSZ (Virtual Memory) | 19.8 ‑ 25.0 MB | Total virtual memory address space (reduced from 33.2 MB) |
| VmPeak (Peak Memory Spike) | 27.5 ‑ 30.0 MB | Peak memory during periodic 15-min database flushes (reduced from 47.8 MB) |
| VmSwap (Swap File Usage) | 0 ‑ 3.5 MB | Minimal paging under continuous multi-peer mesh routing |
The system maintains 3 active threads (plus transient background DNS resolver tasks):
- Main thread (C): Runtime environment initialization, interface registry, and the non-blocking Reticulum event dispatch loop (
Event Loop). - Worker thread (C,
pthread): Asynchronous task queue, lock-safe assembly, and serialization of NomadNet page requests (stack bounded to 128 KB). - Unified Tokio runtime worker thread (Rust core,
reticulum-node): Single cooperatively scheduled worker for all network I/O, timers, announce propagation, persistent I2P SAM tunnels, and FFI event bridging (stack bounded to 128 KB).
Real-time geographic visualization of mesh nodes and links discovered by this router is available at:
- Interactive Live Map: https://reticulum-topology-map.ivansvarkovsky.workers.dev/
Note on Architecture & Scope:
The interactive web map demonstrates live telemetry gathered by the running node. The external telemetry parser script and Cloudflare Worker infrastructure are custom, individual tools and are not distributed or included as part of this core repository.
Running clevnode permanently and autonomously on a home router requires only 3 elements:
clevnodebinary: The statically linked executable..reticulumdirectory: Located in the same directory as the executable, containingconfig.- Init startup script: (e.g.
/opt/etc/init.d/S90clevnodeunder Entware) for automatic background launch on router boot.
Storage Requirement:
During prolonged operation (months of mesh uptime, route caching, and dedup lists), the node and its runtime state require at least 15 MB of free storage space on the USB drive or router flash memory.
Directory Naming on Deployment:
The build scriptbuild_mips_be.shproduces a default configuration inclevnode/reticulum/configfor local repository convenience. When copying files to the router (e.g. into/tmp/mnt/sda1/home/lblogd/), this directory must be renamed to.reticulum(with a leading dot). This matches the binary's runtime lookup and keeps the working directory clean.
┌────────────────────────────────────────────────────────┐
│ C Wrapper (clevnode.c) │
│ - Process isolation & setsid() system call │
│ - Mutex-guarded task queue (pthread worker) │
│ - Pre-caching of index.mu in RAM (MsgPack binary) │
│ - Request-to-Resource association mapping │
└───────────────────────────┬────────────────────────────┘
│ FFI Boundary (leviculum.h)
┌───────────────────────────▼────────────────────────────┐
│ Rust Core (libleviculum.a) │
│ - Full Reticulum network stack (Packet, Link, Route) │
│ - Tokio asynchronous runtime (-Zbuild-std) │
│ - Cryptography: Curve25519, Ed25519, AES-128 │
│ - Static linking against musl libc (+soft-float) │
└────────────────────────────────────────────────────────┘
- Removal of Bluetooth (BLE) and D-Bus:
blueranddbusdependencies are disabled inCargo.toml. Theblemodule ininterfaces/mod.rsis excluded using#[cfg(any())]. Saves ~6.6 MB RAM and eliminates three idle background threads. - Exclusion of Serial, RNode, and KISS:
tokio-serialis disabled inCargo.toml. A lightweight mock moduletokio_serial.rssatisfies type references in the interface driver. - RAM Log Buffer Capping:
A ring buffer capped at 1000 lines per active descriptor was implemented inevent_log.rs. When full, older lines are evicted viabuf.remove(0). - Modular Feature Flags in Cargo:
clap,serde-pickle, andtomlare set to optional. Configured flags:cli,rpc, andtoml-config(disabled by default; only compression remains active). The INI parser remains fully intact. - Safe RPC Dummy Stub (
remote_mgmt_dummy.rs):
The originalremote_mgmt.rsis gated behind#[cfg(feature = "rpc")]. The fallbackremote_mgmt_dummy.rsreturnsNonefor remote management queries without triggering panics. - Zero-Overhead Traffic Counters (
CounterAtomic):
Atomic hardware bus locks on 32-bit MIPS are avoided by replacing interface byte counters with no-op dummy structures when RPC is disabled.
Implementation detail: Only physical interface breakdown counters (lev_interface_stats_t) are zeroed. Global node-wide transport counters (lev_transport_stats) and link metrics (lev_link_stats) remain active inside the Rust core. - Process Daemonization & Signal Tracking:
The binary issuessetsid()at startup, detaching from the controlling terminal. An advancedsigactionhandler records incoming signals alongside the sender's process ID (PID).SIGPIPEis ignored to guard against dropped peer connections. - Asynchronous Background DNS Resolution & Unconditional Boot:
- Problem: Synchronous DNS resolution (
to_socket_addrs()) during interface startup (build_client/driver/mod.rs) caused the daemon to abort withconfiguration error (-6)if any remote peer (e.g.rns.wdgwars.plor DDNS hosts) failed to resolve at boot or if WAN networking was not yet ready. - Solution: Hostname resolution was removed from the synchronous startup path and moved inside the background asynchronous reconnect loop (
tcp_client_reconnect_loopusingtokio::net::lookup_host). - Benefits:
- Unconditional startup: The node always boots reliably, bringing up local Wi-Fi, I2P, and working TCP interfaces even with no internet access.
- Dynamic background reconnect: Unresolved interfaces retry DNS queries every 5 seconds and connect automatically as soon as uplink connectivity is restored.
- Dynamic IP tracking (DDNS): Hostnames are re-resolved before each connection attempt, automatically adapting to changing peer IP addresses without process restarts.
- Problem: Synchronous DNS resolution (
- Structural Buffer & Queue Optimization (Memory Capping):
- Dedup hashlist cap (
FILE_STORAGE_PACKET_HASH_CAP): Reduced from 100,000 to 25,000 entries (saves ~3.5 MB RAM; retains enough history for 2-3 hours of transit traffic, fully preventing routing loops). - FFI event bridge queues (
node.rs): Capacities reduced from 512/256 toDEFAULT_CONTROL_CAP = 64andDEFAULT_DATA_CAP = 32. The C event loop drains events every 500 ms, keeping queues virtually empty. - Pathfinder lifespan & tags (
constants.rs): Route lifetime (PATHFINDER_EXPIRY_SECS) reduced from 7 days to 2 days, and path request tags (MAX_PATH_REQUEST_TAGS) from 32,000 to 8,000. Stale paths are evicted faster, while Reticulum reactive discovery re-queries active routes on demand. - Interface announce queues (
MAX_QUEUED_ANNOUNCES_PER_INTERFACE): Reduced from 16,384 to 512. Prevents megabytes of RAM from buffering delayed announces on throttled interfaces.
- Dedup hashlist cap (
- Storage Lifecycle & Database Retention Optimizations (
known_destinations&ratchets):- Elimination of perpetual timestamp refresh: Fixed an issue in
storage.rswhere the 15-minute flush interval (flush_interval = 900) unconditionally updated the timestamps of all known destinations tonow(e.timestamp = timestamp), preventing entries from ever expiring and ballooning the database to 17,368 entries (2.24 MB). - True event timestamps: Timestamps now update only when an actual announce arrives (
set_identity), mirroring the reference Python Reticulum design (Identity.remember). - Elimination of disk recombine on flush: Removed legacy on-disk recombination (
kd_store.load_all()) inflush_off_lock. The memory snapshot is written atomically directly to disk without reviving expired entries, matching modern Python Reticulum behavior where disk recombining is deprecated. - Automatic retention & capacity caps: Enforced
MAX_KNOWN_DESTINATIONS = 5,000andDEFAULT_IDENTITY_CAP = 5,000both in memory and during flush snapshotting. Destinations inactive for > 30 days are pruned at flush and boot. - Ratchet memory protection: Startup ratchet loading is capped to the 1,000 most recent ratchets (
MAX_LOADED_RATCHETS = 1,000), and expired files (> 30 days) are pruned from disk on boot, preventing thousands of files from exhausting RAM.
- Elimination of perpetual timestamp refresh: Fixed an issue in
- Dynamic Multi-Page Serving & Zero-Downtime Hot Reloading (NomadNet):
- On-demand
mtimecache: Page content is no longer frozen in memory at boot. An LRU cache (16 slots) checks file modification time (stat()) on every request. If a.mufile was edited or uploaded via SCP, it is reloaded and packaged into MessagePack on the fly without restarting the daemon. - Arbitrary page naming & microblog support: The C wrapper dynamically maps any requested subpath under
/page/(e.g./page/blog-post.mu,/page/about.mu) to the corresponding file inposts/, with strict path-traversal sanitization. - Automatic background registration: The event loop scans
posts/every 30 seconds, automatically registering new.mufiles with the Reticulum core without network interruption.
- On-demand
- Unified Tokio Runtime & Single-Threaded Core Scheduling:
- Elimination of duplicated Tokio runtime: Consolidated the FFI event bridge and driver network I/O into a single shared Tokio runtime instance (
reticulum-node). Eliminated the redundant second runtime (tokio-runtime-w), dropping an idle OS worker thread, a duplicate epoll instance, and redundant timer wheels. - Gated traffic counter thread: Gated
spawn_traffic_counterbehind#[cfg(feature = "rpc")], removing the 1-second waking loop and dedicated OS thread when RPC is disabled. - Clamped thread stacks: Bounded the
reticulum-nodeworker thread stack to 128 KB via.thread_stack_size(128 * 1024). Overall system threads dropped to 3, virtual memory address space (VmSize) dropped to 19.8 - 25.0 MB, and peak memory spike (VmPeak) dropped from 47.8 MB to ~27.5 MB (saving over 20 MB of peak RAM).
- Elimination of duplicated Tokio runtime: Consolidated the FFI event bridge and driver network I/O into a single shared Tokio runtime instance (
- MIPS Hardware Acceleration & Zero-Overhead Packet Deduplication:
- Curve25519 unrolled loops (
opt-level = 3): Configured package-level release profile overrides forcurve25519-dalek,ed25519-dalek, andx25519-dalek. LLVM unrolls 32-bit field multiplications, boosting link handshakes and packet verification by 30-40% on MIPS without FPU. - Direct 8-byte digest hasher (
FastHashBuilder): Replaced standard SipHash-1-3 inpacket_cachewith a transparent hasher that takes the first 8 bytes of the SHA-256 digest in a single instruction. Cuts transit packet deduplication overhead from ~250 CPU cycles to zero. - Dead-weight dependency elimination: Removed regex engine dependencies (
regex-automata,regex-syntax) and optionalizedserde_json, shrinking the binary by over 114 KB.
- Curve25519 unrolled loops (
- Security Hardening, Static Analysis & Zero-Leak Memory Verification:
- Path traversal & injection hardening: The NomadNet handler enforces strict validation on requested subpaths: rejects traversal sequences (
..), slashes, backslashes, hidden dotfiles (.env,.git,.hidden.mu), and non-.mufile extensions. Boundary checks onsnprintfprevent buffer truncation exploits. - AddressSanitizer (ASan) & UBSan audited: Validated under AddressSanitizer and UndefinedBehaviorSanitizer on x86_64 host under simulated burst loads, confirming zero buffer overflows, zero out-of-bounds reads, and zero undefined behaviors across LRU eviction and MessagePack serialization.
- LeakSanitizer (LSan) verified shutdown: Active link states, pending queue payloads, and LRU cache slots are cleanly reclaimed on daemon teardown, confirming zero memory leaks.
- Deep static analysis: Audited with
gcc -fanalyzer -Wall -Wextra -Werrorwith zero warnings, guaranteeing memory safety and absence of null-pointer dereferences in the C monolith.
- Path traversal & injection hardening: The NomadNet handler enforces strict validation on requested subpaths: rejects traversal sequences (
Official standalone static release archives are compiled and verified via QEMU for 6 hardware architectures:
- MIPS Big-Endian (
mips-unknown-linux-musl): Qualcomm Atheros AR9xxx, QCA95xx, QCA55xx (OpenWrtath79). - MIPSEL Little-Endian (
mipsel-unknown-linux-musl): MediaTek / Ralink MT7620, MT7621, MT7628 (OpenWrt/Keeneticramips). - ARMv7-A 32-bit (
armv7-unknown-linux-musleabihf): Cortex-A7/A9, Raspberry Pi 2 / Zero 2W, Orange Pi (hard-float). - ARM64 / AArch64 (
aarch64-unknown-linux-musl): Cortex-A53/A72, Raspberry Pi 3/4/5, modern ARM routers and VPS. - x86_64 (
x86_64-unknown-linux-musl): 64-bit Intel / AMD servers, PC, and VPS. - i686 (
i686-unknown-linux-musl): 32-bit x86 legacy hardware and thin clients. - Hardware FPU: Not required on MIPS/MIPSEL; soft-float math is statically linked (
-msoft-float). - Kernel Compatibility: Compiled with
musl libc, which requires a minimum of Linux 2.6.39. While 2.6.39 has not been validated on physical hardware, it is expected to function thanks to the Linux syscall ABI stability. Fully verified on Linux kernel 3.4.103-rt119. Modern kernels (4.x, 5.x, 6.x) are supported natively.
Automated Multi-Architecture Releases:
Standalone static release archives with pre-release QEMU execution verification are automatically compiled and published for all 6 target architectures in GitHub Releases.
The node uses three critical 64-byte key files:
identities/lblogd(64 bytes): Permanent keypair for the NomadNet site.identities/site.id(64 bytes): Secondary deployment identity reference..reticulum/storage/transport_identity(64 bytes): Master transport identity for the Reticulum router. Must never be deleted.
WDHJGSJFCZ3E72YE6L7LQKDKW46BHA6Q56Q*************************************************RQTWUQ=
- Identity Hash:
c1cfe6b1620ff4515f48********fa8c - NomadNet Router URL:
nomad://eeccf2849599909527d4********141 - Personal Messaging Address (LXMF):
lxmf:bff56bcc8ec6e1b49759********16b0
As long as the same lblogd key file is preserved, your NomadNet site and your LXMF messaging address remain permanent across all devices.
[reticulum]
# Node name broadcast across the network.
# If omitted, defaults to "Clevnode" (capitalized).
node_name = Router Node
# Enable forwarding of packets for other mesh nodes.
enable_transport = yes
# Expose local IPC socket for utilities (rnstatus, rnpath).
share_instance = yes
# TCP port for local IPC instances.
shared_instance_port = 37428
# Interval for writing state to disk in seconds (15 minutes).
flush_interval = 900
[logging]
# Static logging level (1 = LEV_LOG_INFO). Supported by parser.
loglevel = 1
[interfaces]
# Local Wi-Fi / Ethernet server interface for client connections.
[[Local Wi-Fi Server]]
type = TCPServerInterface
enabled = yes
listen_ip = 0.0.0.0
listen_port = 4242
# Outgoing TCP link to community clearinghouse hub.
[[WDGWars Node]]
type = TCPClientInterface
enabled = yes
target_host = rns.wdgwars.pl
target_port = 4242
bootstrap_only = yes
name = WDGWars Node
# I2P bridge interface (OPTIONAL - comment out if not using I2P).
[[I2P Bridge Interface]]
type = I2PInterface
enabled = yes
connectable = yes
discoverable = yes
discovery_name = Router Node I2P
reconnect_wait = 120
peers = wnbroeyo5kotdkq4qpitosoch4f64fiwv4uyrk7tp57w2ubthatq.b32.i2p,
fc22dfljkpt2beq3itqjkz2k7oizuythif7aa3m73okq7mqrg66q.b32.i2pReticulum communicates with I2P via SAM API (port 7656). On startup, it checks .reticulum/storage/i2p/i2p_iface_0.i2p. If absent, Reticulum generates a new private destination key (DEST GENERATE), writes it to i2p_iface_0.i2p, and computes its persistent .b32.i2p address.
With enable_transport = yes, the router bridges packets between regular TCP networks and anonymous I2P tunnels. To prevent cross-network routing:
- Set
enable_transport = no(endpoint-only mode), or - Add
mode = boundaryto interface definitions to restrict announce forwarding.
The peers listed in the config are public community beacons. Sharing them is safe and encouraged; however, do not share private .b32.i2p addresses if your service is meant to stay unlisted.
Reticulum builds path tables reactively via cryptographically signed announces. On a fresh startup, route discovery takes 5–15 minutes. Allow the node to warm up before expecting immediate responses from distant destinations.
# Install prerequisites on Ubuntu/Debian x86_64 host
sudo apt update && sudo apt install -y git curl wget gcc make tar xz-utils
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
# Standard incremental build (~2-3 seconds)
./build_mips_be.sh
# Build with extreme binary stripping
./build_mips_be.sh --sstrip
# Complete clean build
./build_mips_be.sh --clean# Transfer binary and config (masked example)
scp -P 63*** clevnode/clevnode [email protected].***:/tmp/mnt/sda1/home/lblogd/
scp -P 63*** clevnode/reticulum/config [email protected].***:/tmp/mnt/sda1/home/lblogd/.reticulum/configSample init script /opt/etc/init.d/S90clevnode:
#!/bin/sh
ENABLED=yes
PROG="clevnode"
DIR="/tmp/mnt/sda1/home/lblogd"
BIN="$DIR/$PROG"
LOG="$DIR/clevnode.log"
start() {
[ "$ENABLED" != "yes" ] && return 0
pidof "$PROG" >/dev/null && return 0
echo -n "Starting $PROG... "
cd "$DIR" || exit 1
"$BIN" > "$LOG" 2>&1 &
sleep 1
pidof "$PROG" >/dev/null && echo "OK" || echo "FAILED"
}
stop() {
echo -n "Stopping $PROG... "
killall "$PROG" 2>/dev/null
for i in 1 2; do
sleep 1
! pidof "$PROG" >/dev/null && echo "OK" && return 0
done
killall -9 "$PROG" 2>/dev/null
echo "Force killed"
}
case "$1" in
start) start ;;
stop) stop ;;
restart) stop; sleep 1; start ;;
status) pidof "$PROG" >/dev/null && echo "Running" || echo "Stopped" ;;
*) echo "Usage: $0 {start|stop|restart|status}"; exit 1 ;;
esactransport_identity: Router private key. Do not delete.packet_hashlist: Automatic ring cache (~3.6 MB cap). Self-managing.known_destinations: Route and identity directory. Can be safely deleted if disk space is low:/opt/etc/init.d/S90clevnode stop rm -f /tmp/mnt/sda1/home/lblogd/.reticulum/storage/known_destinations /opt/etc/init.d/S90clevnode start
All paths, names, and network addresses are illustrative. Systems vary depending on vendor firmware and storage setups. Code and configurations are provided as-is without warranty.
- Live Reticulum Topology Map (Ivan Svarkovsky)
- Official Reticulum Interfaces Manual [1.1.2]
- Reticulum Implementations Comparison
- Awesome Reticulum Directory
- Reticulum Network on Dead.md [1.4.3]
- Reticulum via MeshChat & Yggdrasil Guide [1.1.2]
- I2P Router Setup with Yggdrasil Guide [1.2.1]
- Official Reticulum GitHub Repository
- Leviculum Rust Core on Codeberg
- LXMF Protocol Specification
- Sideband LXMF Client
- Reticulum Articles on DevZone
Високопродуктивний автономний вузол Reticulum та сервер NomadNet для вбудованих пристроїв, роутерів та серверів
clevnode - це оптимізований автономний гібридний моноліт (чистий C + статична бібліотека Rust), розроблений для цілодобової роботи як шлюз і транзитний маршрутизатор мережі Reticulum, а також легковаговий сервер сторінок NomadNet (Micron) на вбудованих роутерах, одноплатних комп'ютерах (SBC) та серверах з обмеженими ресурсами (MIPS, MIPSEL, ARMv7, ARM64, x86_64, i686).
Етимологія: C-Lev-Node = C (швидка C-оболонка) + Leviculum (мережеве ядро) + Node (автономний вузол). Гра слів: Clever Node («Розумний вузол»).
- Повноцінний стек Reticulum: маршрутизація пакетів, встановлення з'єднань (Links), анонси та побудова шляхів.
- Асинхронне Rust-ядро (
leviculum): статично скомпільоване зmusl libc, із глибокими низькорівневими оптимізаціями для 32-бітних архітектур без FPU (-msoft-float) та повною підтримкою сучасних платформ ARM та x86. - C-моноліт (
clevnode.c): асинхронний воркер, черга задач для обробки записів, прекешування MsgPack-сторінок в ОЗУ. - Носії трафіку (Транспорт): робота як транзитного вузла та шлюзу через I2P SAM Bridge (порт 7656).
- NomadNet / Micron: обслуговування легковагових сторінок (запити
/page/index.mu) з автоматичною передачею великих сторінок у вигляді складених ресурсів (Resources) при перевищенні MTU.
Проєкт поширюється на умовах ліцензії AGPL-3.0-or-later (GNU Affero General Public License v3 або будь-якої пізнішої версії).
- Базовий батьківський проєкт: Leviculum
- Автор оригінального ядра: Lew Palm
- Вихідний коміт батьківського репозиторію:
808908b12b802e76e08b4a9067137061087a0d05 - Автор архітектурної адаптації та C-моноліту: Іван Сварковський ([email protected])
Зауваження щодо сумісності вихідного коду:
До оригінальної кодової базиleviculumбуло внесено суттєві архітектурні зміни та оптимізації для роботи на 32-бітних процесорах MIPS без апаратного FPU. Через це вихідний код ядра більше не є сумісним із поточною гілкою master батьківського репозиторію Leviculum. Модифіковане ядро Rust постачається безпосередньо у складі цього репозиторію (каталогleviculum/) разом із C-оболонкоюclevnode.cта складальними скриптами.Актуальність вихідного коду:
Найновіші та найактуальніші виправлення, оптимізації пам'яті та патчі стабільності підтримуються безпосередньо у вихідному коді репозиторію (гілкаmain). Готові скомпільовані бінарні файли в релізах GitHub фіксують окремі контрольні етапи та можуть відставати від поточного стану коду. Для отримання максимальної швидкодії та найсвіжіших виправлень рекомендується пряма компіляція з вихідних текстів за допомогою./build_mips_be.sh.
Примітка: Усі показники пам'яті, процесора та системних ресурсів у таблицях нижче виміряні безпосередньо на реальному MIPS-обладнанні - фізичному роутері ASUS RT-AC57U V3 (процесор Qualcomm Atheros QCA9563, 32-бітний MIPS 74Kc 775 МГц, 128 МБ RAM, OpenWrt ath79, ядро Linux 3.4.103-rt119) під безперервним цілодобовим навантаженням 24/7 (20-30 пірів Reticulum, клірнет та I2P, 5 000 ідентичностей у базі та 18 000+ дедуплікаційних хешів).
- Час безперервної роботи процесу: 198 000 секунд (понад 55,0 годин безперервного виконання).
- Аптайм самого роутера: 200 000 секунд (~55,6 годин).
- Середнє навантаження на процесор (CPU): ~22.83% під час обробки транзитного трафіку, сесій I2P SAM та видачі ресурсів NomadNet.
- Надійність: Повна відсутність витоків пам'яті, збоїв OOM (Out of Memory), апаратних винятків
SIGBUSчи панік рантайму Rust.
| Метрика | Виміряне значення | Опис |
|---|---|---|
| Точний розмір бінарного файлу | ~2.43 МБ | Статичний бінарник зі збіркою під musl libc (2 432 596 байт / 2.32 MiB) |
| VmRSS (холодний старт) | 3.7 МБ | Зафіксовано одразу після ініціалізації стека |
| VmRSS (під безперервним навантаженням 24/7) | 18.5 ‑ 22.0 МБ | Стабілізована резидентна пам'ять під навантаженням 20-30 пірів і 5 000 вузлів |
| VmSize / VSZ (віртуальна пам'ять) | 19.8 ‑ 25.0 МБ | Загальний простір віртуальних адрес (скорочено з 33.2 МБ) |
| VmPeak (піковий сплеск споживання) | 27.5 ‑ 30.0 МБ | Максимальне значення під час періодичного скидання бази (скорочено з 47.8 МБ) |
| VmSwap (використання swap) | 0 ‑ 3.5 МБ | Мінімальне звернення до накопичувача під транзитним навантаженням |
У системі постійно працюють 3 постійних активних потоки (плюс тимчасові сервісні завдання резолвінгу DNS):
- Головний потік (C): Ініціалізація, конфігурація та неблокуючий цикл обробки мережевих подій (
Event Loop). - Потік воркера (C,
pthread): Асинхронна черга завдань та генерація відповідей на запити сторінок NomadNet (стек обмежено до 128 КБ). - Єдиний робочий потік Tokio (Rust,
reticulum-node): Кооперативний планувальник для сокетів вводу-виводу, таймерів анонсів, постійного тунелю I2P SAM Bridge та FFI-моста (стек обмежено до 128 КБ).
Географічна візуалізація вузлів та з'єднань мережі в реальному часі, зафіксованих цим роутером, доступна за посиланням:
- Онлайн-карта топології: https://reticulum-topology-map.ivansvarkovsky.workers.dev/
Примітка щодо реалізації та меж проєкту:
Веб-карта слугує демонстрацією живої телеметрії та масштабу мережі, що проходить крізь роутер. Зовнішній скрипт експорту та інфраструктура Cloudflare Worker є індивідуальними авторськими утилітами моніторингу і не входять до складу та не поширюються в межах кодової бази цього репозиторію.
Для автономної роботи вузла на роутері потрібні лише 3 елементи:
- Виконуваний файл
clevnode: Скомпільований моноліт. - Папка
.reticulum: Розташована поруч із бінарником, містить файлconfig. - Скрипт запуску: (наприклад,
/opt/etc/init.d/S90clevnodeдля Entware) для автозапуску демона під час старту системи.
Вимоги до пам'яті накопичувача:
Під час тривалої роботи (місяці безперервної маршрутизації, збереження хешів дедуплікації та шляхів) для робочих файлів вузла необхідно щонайменше 15 МБ вільного місця на USB-флешці або диску роутера.
Важливий нюанс із назвою каталогу:
Під час збірки скриптbuild_mips_be.shстворює конфігурацію в папціclevnode/reticulum/config. Під час перенесення на роутер (наприклад, у каталог/tmp/mnt/sda1/home/lblogd/) ця папка обов'язково має бути перейменована на.reticulum(із крапкою на початку).
┌────────────────────────────────────────────────────────┐
│ C-оболонка (clevnode.c) │
│ - Керування процесом та системний виклик setsid() │
│ - Черга завдань на м'ютексах (pthread worker) │
│ - Попереднє кешування index.mu в ОЗП (MsgPack) │
│ - Зв'язування запитів: Request -> Resource │
└───────────────────────────┬────────────────────────────┘
│ FFI-межа (leviculum.h)
┌───────────────────────────▼────────────────────────────┐
│ Rust-ядро (libleviculum.a) │
│ - Мережевий стек Reticulum (Packet, Link, Route) │
│ - Асинхронний рантайм Tokio (-Zbuild-std) │
│ - Криптографія: Curve25519, Ed25519, AES-128 │
│ - Статична лінковка з musl libc (+soft-float) │
└────────────────────────────────────────────────────────┘
- Видалення Bluetooth (BLE) та D-Bus:
Бібліотекиbluerтаdbusвимкнено вCargo.toml. Модульbleізольовано через#[cfg(any())]. Заощаджено ~6.6 МБ ОЗП та вимкнено 3 зайві фонові потоки. - Вилучення Serial, RNode та KISS:
Залежністьtokio-serialприбрано. Легковаговий модуль-заглушкаtokio_serial.rsзабезпечує сумісність типів у драйвері. - Обмеження буферів логів в ОЗП:
Уevent_log.rsвстановлено жорсткий ліміт у 1000 рядків на дескриптор. Старі рядки видаляються черезbuf.remove(0), що запобігає переповненню пам'яті. - Модульна система Cargo Feature Flags:
Бібліотекиclap,serde-pickleтаtomlзроблені опціональними. Створено прапорціcli,rpcтаtoml-config. Робота з форматом INI збережена повністю. - Безпечна заглушка RPC (
remote_mgmt_dummy.rs):
Модульremote_mgmt.rsвимкнено прапорцем#[cfg(feature = "rpc")]. Заглушкаremote_mgmt_dummy.rsповертаєNoneдля запитів віддаленого керування, усуваючи паніки. - Оптимізація лічильників (
CounterAtomic, Zero-Overhead):
Усунуто атомарні блокування шини на 32-бітній архітектурі MIPS.
Нюанс: Вирізано лише деталізацію по фізичних інтерфейсах (lev_interface_stats_t). Загальна статистика вузла (lev_transport_stats) та каналів (lev_link_stats) працює всередині ядра, але в C-коді навмисно не виводиться для швидкодії. - Демонізація та перехоплення сигналів:
Вбудовано викликsetsid(), що повністю від'єднує процес від TTY-терміналу та унеможливлює випадкове завершення поCtrl+C. Обробникsigactionфіксує PID процесу-ініціатора сигналуSIGTERM. СигналSIGPIPEігнорується. - Асинхронне розпізнавання DNS та безперервний запуск:
- Проблема: Синхронний резолвінг DNS (
to_socket_addrs()) на етапі ініціалізації інтерфейсів призводив до аварійного завершення роботи демона з помилкоюconfiguration error (-6), якщо віддалений пір (наприклад,rns.wdgwars.plабо DDNS) був недоступний при старті або WAN-інтерфейс ще не піднявся. - Рішення: Резолвінг доменних імен перенесено з етапу ініціалізації всередину фонового асинхронного циклу повторного підключення (
tcp_client_reconnect_loopчерезtokio::net::lookup_host). - Переваги:
- Безперервний запуск: Нода гарантовано стартує завжди, успішно піднімаючи всі доступні локальні інтерфейси (Wi-Fi, I2P, локальні TCP) навіть без інтернету на роутері.
- Динамічне перепідключення: Проблемні інтерфейси резолвлять свої домени у фоні кожні 5 секунд і автоматично підключаються, щойно мережа відновлюється.
- Відстеження зміни IP (DDNS): DNS резолвиться перед кожною спробою з'єднання, автоматично реагуючи на зміну динамічної IP-адреси віддаленого піра.
- Проблема: Синхронний резолвінг DNS (
- Оптимізація структурних буферів та черг в ОЗП:
- Кеш дедуплікації пакетів (
FILE_STORAGE_PACKET_HASH_CAP): Зменшено зі 100 000 до 25 000 записів (економія ~3.5 МБ ОЗП; зберігає історію за 2-3 години транзиту для повного захисту від петель). - Черги моста подій FFI (
node.rs): Місткість черг C-Rust моста зменшено з 512/256 доDEFAULT_CONTROL_CAP = 64таDEFAULT_DATA_CAP = 32. C-цикл обробляє події кожні 500 мс, тому черги залишаються практично порожніми. - Час життя шляхів і тегів (
constants.rs): Термін придатності маршруту (PATHFINDER_EXPIRY_SECS) скорочено з 7 діб до 2 діб, а ліміт тегів (MAX_PATH_REQUEST_TAGS) - з 32 000 до 8 000. - Черги анонсів інтерфейсів (
MAX_QUEUED_ANNOUNCES_PER_INTERFACE): Зменшено з 16 384 до 512, що усуває буферизацію тисяч анонсів на шейпованих каналах.
- Кеш дедуплікації пакетів (
- Оптимізація життєвого циклу сховища та ліміти бази (
known_destinationsтаratchets):- Виправлення бага нескінченного оновлення: У
storage.rsліквідовано цикл уtake_flush_snapshot, який кожні 15 хвилин (flush_interval = 900) перезаписував таймстампи абсолютно всіх записів на поточний час (e.timestamp = now), через що база розросталася без обмежень (досягаючи 17 368 записів і 2.24 МБ). - Справжні таймстампи подій: Таймстамп фіксується лише при фактичному надходженні анонсу (
set_identity), строго відповідно до еталону Python Reticulum (Identity.remember). - Ліквідація злиття з диском при скиданні: Видалено рудимент перечитування диска (
kd_store.load_all()) уflush_off_lock. Снапшот пам'яті записується на диск напряму й атомарно без повторного воскресіння видалених записів, що відповідає актуальній архітектурі Python Reticulum. - Автоматична очистка та ліміти: Запроваджено ліміт
MAX_KNOWN_DESTINATIONS = 5 000таDEFAULT_IDENTITY_CAP = 5 000в пам'яті та безпосередньо при створенні снапшота для диска. Записи, старіші за 30 днів, автоматично відсікаються при збереженні та старті. - Кешування ратчетів (
MAX_LOADED_RATCHETS = 1 000): При старті в пам'ять завантажуються не більше 1 000 найсвіжіших ратчетів, а застарілі файли (> 30 днів) автоматично видаляються з накопичувача.
- Виправлення бага нескінченного оновлення: У
- Динамічне обслуговування багатьох сторінок та гаряче оновлення без перезапуску (NomadNet):
- Ледачий кеш за часом модифікації (
mtime): Вміст сторінок більше не фіксується в ОЗП намертво при старті. LRU-кэш (16 слотів) перевіряє системнийstat()при кожному реальному зверненні. Якщо файл на диску було змінено, він автоматично перечитується на льоту без перезапуску демона. - Підтримка мікроблогу та довільних імен сторінок: C-оболонка динамічно зіставляє будь-які запити в межах
/page/(наприклад,/page/blog-post.mu,/page/about.mu) з файлами в папціposts/із захистом від path-traversal. - Фонова автореєстрація нових сторінок: Цикл подій кожні 30 секунд сканує каталог
posts/і автоматично реєструє нові.muфайли в ядрі Reticulum без розриву транзитних з'єднань.
- Ледачий кеш за часом модифікації (
- Об'єднання рантаймів Tokio та ліквідація зайвих потоків ОС:
- Ліквідація дублюючого екземпляра Tokio: FFI-міст подій та мережевий ввід/вивід драйвера об'єднані в єдиний рантайм Tokio (
reticulum-node). Усунуто окремий потік воркера (tokio-runtime-w), дублюючий epoll та зайві таймерні колеса. - Відключення фонового лічильника швидкості: Запуск потоку
spawn_traffic_counterізольовано під#[cfg(feature = "rpc")], усуваючи щосекундні перемикання контексту процесора. - Фіксація стека воркера: Стек воркера
reticulum-nodeобмежено до 128 КБ (thread_stack_size(128 * 1024)). Кількість постійних потоків процесу скорочено до 3, віртуальне адресне середовище (VmSize) впало до 19.8 - 25.0 МБ, а піковий сплеск пам'яті (VmPeak) скоротився з 47.8 МБ до ~27.5 МБ (економія понад 20 МБ пікового ОЗП).
- Ліквідація дублюючого екземпляра Tokio: FFI-міст подій та мережевий ввід/вивід драйвера об'єднані в єдиний рантайм Tokio (
- Апаратна оптимізація MIPS та миттєва дедуплікація пакетів:
- Розгортання циклів Curve25519 (
opt-level = 3): Для пакетівcurve25519-dalek,ed25519-dalekтаx25519-dalekувімкнено максимальну оптимізацію в профіліrelease. Компілятор розгортає 32-бітну арифметику полів, прискорюючи рукостискання Link та перевірку підписів на 30-40% на MIPS без FPU. - Прямий 8-байтний хешер (
FastHashBuilder): Стандартний SipHash-1-3 уpacket_cacheзамінено на прозорий хешер, що зчитує перші 8 байт SHA-256 за 1 інструкцію. Накладні витрати CPU на дедуплікацію транзитних пакетів зведено до нуля. - Вирізання мертвого коду: Повністю видалено бібліотеки регулярних виразів (
regex-automata,regex-syntax) та зроблено опціональнимserde_json, заощадивши понад 114 КБ розміру бінарника.
- Розгортання циклів Curve25519 (
- Посилення безпеки, статичний аналіз та верифікація пам'яті (Zero Leaks):
- Захист від Path Traversal та ін'єкцій: Обробник NomadNet здійснює сувору валідацію вхідних шляхів: відхиляє послідовності обходу каталогів (
..), прямі та зворотні слеші, приховані системні файли (.env,.git,.hidden.mu) та розширення, відмінні від.mu. Перевірка межsnprintfвиключає атаки на основі усічення шляхів. - Верифікація під AddressSanitizer (ASan) та UBSan: Проведено повний аудит під санітизаторами пам'яті на x86_64 хості: підтверджено 0 переповнень буфера, 0 виходів за межі виділеної пам'яті та 0 випадків невизначеної поведінки при LRU-ротації.
- Повне звільнення пам'яті (LeakSanitizer): Усі активні стани з'єднань Link, черги відповідей та слоти LRU-кешу гарантовано звільняються при зупинці процесу, забезпечуючи нульові витоки пам'яті.
- Глибокий статичний аналіз: Код перевірено за допомогою
gcc -fanalyzer -Wall -Wextra -Werrorбез жодного попередження, гарантуючи коректність роботи з вказівниками.
- Захист від Path Traversal та ін'єкцій: Обробник NomadNet здійснює сувору валідацію вхідних шляхів: відхиляє послідовності обходу каталогів (
Офіційні автономні статичні релізні архіви збираються та тестуються через QEMU для 6 апаратних архітектур:
- MIPS Big-Endian (
mips-unknown-linux-musl): Qualcomm Atheros AR9xxx, QCA95xx, QCA55xx (таргет OpenWrtath79). - MIPSEL Little-Endian (
mipsel-unknown-linux-musl): MediaTek / Ralink MT7620, MT7621, MT7628 (OpenWrt/Keeneticramips). - ARMv7-A 32-bit (
armv7-unknown-linux-musleabihf): Cortex-A7/A9, Raspberry Pi 2 / Zero 2W, Orange Pi (hard-float). - ARM64 / AArch64 (
aarch64-unknown-linux-musl): Cortex-A53/A72, Raspberry Pi 3/4/5, сучасні ARM-роутери та VPS. - x86_64 (
x86_64-unknown-linux-musl): 64-бітні сервери Intel / AMD, ПК та VPS. - i686 (
i686-unknown-linux-musl): 32-бітні x86 платформи та тонкі клієнти. - Апаратний FPU: Не потрібен на MIPS/MIPSEL; розрахунки ведуться програмно завдяки
-msoft-float. - Сумісність з ядрами Linux: Бінарник зібраний із
musl libc, яка потребує ядра Linux 2.6.39 або новішого. На версії 2.6.39 робота прямо не перевірялася, але має забезпечуватися стабільністю системних викликів. Підтверджено бездоганну роботу на ядрі 3.4.103-rt119. Ядра 4.x, 5.x та 6.x підтримуються архітектурно.
Автоматичні мультиплатформенні релізи:
Автономні статичні релізні архіви із верифікацією запуску через QEMU автоматично збираються та публікуються для всіх 6 цільових архітектур у розділі GitHub Releases.
identities/lblogd(64 байти): Постійний ключ вузла сайту NomadNet.identities/site.id(64 байти): Службовий ідентифікатор сайту..reticulum/storage/transport_identity(64 байти): Головний ключ маршрутизатора (паспорт вузла). Видаляти категорично заборонено.
WDHJGSJFCZ3E72YE6L7LQKDKW46BHA6Q56Q*************************************************RQTWUQ=
- Крипто-паспорт (Identity Hash):
c1cfe6b1620ff4515f48********fa8c - Адреса сайту в NomadNet:
nomad://eeccf2849599909527d4********141 - Персональна пошта/месенджер (LXMF):
lxmf:bff56bcc8ec6e1b49759********16b0
Доки ви зберігаєте один і той самий файл lblogd, адреса сайту та поштова адреса LXMF залишатимуться постійними на всіх ваших пристроях.
[reticulum]
# Назва вузла в мережі.
# Якщо рядок відсутній, застосовується дефолтна назва з коду: "Clevnode" (з великої літери).
node_name = Router Node
# Дозвіл транзитної маршрутизації пакетів сторонніх вузлів.
enable_transport = yes
# Дозвіл локальним утилітам підключатися до активного стека.
share_instance = yes
# Порт TCP для IPC-взаємодії утиліт rnstatus/rnpath.
shared_instance_port = 37428
# Періодичність збереження стану на диск у секундах (15 хвилин).
flush_interval = 900
[logging]
# Базовий рівень логів (1 = LEV_LOG_INFO).
loglevel = 1
[interfaces]
# Локальний серверний інтерфейс для домашньої мережі.
[[Local Wi-Fi Server]]
type = TCPServerInterface
enabled = yes
listen_ip = 0.0.0.0
listen_port = 4242
# Вихідне TCP-з'єднання з публічним хабом спільноти.
[[WDGWars Node]]
type = TCPClientInterface
enabled = yes
target_host = rns.wdgwars.pl
target_port = 4242
bootstrap_only = yes
name = WDGWars Node
# Інтерфейс мережі I2P (ОПЦІЙНИЙ - закоментуйте, якщо I2P не потрібен).
[[I2P Bridge Interface]]
type = I2PInterface
enabled = yes
connectable = yes
discoverable = yes
discovery_name = Router Node I2P
reconnect_wait = 120
peers = wnbroeyo5kotdkq4qpitosoch4f64fiwv4uyrk7tp57w2ubthatq.b32.i2p, fc22dfljkpt2beq3itqjkz2k7oizuythif7aa3m73okq7mqrg66q.b32.i2pReticulum спілкується з I2P через SAM API (порт 7656). Під час старту перевіряється .reticulum/storage/i2p/i2p_iface_0.i2p. Якщо файлу немає, створюється новий закритий ключ (DEST GENERATE), зберігається на диск, і обчислюється постійна адреса .b32.i2p.
Параметр enable_transport = yes робить роутер транзитним мостом між відкритим інтернетом та тунелями I2P. Для повної ізоляції мереж:
- Виставте
enable_transport = no(режим виключно кінцевого пристрою), або - Додайте
mode = boundaryдо налаштувань інтерфейсу, щоб зупинити проходження анонсів.
Адреси пірів у конфігурації - це публічні хаби спільноти, їх поширення безпечне. Проте не публікуйте власну адресу .b32.i2p, якщо ваш вузол призначений лише для приватного користування.
Побудова карти мережі в Reticulum здійснюється реактивно на базі криптографічних анонсів. Під час холодного старту таблиця маршрутів порожня, а побудова тунелів I2P триває кілька хвилин. Надайте роутеру 5–15 хвилин після запуску для первинної синхронізації та стабілізації маршрутів.
# Встановлення вимог на хості Ubuntu/Debian x86_64
sudo apt update && sudo apt install -y git curl wget gcc make tar xz-utils
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
# Швидке інкрементальне складання (~2-3 секунди)
./build_mips_be.sh
# Складання з екстремальним стрипінгом sstrip
./build_mips_be.sh --sstrip
# Повне очищення та збирання з нуля
./build_mips_be.sh --clean# Перенесення бінарника та конфігурації (приклад із маскуванням)
scp -P 63*** clevnode/clevnode [email protected].***:/tmp/mnt/sda1/home/lblogd/
scp -P 63*** clevnode/reticulum/config [email protected].***:/tmp/mnt/sda1/home/lblogd/.reticulum/configСкрипт служби автозапуску /opt/etc/init.d/S90clevnode:
#!/bin/sh
ENABLED=yes
PROG="clevnode"
DIR="/tmp/mnt/sda1/home/lblogd"
BIN="$DIR/$PROG"
LOG="$DIR/clevnode.log"
start() {
[ "$ENABLED" != "yes" ] && return 0
pidof "$PROG" >/dev/null && return 0
echo -n "Starting $PROG... "
cd "$DIR" || exit 1
"$BIN" > "$LOG" 2>&1 &
sleep 1
pidof "$PROG" >/dev/null && echo "OK" || echo "FAILED"
}
stop() {
echo -n "Stopping $PROG... "
killall "$PROG" 2>/dev/null
for i in 1 2; do
sleep 1
! pidof "$PROG" >/dev/null && echo "OK" && return 0
done
killall -9 "$PROG" 2>/dev/null
echo "Force killed"
}
case "$1" in
start) start ;;
stop) stop ;;
restart) stop; sleep 1; start ;;
status) pidof "$PROG" >/dev/null && echo "Running" || echo "Stopped" ;;
*) echo "Usage: $0 {start|stop|restart|status}"; exit 1 ;;
esactransport_identity: Головний ключ роутера. Не видаляти.packet_hashlist: Автоматичний кільцевий кеш (~3.6 МБ). Очищення не потребує.known_destinations: База адрес і маршрутів. Якщо на флешці бракує місця, можна скинути:/opt/etc/init.d/S90clevnode stop rm -f /tmp/mnt/sda1/home/lblogd/.reticulum/storage/known_destinations /opt/etc/init.d/S90clevnode start
Усі шляхи до каталогів, назви та мережеві параметри є індивідуальними для конкретного тестового стенда. Інформація надається виключно в ознайомчих цілях без гарантій будь-якого роду.
- Онлайн-карта топології Reticulum (Іван Сварковський)
- Офіційне керівництво з інтерфейсів Reticulum [1.1.2]
- Таблиця реалізацій стека Reticulum
- Каталог проєктів Awesome Reticulum
- Документація з Reticulum на Dead.md [1.4.3]
- Налаштування Reticulum через MeshChat та Yggdrasil [1.1.2]
- Налаштування I2P роутера через мережу Yggdrasil [1.2.1]
- Офіційний репозиторій Reticulum на GitHub
- Репозиторій ядра Leviculum на Codeberg
- Специфікація протоколу LXMF
- Клієнт Sideband для LXMF
- Статті про Reticulum на DevZone
Высокопроизводительный автономный узел Reticulum и сервер NomadNet для встраиваемых устройств, роутеров и серверов
clevnode - это оптимизированный автономный гибридный монолит (чистый Си + статическая библиотека на Rust), созданный для постоянной круглосуточной работы в качестве шлюза и транзитного маршрутизатора сети Reticulum, а также легковесного сервера страниц NomadNet (Micron) на встраиваемых роутерах, микрокомпьютерах (SBC) и серверах (MIPS, MIPSEL, ARMv7, ARM64, x86_64, i686).
Этимология: C-Lev-Node = C (производительная Си-оболочка) + Leviculum (сетевой стек) + Node (автономный узел). Дополнительная смысловая игра слов: Clever Node («Умный узел»).
- Полноценный стек Reticulum: маршрутизация пакетов, установление соединений (Links), анонсы и построение путей.
- Асинхронное Rust-ядро (
leviculum): статически скомпилированное сmusl libc, с глубокими низкоуровневыми оптимизациями для 32-битных встраиваемых платформ без FPU (-msoft-float) и полноценной поддержкой современных процессоров ARM и x86. - C-монолит (
clevnode.c): асинхронный воркер, очередь задач для обработки запросов, прекэширование MsgPack-страниц в ОЗУ. - Носителели трафика (Транспорт): работа в качестве транзитного узла и шлюза через I2P SAM Bridge (порт 7656).
- NomadNet / Micron: обслуживание легковесных страниц (запросы
/page/index.mu) с автоматической передачей больших страниц в виде составных ресурсов (Resources) при превышении MTU.
Проект распространяется на условиях лицензии AGPL-3.0-or-later (GNU Affero General Public License v3 или более поздней версии).
- Базовый родительский проект: Leviculum
- Автор оригинального ядра: Lew Palm
- Исходный коммит родительского репозитория:
808908b12b802e76e08b4a9067137061087a0d05 - Автор архитектурной адаптации и Си-монолита: Иван Сварковский ([email protected])
Замечание о совместимости исходного кода:
В оригинальную кодовую базуleviculumбыли внесены существенные архитектурные изменения, оптимизации и патчи для работы на 32-битных встраиваемых MIPS-процессорах без FPU. В связи с этим исходный код ядра более не является обратно совместимым с актуальной веткой master репозитория Leviculum. Модифицированные исходные коды Rust-ядра поставляются непосредственно в составе данного репозитория (каталогleviculum/) вместе с Си-оболочкойclevnode.cи скриптами сборки.Актуальность исходного кода:
Самые свежие и последние изменения, оптимизации памяти и патчи стабильности находятся непосредственно в исходном коде репозитория (веткаmain). Готовые скомпилированные бинарники в релизах GitHub фиксируют контрольные версии и могут отставать от текущего состояния разработки. Для получения наилучшей производительности и самых свежих исправлений рекомендуется самостоятельная сборка из исходников с помощью./build_mips_be.sh.
Примечание: Все показатели памяти, процессора и системных ресурсов в таблицах ниже измерены непосредственно на реальном MIPS-оборудовании - физическом роутере ASUS RT-AC57U V3 (процессор Qualcomm Atheros QCA9563, 32-битный MIPS 74Kc 775 МГц, 128 МБ RAM, OpenWrt ath79, ядро Linux 3.4.103-rt119) под непрерывной круглосуточной нагрузкой 24/7 (20-30 пиров Reticulum, клирнет и I2P, 5 000 адресатов в базе и 18 000+ дедупликационных хешей).
- Время работы процесса
clevnode: 198 000 секунд (свыше 55,0 часов непрерывного исполнения). - Общий аптайм роутера: 200 000 секунд (~55,6 часов).
- Средняя утилизация CPU: ~22.83% под сетевой нагрузкой маршрутизации, фоновым сессиям I2P SAM и раздаче ресурсов NomadNet. Полное отсутствие зависаний и фонового перегрева ядра.
- Надежность: Подтверждено полное отсутствие утечек памяти, сбоев OOM (Out of Memory), аппаратных исключений
SIGBUSи паник рантайма Rust.
| Метрика | Измеренное значение | Описание |
|---|---|---|
| Точный размер исполняемого файла | ~2.43 МБ | Статический бинарник со сборкой под musl libc (2 432 596 байт / 2.32 MiB) |
| VmRSS (холодный старт) | 3.7 МБ | Зафиксировано сразу после инициализации стека |
| VmRSS (под непрерывной нагрузкой 24/7) | 18.5 ‑ 22.0 МБ | Стабилизированная резидентная память под нагрузкой 20-30 пиров и 5 000 узлов |
| VmSize / VSZ (объем виртуальной памяти) | 19.8 ‑ 25.0 МБ | Общее виртуальное адресное пространство процесса (снижено с 33.2 МБ) |
| VmPeak (пиковый всплеск потребления) | 27.5 ‑ 30.0 МБ | Максимальное значение во время периодического сброса базы (снижено с 47.8 МБ) |
| VmSwap (использование файла подкачки) | 0 ‑ 3.5 МБ | Минимальное обращение к свопу под постоянной транзитной нагрузкой |
В системе постоянно активно 3 постоянных потока (плюс временные сервисные задачи резолвинга DNS):
- Основной поток (C): Инициализация структур, регистрация интерфейсов и главный неблокирующий цикл опроса сетевых событий (
Event Loop). - Поток воркера (C,
pthread): Асинхронная очередь задач, потокобезопасная компоновка и отдача ответов на входящие запросы страниц NomadNet (стек ограничен до 128 КБ). - Единый рабочий поток рантайма Tokio (Rust-ядро,
reticulum-node): Кооперативный планировщик для сетевого ввода-вывода (I/O) сокетов, таймеров анонсов, постоянного туннеля I2P SAM Bridge и FFI-моста событий (стек ограничен до 128 КБ).
Географическая визуализация узлов и соединений сети в реальном времени, зафиксированных данным роутером, доступна по ссылке:
- Онлайн-карта топологии: https://reticulum-topology-map.ivansvarkovsky.workers.dev/
Примечание об архитектуре и границах проекта:
Веб-карта служит наглядной демонстрацией телеметрии и масштаба сети, проходящей сквозь данный роутер. Внешний скрипт экспорта данных и инфраструктура Cloudflare Worker являются индивидуальными пользовательскими утилитами мониторинга и не входят в состав и не распространяются в рамках кодовой базы этого репозитория.
Для полноценной и автономной работы узла на роутере пользователю необходим минимальный комплект из 3 элементов:
- Бинарный файл
clevnode: Сам исполняемый файл. - Папка
.reticulumс файломconfigвнутри: Лежащая в той же директории, что и бинарник. - Скрипт запуска: (например,
/opt/etc/init.d/S90clevnodeдля Entware) для автоматического старта в фоне при включении роутера.
Требования к объему свободного места:
В условиях продолжительной работы (многомесячная маршрутизация, сохранение маршрутов, кэш дедупликации) для всех рабочих файлов узла на флешке роутера необходимо не менее 15 МБ свободного места.
Важный нюанс по именованию директорий:
При сборке скриптbuild_mips_be.shсоздает дефолтный конфиг в открытой папкеclevnode/reticulum/configдля локального удобства. При переносе на роутер (в рабочую директорию, например,/tmp/mnt/sda1/home/lblogd/) папка должна быть переименована в скрытую.reticulum(с точкой в начале), что полностью соответствует ожиданиям бинарника и не захламляет домашний каталог.
┌────────────────────────────────────────────────────────┐
│ Си-оболочка (clevnode.c) │
│ - Управление процессами, вызовы setsid() │
│ - Потокобезопасная очередь задач (pthread worker) │
│ - Предварительное кэширование index.mu в ОЗУ (MsgPack)│
│ - Связывание входящих запросов: Request -> Resource │
└───────────────────────────┬────────────────────────────┘
│ FFI-граница (leviculum.h)
┌───────────────────────────▼────────────────────────────┐
│ Rust-ядро (libleviculum.a) │
│ - Полный сетевой стек Reticulum (Packet, Link, Route) │
│ - Асинхронный рантайм Tokio (-Zbuild-std) │
│ - Криптография: Curve25519, Ed25519, AES-128 │
│ - Статическая линковка musl libc (+soft-float) │
└────────────────────────────────────────────────────────┘
- Полное удаление зависимостей Bluetooth (BLE) и D-Bus:
Библиотекиbluerиdbusзакомментированы вCargo.toml. Модульbleвinterfaces/mod.rsизолирован через#[cfg(any())]. Освобождено ~6.6 МБ оперативной памяти и исключен запуск трех фоновых потоков опроса шин. - Исключение Serial, RNode и KISS:
Зависимостьtokio-serialотключена вCargo.toml. Написан мок-модульtokio_serial.rsдля сохранения строгой совместимости типов в драйвере. Исключены системные прерывания на опрос TTY-портов. - Лимитирование буферов логов в оперативной памяти:
Вevent_log.rsвнедрен кольцевой буфер с жестким лимитом в 1000 строк на активный дескриптор. При превышении лимита старые записи вытесняются методомbuf.remove(0), защищая роутер от Out-of-Memory при длительной непрерывной работе. - Модульная система Cargo-фич (Feature Flags):
Библиотекиclap,serde-pickleиtomlсделаны опциональными. Созданы флагиcli,rpcиtoml-config(по умолчанию отключены, в default оставлена только компрессия). Парсер INI-конфигураций оставлен полностью функциональным. - Безопасная заглушка RPC (
remote_mgmt_dummy.rs):
Оригинальный модульremote_mgmt.rsизолирован флагом#[cfg(feature = "rpc")]. Добавлен модульremote_mgmt_dummy.rs, возвращающий безопасныйNoneна входящие запросы управления. Это устранило паники рантайма при сканировании ноды внешними утилитами. - Оптимизация счетчиков трафика (
CounterAtomic, Zero-Overhead):
Исключены накладные расходы на блокирующие атомарные синхронизации шины памяти на 32-битной архитектуре MIPS.
Важная деталь реализации: Вырезана только детализация трафика по физическим интерфейсам (lev_interface_stats_t). При этом глобальный подсчет трафика всего узла (lev_transport_stats) и статистика каналов/соединений (lev_link_stats) продолжают полноценно функционировать внутри ядра библиотеки. В Си-кодеclevnode.cпромежуточный сбор и вывод этой статистики намеренно не производятся ради максимального снижения накладных расходов. - Пошаговое логирование, демонизация и отвязка от TTY:
Вclevnode.cвстроен системный вызовsetsid(): процесс отвязывается от терминала и запускается в новой независимой сессии, что исключает падение узла по сигналуSIGINT(Ctrl+C) при просмотре логов. Обработчикsigaction(SA_SIGINFO) перехватывает сигналSIGTERMи выводит в лог точный PID процесса-отправителя команды. СигналSIGPIPEигнорируется. - Асинхронное разрешение DNS и непрерывный запуск:
- Проблема: Синхронный резолвинг DNS (
to_socket_addrs()) на этапе инициализации интерфейсов (build_client/driver/mod.rs) приводил к падению всего демона с ошибкойconfiguration error (-6), если хотя бы один удаленный пир (например,rns.wdgwars.plили DDNS) был временно недоступен или сетевой стек роутера еще не поднял интернет на старте. - Решение: Резолвинг доменных имен перенесен из этапа инициализации внутрь фонового асинхронного цикла переподключения (
tcp_client_reconnect_loopчерезtokio::net::lookup_host). - Преимущества:
- Непрерывный запуск: Нода гарантированно стартует всегда, поднимая все локальные и работающие интерфейсы (Wi-Fi, I2P, локальные TCP), даже при полном отсутствии интернета на роутере.
- Динамическое переподключение: Проблемные интерфейсы пытаются резолвить свои домены в фоне каждые 5 секунд и подключаются автоматически, как только сеть восстанавливается.
- Корректная обработка смены IP (DDNS): Так как DNS резолвится заново перед каждой попыткой соединения, узел корректно обрабатывает смену динамического IP удаленного узла (например,
zer0bitz.ddns.net) и не зависает на старом адресе.
- Проблема: Синхронный резолвинг DNS (
- Оптимизация структурных буферов и очередей (Memory Capping):
- Лимит кэша дедупликации пакетов (
FILE_STORAGE_PACKET_HASH_CAP): Снижен со 100 000 до 25 000 записей. Экономит ~3.5 МБ ОЗУ; 25k записей при транзитном трафике обеспечивают 2-3 часа полной защиты от петель маршрутизации. - Очереди событий FFI (
node.rs): Емкость очередей моста C-Rust снижена с 512/256 доDEFAULT_CONTROL_CAP = 64иDEFAULT_DATA_CAP = 32. Си-цикл немедленно вычитывает события каждые 500 мс, поэтому в очередях редко накапливается более 5-10 элементов. - Время жизни путей (
PATHFINDER_EXPIRY_SECS): Сокращено с 7 суток до 2 суток, а лимит тегов запросов путей (MAX_PATH_REQUEST_TAGS) - с 32 000 до 8 000. В динамичной сети пути старше 2 суток часто недействительны, а реактивный протокол Reticulum штатно обновляет их черезPATH_REQUEST. - Очереди анонсов интерфейсов (
MAX_QUEUED_ANNOUNCES_PER_INTERFACE): Снижены с 16 384 до 512. Устраняет буферизацию тысяч устаревающих анонсов на шейпированных каналах (2% полосы).
- Лимит кэша дедупликации пакетов (
- Оптимизация жизненного цикла хранилища и лимиты базы (
known_destinations&ratchets):- Ликвидация бага бесконечного омоложения: В
storage.rsустранен ошибочный цикл вtake_flush_snapshot, который каждые 15 минут (flush_interval = 900) перезаписывал таймстамп абсолютно всех записей на текущий (e.timestamp = now), из-за чего адреса никогда не старели, а база раздулась до 17 368 записей (2.24 МБ). - Истинные таймстампы событий: Таймстамп теперь фиксируется строго в момент реального приема анонса (
set_identity), полностью соответствуя поведению эталонного Python Reticulum (Identity.remember). - Ликвидация слияния с диском при сбросе: Удален устаревший вызов перечитывания диска (
kd_store.load_all()) вflush_off_lock. Снапшот памяти сохраняется на диск напрямую и атомарно без воскрешения старых записей, в точном соответствии с актуальным Python Reticulum, где слияние с кэшем на диске объявлено устаревшим. - Автоматическая очистка и лимиты: Введен лимит
MAX_KNOWN_DESTINATIONS = 5 000иDEFAULT_IDENTITY_CAP = 5 000в памяти и при формировании снапшота на диск. Записи старше 30 дней автоматически вычищаются при старте и сохранении. - Кэширование ратчетов (
MAX_LOADED_RATCHETS = 1 000): При старте в память загружаются не более 1 000 свежих ратчетов, а просроченные файлы (> 30 дней) автоматически удаляются с накопителя при загрузке.
- Ликвидация бага бесконечного омоложения: В
- Динамическая раздача страниц и горячее обновление без перезапуска (NomadNet):
- Ленивый кэш по времени модификации (
mtime): Контент страниц больше не фиксируется в ОЗУ намертво при старте. LRU-кэш (16 слотов) проверяет системныйstat()при каждом реальном запросе клиента. Если файл на диске был изменен, он автоматически перечитывается на лету без перезапуска демона. - Поддержка микроблога и любых имен страниц: Си-оболочка динамически сопоставляет любые входящие запросы в пределах префикса
/page/(например,/page/blog-post.mu,/page/about.mu) с файлами в папкеposts/с защитой от path-traversal. - Фоновая авторегистрация новых страниц: Главный цикл каждые 30 секунд сканирует каталог
posts/и автоматически регистрирует новые.muфайлы в ядре Reticulum без разрыва транзитных соединений.
- Ленивый кэш по времени модификации (
- Объединение рантаймов Tokio и ликвидация лишних системных потоков:
- Ликвидация дублирующего экземпляра Tokio: FFI-мост событий и сетевой ввод/вывод драйвера объединены в единый рантайм Tokio (
reticulum-node). Устранен отдельный поток воркера (tokio-runtime-w), дублирующий epoll и лишние таймерные колеса. - Отключение фонового счетчика скорости: Запуск потока
spawn_traffic_counterизолирован под#[cfg(feature = "rpc")], устраняя ежесекундные холостые переключения контекста процессора. - Ограничение стека воркера: Стек рабочего потока
reticulum-nodeограничен до 128 КБ (thread_stack_size(128 * 1024)). Количество постоянных потоков процесса снижено до 3, виртуальное адресное пространство (VmSize) упало до 19.8 - 25.0 МБ, а пиковый всплеск памяти (VmPeak) снизился с 47.8 МБ до ~27.5 МБ (экономия более 20 МБ пикового ОЗУ).
- Ликвидация дублирующего экземпляра Tokio: FFI-мост событий и сетевой ввод/вывод драйвера объединены в единый рантайм Tokio (
- Аппаратная оптимизация MIPS и мгновенная дедупликация пакетов:
- Разворачивание циклов Curve25519 (
opt-level = 3): Для пакетовcurve25519-dalek,ed25519-dalekиx25519-dalekвключена максимальная оптимизация в профилеrelease. Компилятор разворачивает 32-битную арифметику полей, ускоряя рукопожатия Link и проверку подписей на 30-40% на MIPS без FPU. - Прямой 8-байтный хешер (
FastHashBuilder): Стандартный SipHash-1-3 вpacket_cacheзаменен на прозрачный хешер, считывающий первые 8 байт SHA-256 за 1 процессорную инструкцию. Накладные расходы CPU на дедупликацию транзитных пакетов сведены к нулю. - Вырезание мертвого кода: Полностью удалены библиотеки регулярных выражений (
regex-automata,regex-syntax) и сделан опциональнымserde_json, сэкономив более 114 КБ размера бинарника.
- Разворачивание циклов Curve25519 (
- Усиление безопасности, статический анализ и верификация памяти (Zero Leaks):
- Защита от Path Traversal и инъекций: Обработчик страниц NomadNet строго фильтрует входящие пути: отклоняет попытки обхода директорий (
..), прямые и обратные слэши, скрытые системные файлы (.env,.git,.hidden.mu) и любые файлы без расширения.mu. Проверка возвратаsnprintfзащищает от атак через усечение длинных путей. - Верификация под AddressSanitizer (ASan) и UBSan: Выполнен аудит под санитизаторами памяти на x86_64 хосте: подтверждено 0 переполнений буфера, 0 выходов за границы массивов и 0 случаев неопределенного поведения при LRU-ротации и сериализации MessagePack.
- Полное освобождение памяти (LeakSanitizer): Все активные состояния соединений Link, очереди ответов и слоты LRU-кэша гарантированно освобождаются при остановке демона, подтверждая 0 утечек памяти.
- Глубокий статический анализ: Си-монолит прошел аудит анализатором
gcc -fanalyzer -Wall -Wextra -Werrorбез единого замечания, подтверждая безопасность разыменования указателей.
- Защита от Path Traversal и инъекций: Обработчик страниц NomadNet строго фильтрует входящие пути: отклоняет попытки обхода директорий (
Официальные автономные статические релизные архивы собираются и проверяются через QEMU для 6 аппаратных архитектур:
- MIPS Big-Endian (
mips-unknown-linux-musl): Qualcomm Atheros AR9xxx, QCA95xx, QCA55xx (таргет OpenWrtath79). - MIPSEL Little-Endian (
mipsel-unknown-linux-musl): MediaTek / Ralink MT7620, MT7621, MT7628 (OpenWrt/Keeneticramips). - ARMv7-A 32-bit (
armv7-unknown-linux-musleabihf): Cortex-A7/A9, Raspberry Pi 2 / Zero 2W, Orange Pi (hard-float). - ARM64 / AArch64 (
aarch64-unknown-linux-musl): Cortex-A53/A72, Raspberry Pi 3/4/5, современные ARM-роутеры и VPS. - x86_64 (
x86_64-unknown-linux-musl): 64-битные серверы Intel / AMD, ПК и VPS. - i686 (
i686-unknown-linux-musl): 32-битные платформы x86 и тонкие клиенты. - Аппаратный FPU: Не требуется на MIPS/MIPSEL; вычисления проводятся программно благодаря
-msoft-float. - Совместимость с ядрами Linux:
Бинарный файл скомпилирован со статической библиотекойmusl libc, минимальным системным требованием которой является ядро Linux 2.6.39.
На ядрах 2.6.39 работа напрямую не проверялась, однако теоретически бинарник должен запускаться на любых ядрах от 2.6.39 и новее благодаря правилу ядра Linux «never break userspace» и стабильности ABI системных вызовов.
Фактически подтверждена стабильная работа на ядре 3.4.103-rt119 (ASUS RT-AC57U V3). На ядрах 4.x, 5.x и 6.x работа гарантируется архитектурой статической сборки.
Автоматические мультиплатформенные релизы:
Автономные статические релизные архивы с предварительной верификацией запуска через QEMU автоматически собираются и публикуются для всех 6 целевых архитектур в разделе GitHub Releases.
В каталоге ноды используются три критически важных 64-байтных файла ключей:
identities/lblogd(64 байта): Постоянный ключ узла NomadNet (блога/сайта). Определяет публичный адрес страницы в сети. Терять и удалять нельзя, иначе узел сменит адрес страницы.identities/site.id(64 байта): Служебный идентификатор сайта, созданный при развертывании..reticulum/storage/transport_identity(64 байта): Мастер-ключ роутера (криптографический паспорт). Удалять категорически запрещено, иначе сменится Transport ID, а все связи и маршруты аннулируются.
WDHJGSJFCZ3E72YE6L7LQKDKW46BHA6Q56Q*************************************************RQTWUQ=
- Единый крипто-паспорт (Identity Hash):
c1cfe6b1620ff4515f48********fa8c - Сайт в сети NomadNet на домашнем роутере:
nomad://eeccf2849599909527d4********141 - Адрес личной почты и мессенджера (LXMF / Sideband / MeshChat):
lxmf:bff56bcc8ec6e1b49759********16b0
Пока вы сохраняете неизменным один и тот же файл ключа (lblogd), ваш почтовый адрес LXMF и адрес сайта в сети будут оставаться постоянными на всех ваших устройствах.
[reticulum]
# Имя ноды в глобальной сети.
# Если параметр не указан, применяется стандартное имя из C-кода: "Clevnode" (с большой буквы).
node_name = Router Node
# Разрешает сквозную маршрутизацию пакетов сторонних узлов (режим транзитного роутера).
enable_transport = yes
# Позволяет локальным утилитам подключаться к запущенному экземпляру стека.
share_instance = yes
# Порт TCP для локального межпроцессного взаимодействия (IPC) утилит rnstatus/rnpath.
shared_instance_port = 37428
# Интервал сброса кэша маршрутов и хэшей на накопитель в секундах (900 сек = 15 минут).
flush_interval = 900
[logging]
# Базовый уровень вывода логов. В FFI-слое жестко зафиксирован уровень 1 (LEV_LOG_INFO).
loglevel = 1
[interfaces]
# Интерфейс локального сервера для устройств домашней сети (ПК, телефоны по Wi-Fi).
[[Local Wi-Fi Server]]
type = TCPServerInterface
enabled = yes
listen_ip = 0.0.0.0
listen_port = 4242
# Исходящее постоянное TCP-подключение к публичному хабу сети Reticulum (Польша).
[[WDGWars Node]]
type = TCPClientInterface
enabled = yes
target_host = rns.wdgwars.pl
target_port = 4242
bootstrap_only = yes
name = WDGWars Node
# Мост в анонимную сеть I2P через локальный SAM API (порт 7656).
# Интерфейс является ПОЛНОСТЬЮ ОПЦИОНАЛЬНЫМ и нужен далеко не каждому пользователю.
# Если I2P не требуется, секцию ниже можно закомментировать символом #.
[[I2P Bridge Interface]]
type = I2PInterface
enabled = yes
connectable = yes
discoverable = yes
discovery_name = Router Node I2P
reconnect_wait = 120
peers = wnbroeyo5kotdkq4qpitosoch4f64fiwv4uyrk7tp57w2ubthatq.b32.i2p, fc22dfljkpt2beq3itqjkz2k7oizuythif7aa3m73okq7mqrg66q.b32.i2pReticulum взаимодействует с I2P через SAM API (порт 7656). При запуске проверяется файл .reticulum/storage/i2p/i2p_iface_0.i2p. Если его нет, генерируется новый Destination (DEST GENERATE), записывается на диск, и вычисляется постоянный скрытый адрес .b32.i2p.
Параметр enable_transport = yes превращает роутер в межсетевой шлюз. Пакеты, пришедшие из открытого интернета (порт 4242), пересылаются в скрытые туннели I2P и наоборот. Чтобы изолировать сети друг от друга:
- Выставьте
enable_transport = no(режим только конечного узла), либо - Добавьте параметр
mode = boundaryв секцию интерфейса I2P для запрета прохождения анонсов.
Адреса пиров в шаблоне - это проверенные общеизвестные публичные хабы сообщества, делиться ими безопасно. Однако не публикуйте в открытом доступе свой личный сгенерированный адрес .b32.i2p, если ваш узел предназначен для закрытого использования.
Построение карты сети Reticulum происходит реактивно через анонсы (Announces). При холодном старте таблица пуста, а построение туннелей в сети I2P занимает несколько минут. Рекомендуется дать узлу 5–15 минут после старта для завершения маршрутной сходимости перед активной передачей данных.
Сборка полностью автоматизирована скриптом build_mips_be.sh на хосте Linux x86_64.
# Установка базовых инструментов на хосте Ubuntu/Debian
sudo apt update && sudo apt install -y git curl wget gcc make tar xz-utils
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
# Быстрая инкрементальная сборка (~2-3 секунды)
./build_mips_be.sh
# Сборка со стриппингом секций sstrip
./build_mips_be.sh --sstrip
# Полная зачистка и пересборка с нуля
./build_mips_be.sh --clean# Копирование бинарника и конфигурации (пример с маскированием)
scp -P 63*** clevnode/clevnode [email protected].***:/tmp/mnt/sda1/home/lblogd/
scp -P 63*** clevnode/reticulum/config [email protected].***:/tmp/mnt/sda1/home/lblogd/.reticulum/configСлужба автозапуска /opt/etc/init.d/S90clevnode:
#!/bin/sh
ENABLED=yes
PROG="clevnode"
DIR="/tmp/mnt/sda1/home/lblogd"
BIN="$DIR/$PROG"
LOG="$DIR/clevnode.log"
start() {
[ "$ENABLED" != "yes" ] && return 0
pidof "$PROG" >/dev/null && return 0
echo -n "Starting $PROG... "
cd "$DIR" || exit 1
"$BIN" > "$LOG" 2>&1 &
sleep 1
pidof "$PROG" >/dev/null && echo "OK" || echo "FAILED"
}
stop() {
echo -n "Stopping $PROG... "
killall "$PROG" 2>/dev/null
for i in 1 2; do
sleep 1
! pidof "$PROG" >/dev/null && echo "OK" && return 0
done
killall -9 "$PROG" 2>/dev/null
echo "Force killed"
}
case "$1" in
start) start ;;
stop) stop ;;
restart) stop; sleep 1; start ;;
status) pidof "$PROG" >/dev/null && echo "Running" || echo "Stopped" ;;
*) echo "Usage: $0 {start|stop|restart|status}"; exit 1 ;;
esactransport_identity: Мастер-ключ узла. Удалять запрещено.packet_hashlist: Двухпоколенный кэш (~3.6 МБ). Самоочищается автоматически.known_destinations: База известных адресов. Если на носителе заканчивается место, файл можно безопасно удалить:/opt/etc/init.d/S90clevnode stop rm -f /tmp/mnt/sda1/home/lblogd/.reticulum/storage/known_destinations /opt/etc/init.d/S90clevnode start
Все приведенные пути к директориям, порты и имена интерфейсов являются индивидуальными примерами для тестового стенда. Информация предоставляется «как есть» исключительно для ознакомления и технических экспериментов.
- Онлайн-карта топологии Reticulum (Иван Сварковский)
- Официальное руководство по интерфейсам Reticulum [1.1.2]
- Сводная таблица реализаций Reticulum
- Каталог проектов Awesome Reticulum
- Документация по сети Reticulum на Dead.md [1.4.3]
- Установка Reticulum на примере MeshChat через Yggdrasil [1.1.2]
- Установка I2P роутера через сеть Yggdrasil [1.2.1]
- Официальный репозиторий Reticulum на GitHub
- Репозиторий ядра Leviculum на Codeberg
- Спецификация протокола LXMF
- Клиент Sideband для LXMF
- Статьи о Reticulum на DevZone

