i2pd-sys 0.0.1

Raw FFI bindings to a minimal C shim over libi2pd (PurpleI2P/i2pd).
Documentation
//! 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.
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals, dead_code)]

#[cfg(all(feature = "aws-lc", feature = "fips"))]
compile_error!(
    "features `aws-lc` and `fips` are mutually exclusive (two crypto backends can't both be \
     linked in) -- pick exactly one: `--features fips` alone needs \
     `default-features = false` too, since `aws-lc` is on by default."
);
#[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"));