#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 #ifdef __cplusplus extern "C" { #endif // ── Result type ─────────────────────────────────────────────────────────────── 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; typedef struct { wireguard_result_type op; size_t size; // bytes written to dst (valid when op != WIREGUARD_ERROR/DONE) } wireguard_result; // ── Opaque tunnel type ──────────────────────────────────────────────────────── typedef struct wireguard_tunnel wireguard_tunnel; // ── Lifecycle ───────────────────────────────────────────────────────────────── // 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 by new_tunnel(). Must not be called from an I/O thread. void tunnel_free(wireguard_tunnel *tunnel); // ── Data plane ──────────────────────────────────────────────────────────────── // 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, size_t src_size, uint8_t *dst, size_t *dst_size); // 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, size_t src_size, uint8_t *dst, size_t *dst_size); // ── 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, size_t *dst_size); // 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, size_t *dst_size); #ifdef __cplusplus } // extern "C" #endif