// 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