1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
//! 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`](tokio::io::AsyncRead)/[`AsyncWrite`](tokio::io::AsyncWrite) — no
//! external `i2pd`/Java-I2P process, no SAM bridge, no separate service to run alongside your
//! binary.
//!
//! # Crypto backend: `aws-lc` (default) vs `fips`
//!
//! Mirrors `i2pd-sys`'s own two features, passed straight through:
//!
//! - **`aws-lc`** (default): regular AWS-LC via `i2pd-sys`'s `aws-lc` feature.
//! - **`fips`**: the FIPS 140-3-validated AWS-LC-FIPS module instead, via `i2pd-sys`'s `fips`
//! feature. **`fips` wins if both end up enabled** (e.g. a dependent crate's own default
//! reaching for `aws-lc` while a workspace-wide `fips` flag also reaches in here) -- see
//! `i2pd-sys`'s crate docs for why an inert, unused `aws-lc-sys` compiled in alongside it is
//! harmless. See `i2pd-sys`'s "FIPS" README section for what `fips` does and does not get you
//! before reaching for it to satisfy a compliance requirement.
//!
//! # Why this crate exists, and why it's `unsafe` internally
//!
//! `libi2pd` (the underlying router, from [PurpleI2P/i2pd](https://github.com/PurpleI2P/i2pd))
//! is a C++ library with no stable C ABI. `i2pd-sys` bridges it through a small hand-written
//! `extern "C"` shim; this crate is where every `unsafe` call site into that shim lives, so that
//! `tachyon-web` itself never has to relax its own `forbid(unsafe_code)`. **The public API below
//! is 100% safe Rust** — no `pub unsafe fn`, no raw pointers exposed — but that safety rests
//! entirely on this crate's own review of libi2pd's threading/ownership contracts (documented
//! inline at each `unsafe` block, and in `i2pd-sys/shim/shim.h`), not on any external memory-safety
//! guarantee the way a pure-Rust dependency would give you. See `tachyon-web`'s `i2p` feature
//! docs for the practical implication of that distinction.
//!
//! # Basic usage
//!
//! ```rust,no_run
//! # async fn example() -> Result<(), tachyon_i2p::I2pError> {
//! use tachyon_i2p::{I2pRouter, SigType};
//!
//! let router = I2pRouter::start("my-eepsite").await?;
//! let mut dest = router
//! // Empty slice: publish libi2pd's own automatic hybrid encryption set (ElGamal +
//! // ECIES-X25519, plus ML-KEM-768 if built against a post-quantum-capable backend) rather
//! // than a single fixed algorithm -- see `CryptoType`'s docs to narrow that down instead.
//! .destination_from_keys_file("my-eepsite.keys", true, SigType::default(), &[])
//! .await?;
//! println!("reachable at http://{}", dest.b32_address());
//!
//! loop {
//! let _stream = dest.accept().await?; // implements AsyncRead + AsyncWrite
//! // ... spawn a task to serve it ...
//! }
//! # }
//! ```
//!
//! Only one [`I2pRouter`] may run per process — libi2pd keeps its router context as a
//! process-wide global, not a per-instance object.
compile_error!;
pub use Destination;
pub use I2pError;
pub use ;
pub use I2pStream;