Align boringtun FFI with canonical Artemis version (size_t* convention)

This commit is contained in:
Zac Gaetano 2026-05-07 00:10:03 -04:00
parent 4a90ed82fb
commit 693c20d6a5

View file

@ -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 #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 <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@ -14,97 +16,83 @@
extern "C" { extern "C" {
#endif #endif
// ─── Result codes ───────────────────────────────────────────────────────────── // ── Result type ───────────────────────────────────────────────────────────────
/// Nothing to emit — packet consumed, no output. typedef enum {
#define WIREGUARD_DONE 0 WIREGUARD_DONE = 0, // operation complete, no further output
/// Send result.size bytes from dst over UDP to the WireGuard server. WRITE_TO_NETWORK = 1, // dst contains encrypted data to send to UDP peer
#define WRITE_TO_NETWORK 1 WIREGUARD_ERROR = -1, // fatal error
/// Fatal error; tunnel should be torn down. WRITE_TO_TUNNEL_IPV4 = 2, // dst contains decrypted IPv4 packet for TUN
#define WIREGUARD_ERROR (-1) WRITE_TO_TUNNEL_IPV6 = 3, // dst contains decrypted IPv6 packet for TUN
/// Plaintext IPv4 packet in dst, ready to write to TUN. } wireguard_result_type;
#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 { typedef struct {
int32_t op; ///< One of the WIREGUARD_* / WRITE_TO_* constants above. wireguard_result_type op;
uint32_t size; ///< Bytes written to dst (valid when op != WIREGUARD_ERROR). size_t size; // bytes written to dst (valid when op != WIREGUARD_ERROR/DONE)
} wireguard_result; } wireguard_result;
/// Opaque WireGuard tunnel handle. // ── Opaque tunnel type ────────────────────────────────────────────────────────
typedef struct wireguard_tunnel wireguard_tunnel; typedef struct wireguard_tunnel wireguard_tunnel;
// ── Lifecycle ──────────────────────────────────────────────────────────────── // ── Lifecycle ────────────────────────────────────────────────────────────────
/// Create a new WireGuard tunnel instance. // Create a new WireGuard tunnel.
/// // private_key : base64-encoded Curve25519 private key (NUL-terminated)
/// @param static_private Base64 private key of this peer (Interface PrivateKey). // peer_public_key : base64-encoded Curve25519 public key (NUL-terminated)
/// @param server_static_public Base64 public key of the remote WireGuard peer. // preshared_key : base64-encoded 32-byte PSK, or NULL
/// @param preshared_key Base64 preshared key, or NULL if none. // keepalive : PersistentKeepalive interval in seconds (0 = off)
/// @param keep_alive Persistent-keepalive interval in seconds; 0 = disabled. // log_level : 0=none, 1=error, 2=info, 3=debug
/// @param index Arbitrary 32-bit session index (use 0 if in doubt). //
/// @return Heap-allocated tunnel, or NULL on bad key material. // Returns NULL on failure.
wireguard_tunnel *new_tunnel(const char *static_private, wireguard_tunnel *new_tunnel(const char *private_key,
const char *server_static_public, const char *peer_public_key,
const char *preshared_key, const char *preshared_key,
uint16_t keep_alive, uint16_t keepalive,
uint32_t index); 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); void tunnel_free(wireguard_tunnel *tunnel);
// ─── Packet I/O ─────────────────────────────────────────────────────────────── // ── Data plane ────────────────────────────────────────────────────────────────
/// Encrypt a plaintext IP packet for transmission over UDP. // Encrypt a plaintext IP packet from the TUN device.
/// // src / src_size : plaintext packet (read from TUN fd)
/// Call this whenever a packet arrives from the TUN device. // 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;
/// @param tunnel The tunnel handle. // on return it is the number of bytes written.
/// @param src Plaintext IPv4/IPv6 packet from TUN (no leading AF header). // Returns WRITE_TO_NETWORK when dst holds data ready to send to the UDP peer,
/// @param src_size Length of src in bytes. // WIREGUARD_DONE when the packet was consumed but produced no output,
/// @param dst Output buffer; must be at least src_size + 32 bytes. // WIREGUARD_ERROR on failure.
/// @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, wireguard_result wireguard_write(wireguard_tunnel *tunnel,
const uint8_t *src, uint32_t src_size, const uint8_t *src, size_t src_size,
uint8_t *dst, uint32_t dst_capacity); uint8_t *dst, size_t *dst_size);
/// Decrypt a UDP datagram received from the WireGuard server. // Decrypt a WireGuard UDP datagram received from the network.
/// // src / src_size : encrypted UDP payload
/// Call this whenever a UDP packet arrives from the server endpoint. // dst / dst_size : output buffer; *dst_size MUST be set on entry to capacity,
/// // updated on return to bytes written.
/// @param tunnel The tunnel handle. // Returns WRITE_TO_TUNNEL_IPV4 / _IPV6 when dst holds a decrypted IP packet,
/// @param src Encrypted UDP payload. // WRITE_TO_NETWORK when dst holds a handshake response to send back,
/// @param src_size Length of src in bytes. // WIREGUARD_DONE when the message was consumed (e.g. keepalive),
/// @param dst Output buffer for plaintext IP packet; must be >= src_size. // WIREGUARD_ERROR on failure.
/// @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, wireguard_result wireguard_read(wireguard_tunnel *tunnel,
const uint8_t *src, uint32_t src_size, const uint8_t *src, size_t src_size,
uint8_t *dst, uint32_t dst_capacity); uint8_t *dst, size_t *dst_size);
/// Produce a periodic WireGuard packet (keepalive or handshake initiation). // ── Timers ────────────────────────────────────────────────────────────────────
///
/// Call every ~100 ms from a timer thread. Usually returns WIREGUARD_DONE. // Drive WireGuard timers (keepalives, re-handshakes).
/// // Call every 100 ms from a dedicated ticker thread.
/// @return WRITE_TO_NETWORK — send result.size bytes of dst over UDP. // *dst_size MUST be set on entry to the buffer's capacity.
/// WIREGUARD_DONE — nothing to send right now. // Returns WRITE_TO_NETWORK if dst holds data to send; WIREGUARD_DONE otherwise.
wireguard_result wireguard_tick(wireguard_tunnel *tunnel, 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, wireguard_result wireguard_force_handshake(wireguard_tunnel *tunnel,
uint8_t *dst, uint8_t *dst, size_t *dst_size);
uint32_t dst_capacity);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"