Skip to main content

tachyon_i2p/
lib.rs

1//! Safe async wrapper around `i2pd-sys`: a [`Destination`] (an I2P eepsite identity, reachable at
2//! a `.b32.i2p` address) and an [`I2pStream`] implementing
3//! [`AsyncRead`](tokio::io::AsyncRead)/[`AsyncWrite`](tokio::io::AsyncWrite), with no external
4//! `i2pd` process or SAM bridge.
5//!
6//! Every `unsafe` call into libi2pd's C shim lives in this crate; the public API exposes no raw
7//! pointers and no `pub unsafe fn`. That safety rests on this crate's reading of libi2pd's
8//! threading and ownership contracts, documented at each `unsafe` block and in
9//! `i2pd-sys/shim/shim.h`, not on anything the compiler checks.
10//!
11//! # Features
12//!
13//! `aws-lc` (default) and `fips` pick the `i2pd-sys` crypto backend; at least one must be
14//! enabled, and `fips` wins if both are (Cargo features are additive, so a dependent crate can
15//! pull `aws-lc` back in). `transit` (default) compiles in libi2pd's tunnel build-request path.
16//!
17//! # Basic usage
18//!
19//! ```rust,no_run
20//! # async fn example() -> Result<(), tachyon_i2p::I2pError> {
21//! use tachyon_i2p::{I2pRouter, SigType};
22//!
23//! let router = I2pRouter::start("my-eepsite").await?;
24//! let mut dest = router
25//!     // Empty slice: libi2pd's own hybrid encryption set. See `CryptoType` to narrow it down.
26//!     .destination_from_keys_file("my-eepsite.keys", true, SigType::default(), &[])
27//!     .await?;
28//! println!("reachable at http://{}", dest.b32_address());
29//!
30//! loop {
31//!     let _stream = dest.accept().await?; // implements AsyncRead + AsyncWrite
32//!     // ... spawn a task to serve it ...
33//! }
34//! # }
35//! ```
36//!
37//! Only one [`I2pRouter`] may run per process at a time: libi2pd keeps its router context as a
38//! process-wide global. Starting a new one after the previous router has been dropped works.
39//!
40//! # Network participation
41//!
42//! This crate runs a real I2P router, so it has a position in the network beyond hosting your own
43//! destinations. By default it carries transit tunnels (other users' traffic) at up to 256 KB/s
44//! router-wide, and does not act as a floodfill. Transit defaults to on because a router that
45//! relays nothing gives an observer no cover traffic: every byte crossing the link is then yours.
46//! [`RouterConfig`] is the only way to change any of it -- libi2pd reads these settings as the
47//! router comes up, and never parses an `i2pd.conf` when embedded as a library.
48
49#[cfg(not(any(feature = "aws-lc", feature = "fips")))]
50compile_error!(
51    "no crypto backend selected -- enable exactly one of the `aws-lc` (default) or `fips` \
52     features."
53);
54
55/// Compiles the `README.md` usage example as a doctest so it can't drift from the real API.
56#[cfg(doctest)]
57#[doc = include_str!("../README.md")]
58struct ReadmeExample;
59
60mod destination;
61mod error;
62mod router;
63mod stream;
64
65pub use destination::Destination;
66pub use error::I2pError;
67pub use router::{CryptoType, I2pRouter, RouterConfig, SigType};
68pub use stream::I2pStream;