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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
//! Raw, `bindgen`-generated FFI bindings to the `i2pd-sys/shim` C shim over `libi2pd`
//! (PurpleI2P/i2pd) — a real I2P router built in-process, not a client for a separately-running
//! `i2pd` daemon.
//!
//! # What's here
//!
//! Every symbol in this module is generated at build time from [`shim/shim.h`][shim-h] (the
//! *only* header `bindgen` ever runs against — never `libi2pd`'s own C++ headers, which use
//! `std::shared_ptr`/STL types with no stable C ABI). See that file for the fully documented API
//! surface; the short version:
//!
//! | Group | Functions |
//! |---|---|
//! | Lifecycle | [`i2pd_init`], [`i2pd_start`], [`i2pd_stop`], [`i2pd_terminate`] |
//! | Destinations | [`i2pd_create_transient_destination`], [`i2pd_generate_keys`], [`i2pd_create_persistent_destination`], [`i2pd_destroy_destination`], [`i2pd_destination_b32_address`], [`i2pd_destination_ident_hash`], [`i2pd_accept_stream`] |
//! | Streams | [`i2pd_create_stream`], [`i2pd_stream_send`], [`i2pd_stream_receive`], [`i2pd_stream_is_open`], [`i2pd_stream_close`], [`i2pd_destroy_stream`] |
//! | Memory | [`i2pd_free_buffer`], [`i2pd_free_string`] |
//!
//! [shim-h]: https://codeberg.org/hacer-bark/i2pd-sys/src/branch/main/shim/shim.h
//!
//! # Example
//!
//! ```rust,no_run
//! use i2pd_sys::*;
//! use std::ffi::CString;
//!
//! unsafe {
//! let app_name = CString::new("my-app").unwrap();
//! i2pd_init(app_name.as_ptr()); // exactly once, before anything else
//! i2pd_start();
//!
//! let dest = i2pd_create_transient_destination();
//! assert!(!dest.is_null());
//!
//! // ... i2pd_accept_stream / i2pd_create_stream / i2pd_stream_send / i2pd_stream_receive ...
//!
//! i2pd_destroy_destination(dest);
//! i2pd_stop();
//! i2pd_terminate();
//! }
//! ```
//!
//! # Safety
//!
//! This is a raw C ABI with all the usual obligations: [`i2pd_init`] must be called exactly once
//! before any other function; every `I2pdDestination`/`I2pdStream` pointer must be destroyed
//! exactly once (via the matching `i2pd_destroy_*`) and never used afterwards; buffers returned
//! by [`i2pd_generate_keys`]/[`i2pd_destination_b32_address`] must be freed with
//! [`i2pd_free_buffer`]/[`i2pd_free_string`] respectively, exactly once.
//!
//! [`i2pd_stream_send`] and [`i2pd_stream_receive`] *are* safe to call concurrently from
//! different threads on the same stream (one sending, one receiving) — each posts work onto
//! i2pd's internal `io_service` and blocks the calling thread on a condition variable, the same
//! pattern i2pd's own SAM/BOB bridges use. The callback registered via [`i2pd_accept_stream`]
//! runs on i2pd's own internal thread and must return quickly without blocking, or it stalls the
//! event loop for every destination sharing that router.
//!
//! Every shim function catches all C++ exceptions internally, so a C++ exception can never
//! unwind across the `extern "C"` boundary (which would be undefined behavior) — failures
//! surface as `NULL`/`0`/`-1` return values instead, not panics or aborts.
//!
//! # Crypto backend: `aws-lc` (default) vs `fips`
//!
//! `i2pd` needs an OpenSSL-API-compatible crypto library; this crate provides one via exactly
//! one of two mutually exclusive features, never both:
//!
//! - **`aws-lc`** (default): regular [AWS-LC](https://github.com/aws/aws-lc) via `aws-lc-sys`.
//! - **`fips`**: the FIPS-validated [AWS-LC-FIPS](https://github.com/aws/aws-lc/tree/fips-2024-09-27)
//! module via `aws-lc-fips-sys` instead — `default-features = false, features = ["fips"]`.
//! See the "FIPS" section of `README.md` for what this does (and does not) get you, and what
//! it costs, before reaching for it to satisfy a compliance requirement.
compile_error!;
compile_error!;
include!;