i2pd-sys 0.0.6

Raw FFI bindings to a minimal C shim over libi2pd (PurpleI2P/i2pd)
Documentation
//! Raw `bindgen`-generated FFI bindings to a C shim over `libi2pd` (PurpleI2P/i2pd) — a real I2P
//! router built in-process, not a client for a separately-running `i2pd` daemon.
//!
//! Everything here is generated from [`shim/shim.h`][shim-h], the only header bindgen runs against;
//! libi2pd's own C++ headers use `std::shared_ptr`/STL types with no stable C ABI. That file
//! documents each function. README.md covers the build, the trimmed attack surface, network
//! participation, and the FIPS backend.
//!
//! [shim-h]: https://github.com/tachyon-web/i2pd-sys/blob/main/shim/shim.h
//!
//! ```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()); // before anything else
//!     i2pd_start();
//!
//!     let dest = i2pd_create_transient_destination();
//!     assert!(!dest.is_null());
//!
//!     i2pd_destroy_destination(dest);
//!     i2pd_stop();
//!     i2pd_terminate();
//! }
//! ```
//!
//! # Safety
//!
//! [`i2pd_init`] must be called before anything else. Every `I2pdDestination`/`I2pdStream` pointer
//! must be destroyed exactly once via the matching `i2pd_destroy_*` and never used afterwards.
//! [`i2pd_free_buffer`] takes the length [`i2pd_generate_keys`] reported and wipes the buffer
//! first: it holds a private key, and plain `free` would leave the bytes readable in the heap.
//!
//! The four lifecycle calls share one mutex held across the underlying libi2pd call, so a repeated
//! or out-of-order call is a no-op rather than a second pass over libi2pd's non-reentrant globals,
//! and a racing caller blocks until the transition it observed has finished. `terminate` stops a
//! still-running router first.
//!
//! [`i2pd_stream_send`] and [`i2pd_stream_receive`] *are* safe to call concurrently on the same
//! stream — each posts work onto i2pd's `io_service` and blocks the calling thread on a condition
//! variable, as i2pd's own SAM/BOB bridges do. The [`i2pd_accept_stream`] callback runs on i2pd's
//! thread and must return quickly, or it stalls the event loop for every destination on the router.
//!
//! Every shim function catches all C++ exceptions internally, including that callback, so nothing
//! unwinds across the `extern "C"` boundary. Failures surface as `NULL`/`0`/`-1`, not panics.
//!
//! # Features
//!
//! `aws-lc` (default) links [AWS-LC](https://github.com/aws/aws-lc); `fips` swaps in the
//! FIPS-validated module. `fips` wins if both end up enabled — `build.rs` emits link directives for
//! one backend only, and the two use per-version-prefixed symbol names, so the other is inert.
//!
//! `transit` (default) carries other users' tunnels. Building without it compiles the tunnel
//! build-request path out of libi2pd entirely, whatever the runtime settings say;
//! [`i2pd_accepts_transit`] reports what the build supports.
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals, dead_code)]

#[cfg(not(any(feature = "aws-lc", feature = "fips")))]
compile_error!(
    "no crypto backend selected -- enable exactly one of the `aws-lc` (default) or `fips` \
     features."
);

include!(concat!(env!("OUT_DIR"), "/bindings.rs"));