text: // Copyright (c) 2019 Cloudflare, Inc. All rights reserved.
  // SPDX-License-Identifier: BSD-3-Clause
  
  #pragma once
  
  #include <stdint.h>
  
  struct wireguard_tunnel; // This corresponds to the Rust type
  
  enum
  {
      MAX_WIREGUARD_PACKET_SIZE = 65536 + 64,
  };
  
  enum result_type
  {
      WIREGUARD_DONE = 0,
      WRITE_TO_NETWORK = 1,
      WIREGUARD_ERROR = 2,
      WRITE_TO_TUNNEL_IPV4 = 4,
      WRITE_TO_TUNNEL_IPV6 = 6,
  };
  
  enum log_level
  {
      NONE = 0,
      INFO = 1,
      DEB = 2,
      ALL = 3,
  };
  
  struct wireguard_result
  {
      enum result_type op;
      size_t size;
  };
  
  struct stats
  {
      int64_t time_since_last_handshake;
      size_t tx_bytes;
      size_t rx_bytes;
      float estimated_loss;
      int32_t estimated_rtt; // rtt estimated on time it took to complete lateset initiated handshake in ms
      uint8_t reserved[56];  // decrement appropriately when adding new fields
  };
  
  struct x25519_key
  {
      uint8_t key[32];
  };
  
  // Generates a fresh x25519 secret key
  struct x25519_key x25519_secret_key();
  // Computes an x25519 public key from a secret key
  struct x25519_key x25519_public_key(struct x25519_key private_key);
  // Encodes a public or private x25519 key to base64. Must be freed with x25519_key_to_str_free.
  const char *x25519_key_to_base64(struct x25519_key key);
  // Encodes a public or private x25519 key to hex. Must be freed with x25519_key_to_str_free.
  const char *x25519_key_to_hex(struct x25519_key key);
  // Free string pointer obtained from either x25519_key_to_base64 or x25519_key_to_hex
  void x25519_key_to_str_free(const char *key_str);
  // Check if a null terminated string represents a valid x25519 key
  // Returns 0 if not
  int check_base64_encoded_x25519_key(const char *key);
  
  // Allocate a new tunnel
  struct wireguard_tunnel *new_tunnel(const char *static_private,
                                      const char *server_static_public,
                                      void (*log_printer)(const char *),
                                      enum log_level log_level);
  
  // Deallocate the tunnel
  void tunnel_free(struct wireguard_tunnel *);
  
  struct wireguard_result wireguard_write(struct wireguard_tunnel *tunnel,
                                          const uint8_t *src,
                                          uint32_t src_size,
                                          uint8_t *dst,
                                          uint32_t dst_size);
  
  struct wireguard_result wireguard_read(struct wireguard_tunnel *tunnel,
                                         const uint8_t *src,
                                         uint32_t src_size,
                                         uint8_t *dst,
                                         uint32_t dst_size);
  
  struct wireguard_result wireguard_tick(struct wireguard_tunnel *tunnel,
                                         uint8_t *dst,
                                         uint32_t dst_size);
  
  struct wireguard_result wireguard_force_handshake(struct wireguard_tunnel *tunnel,
                                                    uint8_t *dst,
                                                    uint32_t dst_size);
  
  struct stats wireguard_stats(struct wireguard_tunnel *tunnel);
  
  const uint8_t *benchmark(int32_t name, uint32_t idx);
  