diff --git a/app/vpn/boringtun_ffi.h b/app/vpn/boringtun_ffi.h index 2ff35f3..d4ab48e 100644 --- a/app/vpn/boringtun_ffi.h +++ b/app/vpn/boringtun_ffi.h @@ -1,11 +1,13 @@ -// 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 +// boringtun_ffi.h — C ABI for Cloudflare's boringtun WireGuard library. +// +// Build boringtun with --features ffi-bindings, then link the resulting +// libboringtun.a (or boringtun.lib on Windows) into the application. +// +// This header MUST stay in lock-step with the version in +// forge.wilddragon.net/zgaetano/artemis/src/wg/boringtun_ffi.h — both +// projects link the same boringtun build artifact and the FFI surface must +// be identical. #include #include @@ -14,97 +16,83 @@ extern "C" { #endif -// ─── Result codes ───────────────────────────────────────────────────────────── +// ── Result type ─────────────────────────────────────────────────────────────── -/// 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 +typedef enum { + WIREGUARD_DONE = 0, // operation complete, no further output + WRITE_TO_NETWORK = 1, // dst contains encrypted data to send to UDP peer + WIREGUARD_ERROR = -1, // fatal error + WRITE_TO_TUNNEL_IPV4 = 2, // dst contains decrypted IPv4 packet for TUN + WRITE_TO_TUNNEL_IPV6 = 3, // dst contains decrypted IPv6 packet for TUN +} wireguard_result_type; -/// 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_type op; + size_t size; // bytes written to dst (valid when op != WIREGUARD_ERROR/DONE) } wireguard_result; -/// Opaque WireGuard tunnel handle. +// ── Opaque tunnel type ──────────────────────────────────────────────────────── + typedef struct wireguard_tunnel wireguard_tunnel; -// ─── Lifecycle ──────────────────────────────────────────────────────────────── +// ── 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); +// Create a new WireGuard tunnel. +// private_key : base64-encoded Curve25519 private key (NUL-terminated) +// peer_public_key : base64-encoded Curve25519 public key (NUL-terminated) +// preshared_key : base64-encoded 32-byte PSK, or NULL +// keepalive : PersistentKeepalive interval in seconds (0 = off) +// log_level : 0=none, 1=error, 2=info, 3=debug +// +// Returns NULL on failure. +wireguard_tunnel *new_tunnel(const char *private_key, + const char *peer_public_key, + const char *preshared_key, + uint16_t keepalive, + uint32_t log_level); -/// Free a tunnel created with new_tunnel(). +// Free a tunnel created by new_tunnel(). Must not be called from an I/O thread. void tunnel_free(wireguard_tunnel *tunnel); -// ─── Packet I/O ─────────────────────────────────────────────────────────────── +// ── Data plane ──────────────────────────────────────────────────────────────── -/// 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. +// Encrypt a plaintext IP packet from the TUN device. +// src / src_size : plaintext packet (read from TUN fd) +// dst / dst_size : output buffer (at least src_size + 148 bytes for overhead) +// *dst_size MUST be set on entry to the buffer's capacity; +// on return it is the number of bytes written. +// Returns WRITE_TO_NETWORK when dst holds data ready to send to the UDP peer, +// WIREGUARD_DONE when the packet was consumed but produced no output, +// WIREGUARD_ERROR on failure. wireguard_result wireguard_write(wireguard_tunnel *tunnel, - const uint8_t *src, uint32_t src_size, - uint8_t *dst, uint32_t dst_capacity); + const uint8_t *src, size_t src_size, + uint8_t *dst, size_t *dst_size); -/// 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. +// Decrypt a WireGuard UDP datagram received from the network. +// src / src_size : encrypted UDP payload +// dst / dst_size : output buffer; *dst_size MUST be set on entry to capacity, +// updated on return to bytes written. +// Returns WRITE_TO_TUNNEL_IPV4 / _IPV6 when dst holds a decrypted IP packet, +// WRITE_TO_NETWORK when dst holds a handshake response to send back, +// WIREGUARD_DONE when the message was consumed (e.g. keepalive), +// WIREGUARD_ERROR on failure. wireguard_result wireguard_read(wireguard_tunnel *tunnel, - const uint8_t *src, uint32_t src_size, - uint8_t *dst, uint32_t dst_capacity); + const uint8_t *src, size_t src_size, + uint8_t *dst, size_t *dst_size); -/// 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. +// ── Timers ──────────────────────────────────────────────────────────────────── + +// Drive WireGuard timers (keepalives, re-handshakes). +// Call every 100 ms from a dedicated ticker thread. +// *dst_size MUST be set on entry to the buffer's capacity. +// Returns WRITE_TO_NETWORK if dst holds data to send; WIREGUARD_DONE otherwise. wireguard_result wireguard_tick(wireguard_tunnel *tunnel, - uint8_t *dst, uint32_t dst_capacity); + uint8_t *dst, size_t *dst_size); -/// Immediately initiate a new handshake (e.g., after a network change). +// Force an immediate handshake initiation (call once after start()). +// *dst_size MUST be set on entry to the buffer's capacity. wireguard_result wireguard_force_handshake(wireguard_tunnel *tunnel, - uint8_t *dst, - uint32_t dst_capacity); + uint8_t *dst, size_t *dst_size); #ifdef __cplusplus } // extern "C"