Appearance
Dev Notes (SAM + KAD Over I2P)
This repo is currently focused on bootstrapping an iMule-compatible Kademlia (KAD) overlay over I2P using SAM v3.
If you're continuing work in a new chat session, start with docs/handoff.md.
Branch
Canonical branch is main.
What Works Today
- SAM v3 control protocol client (
src/i2p/sam/). - SAM
STYLE=DATAGRAMsession over TCP (iMule-styleDATAGRAM SEND/DATAGRAM RECEIVED) (src/i2p/sam/datagram_tcp.rs). - SAM
STYLE=DATAGRAMsession with UDP forwarding (src/i2p/sam/datagram.rs). - iMule-compatible identity:
preferencesKad.datpersisted KadID (random 128-bit) (src/kad.rs).
- iMule-compatible
nodes.datparsing (I2P destinations, KadIDs, UDP keys) (src/nodes/imule.rs). - KAD2 bootstrap "probe":
- Sends
KADEMLIA2_PINGandKADEMLIA2_BOOTSTRAP_REQto peers fromnodes.dat. - Receives and decodes
KADEMLIA2_PONGandKADEMLIA2_BOOTSTRAP_RES. - Supports iMule "packed" KAD replies (deflate+zlib) via a pure-Rust inflater (
src/kad/packed.rs).
- Sends
This is not yet a full routing table implementation. It is a minimal end-to-end connectivity check to real peers.
Local Reference Sources
source_ref/contains iMule sources and reference files. It is intentionally gitignored.
For distributable builds we embed a baseline seed snapshot in assets/nodes.initseed.dat. On startup, the app will create data/nodes.initseed.dat and data/nodes.fallback.dat from that embedded snapshot (best-effort).
The app will prefer data/nodes.dat. If that file doesn't exist yet, it falls back to data/nodes.initseed.dat and data/nodes.fallback.dat.
Running
- Ensure SAM is reachable.
- Choose a datagram transport in
config.toml:sam.datagram_transport = "tcp"(recommended; easiest with remote SAM).sam.datagram_transport = "udp_forward"(requires UDP forwarding; see next section).
- Run:
bash
cargo runLogs are persisted under data/logs/ by default (daily rolled) if [general].log_to_file = true.
Optional tooling:
bash
cargo run --bin imule_nodes_inspect -- assets/nodes.initseed.datRemote SAM Bridging (Docker Scenario)
If the SAM bridge is on a different machine than the rust-mule process, SAM UDP forwarding must be configured so that:
- The SAM bridge can send UDP packets to the host+port you provide in
SESSION CREATE ... HOST=<forward_host> PORT=<forward_port>. - That UDP host+port ultimately reaches the
rust-muleUDP socket.
Example topology used during development:
- SAM bridge:
10.99.0.2 - This dev environment: Docker container on host
10.99.0.1
Recommended config.toml values for that topology:
sam.host = "10.99.0.2"(SAM TCP control)sam.port = 7656sam.udp_port = 7655(SAM UDP datagrams)sam.forward_host = "10.99.0.1"(the Docker host IP, reachable from10.99.0.2)sam.forward_port = 40000(fixed UDP port, so Docker/firewalls can be configured)
Docker requirements (choose one):
- Use host networking (
--network host), or - Publish UDP port mapping (
-p 40000:40000/udp).
If you leave sam.forward_port = 0 (ephemeral), it is usually hard to forward through Docker or firewalls.
Obsolete Code Cleanup
As part of the KAD-over-I2P alignment, the following obsolete/unused modules were removed:
src/net/(TCP probe helpers)- The older IPv4-centric
nodes.datparser insrc/nodes/parse.rsandsrc/nodes/detect.rs