diff --git a/app/vpn/boringtun_ffi.h b/app/vpn/boringtun_ffi.h new file mode 100644 index 0000000..2ff35f3 --- /dev/null +++ b/app/vpn/boringtun_ffi.h @@ -0,0 +1,111 @@ +// boringtun_ffi.h — C ABI declarations for cloudflare/boringtun. +// +// These match the extern "C" surface exported by boringtun when compiled as a +// static library (cargo build --release --features ffi). +// +// Reference: https://github.com/cloudflare/boringtun/blob/master/src/ffi/mod.rs + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +// ─── Result codes ───────────────────────────────────────────────────────────── + +/// Nothing to emit — packet consumed, no output. +#define WIREGUARD_DONE 0 +/// Send result.size bytes from dst over UDP to the WireGuard server. +#define WRITE_TO_NETWORK 1 +/// Fatal error; tunnel should be torn down. +#define WIREGUARD_ERROR (-1) +/// Plaintext IPv4 packet in dst, ready to write to TUN. +#define WRITE_TO_TUNNEL_IPV4 2 +/// Plaintext IPv6 packet in dst, ready to write to TUN. +#define WRITE_TO_TUNNEL_IPV6 3 + +/// Return value from wireguard_write / wireguard_read / wireguard_tick. +typedef struct { + int32_t op; ///< One of the WIREGUARD_* / WRITE_TO_* constants above. + uint32_t size; ///< Bytes written to dst (valid when op != WIREGUARD_ERROR). +} wireguard_result; + +/// Opaque WireGuard tunnel handle. +typedef struct wireguard_tunnel wireguard_tunnel; + +// ─── Lifecycle ──────────────────────────────────────────────────────────────── + +/// Create a new WireGuard tunnel instance. +/// +/// @param static_private Base64 private key of this peer (Interface PrivateKey). +/// @param server_static_public Base64 public key of the remote WireGuard peer. +/// @param preshared_key Base64 preshared key, or NULL if none. +/// @param keep_alive Persistent-keepalive interval in seconds; 0 = disabled. +/// @param index Arbitrary 32-bit session index (use 0 if in doubt). +/// @return Heap-allocated tunnel, or NULL on bad key material. +wireguard_tunnel *new_tunnel(const char *static_private, + const char *server_static_public, + const char *preshared_key, + uint16_t keep_alive, + uint32_t index); + +/// Free a tunnel created with new_tunnel(). +void tunnel_free(wireguard_tunnel *tunnel); + +// ─── Packet I/O ─────────────────────────────────────────────────────────────── + +/// Encrypt a plaintext IP packet for transmission over UDP. +/// +/// Call this whenever a packet arrives from the TUN device. +/// +/// @param tunnel The tunnel handle. +/// @param src Plaintext IPv4/IPv6 packet from TUN (no leading AF header). +/// @param src_size Length of src in bytes. +/// @param dst Output buffer; must be at least src_size + 32 bytes. +/// @param dst_capacity Size of dst in bytes. +/// @return WRITE_TO_NETWORK — send result.size bytes of dst over UDP. +/// WIREGUARD_DONE — handshake consumed; nothing to send yet. +/// WIREGUARD_ERROR — drop this packet and log. +wireguard_result wireguard_write(wireguard_tunnel *tunnel, + const uint8_t *src, uint32_t src_size, + uint8_t *dst, uint32_t dst_capacity); + +/// Decrypt a UDP datagram received from the WireGuard server. +/// +/// Call this whenever a UDP packet arrives from the server endpoint. +/// +/// @param tunnel The tunnel handle. +/// @param src Encrypted UDP payload. +/// @param src_size Length of src in bytes. +/// @param dst Output buffer for plaintext IP packet; must be >= src_size. +/// @param dst_capacity Size of dst in bytes. +/// @return WRITE_TO_TUNNEL_IPV4 — plaintext IPv4 packet in dst; write to TUN. +/// WRITE_TO_TUNNEL_IPV6 — plaintext IPv6 packet in dst; write to TUN. +/// WRITE_TO_NETWORK — WireGuard control packet (handshake/keepalive); +/// send result.size bytes of dst over UDP. +/// WIREGUARD_DONE — consumed; nothing to emit. +/// WIREGUARD_ERROR — drop this datagram and log. +wireguard_result wireguard_read(wireguard_tunnel *tunnel, + const uint8_t *src, uint32_t src_size, + uint8_t *dst, uint32_t dst_capacity); + +/// Produce a periodic WireGuard packet (keepalive or handshake initiation). +/// +/// Call every ~100 ms from a timer thread. Usually returns WIREGUARD_DONE. +/// +/// @return WRITE_TO_NETWORK — send result.size bytes of dst over UDP. +/// WIREGUARD_DONE — nothing to send right now. +wireguard_result wireguard_tick(wireguard_tunnel *tunnel, + uint8_t *dst, uint32_t dst_capacity); + +/// Immediately initiate a new handshake (e.g., after a network change). +wireguard_result wireguard_force_handshake(wireguard_tunnel *tunnel, + uint8_t *dst, + uint32_t dst_capacity); + +#ifdef __cplusplus +} // extern "C" +#endif