tachyon-i2p
Safe async wrapper around i2pd-sys, giving Tokio code a
Destination (an I2P eepsite identity, reachable at a .b32.i2p address) with an I2pStream
connection type that implements AsyncRead/AsyncWrite — no external i2pd/Java-I2P process,
no SAM bridge, no separate service to run alongside your binary.
Status: pre-0.1 (
0.0.x), developed alongside and consumed by thetachyon-webworkspace. The API may still change without notice.
Why it's unsafe internally
libi2pd (the underlying router, from PurpleI2P/i2pd) is a
C++ library with no stable C ABI. i2pd-sys bridges it through a small hand-written extern "C"
shim, and this crate is where every unsafe call site into that shim lives, so consumers never
have to relax their own forbid(unsafe_code). The public API exposes no pub unsafe fn and no
raw pointers, but that safety rests on this crate's own review of libi2pd's threading and
ownership contracts — documented at each unsafe block and in i2pd-sys/shim/shim.h — not on
anything the compiler checks.
Usage
use ;
async
The keys file is this destination's private identity — anyone who obtains it can impersonate
the eepsite. It is created owner-only (0600) and written atomically; back it up accordingly,
and reuse the same path across restarts to keep the same .b32.i2p address.
Only one I2pRouter may run per process at a time — libi2pd keeps its router context as a
process-wide global. Starting a new one after the previous router has been dropped works.
Network participation
This crate runs a real I2P router, so it has a position in the network beyond hosting your own destinations. Defaults:
| Transit tunnels | Carried. |
| Bandwidth | 256 KB/s, whole router. |
| Floodfill | Off. |
| Config files | None read. libi2pd only parses i2pd.conf in upstream's daemon. |
Transit means carrying other users' tunnels, and is unrelated to your own destinations, which
work either way. It defaults to on because a router that relays nothing gives an observer no
cover traffic: every byte crossing your link is then yours, which makes correlating your service
easier, and the refusal is itself a fingerprint. Turn it off when bandwidth is metered, or when
the risk you care about is a memory-safety bug in libi2pd rather than traffic analysis.
RouterConfig is the only way to change any of this — the settings are read as the router comes
up, so there is no equivalent on a running one:
use ;
async
Building without the default transit feature is the stronger form of accepts_transit(false):
libi2pd's tunnel build-request path is compiled out, so no transit tunnel can exist whatever
RouterConfig says. I2pRouter::supports_transit() reports which build you got.
Crypto backend: aws-lc (default) vs fips
Both mirror i2pd-sys's features of the same name: aws-lc links regular AWS-LC, fips links
the FIPS 140-3-validated AWS-LC-FIPS module instead. At least one must be enabled — building with
neither is a compile error, not a silently crypto-less router.
For fips, prefer default-features = false, features = ["fips"]. Cargo features are additive,
so a dependent crate reaching for aws-lc can still switch it back on; if both end up enabled,
fips wins. See the "FIPS" section of i2pd-sys's README
for what it does and does not get you before reaching for it to satisfy a compliance requirement.
The third feature, transit (also default), is the compile-time half of
Network participation above.
License
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.