all repos — circe-vpn @ 7105ecea863e8330ab95c89a34f2e96e71c90f41

Circe VPN

core/core.h (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
#ifndef CIRCE_CORE_H
#define CIRCE_CORE_H

#include "mldsa_native.h"
#include "packet.h"
#include "peer_table.h"
#include <stddef.h>
#include <stdint.h>

#define CIRCE_MAX_OUTGOING_PACKETS 64
#define CIRCE_HEARTBEAT_PERIOD_MS 1000

enum circe_result
{
  CIRCE_RESULT_SUCCESS = 0,
  CIRCE_RESULT_INSUFFICIENT_MEM,
  CIRCE_RESULT_INVALID_PACKET,
  CIRCE_RESULT_INVALID_MAC,
  CIRCE_RESULT_INTERNAL_ERROR,
  CIRCE_RESULT_UNKNOWN_REMOTE,
  CIRCE_RESULT_OVER_MTU,
  CIRCE_RESULT_HANDSHAKE_PENDING,
  CIRCE_RESULT_PEER_TABLE_FULL,
  CIRCE_RESULT_RELAY_LOOKUP_FAILED,
  CIRCE_RESULT_PACKET_TABLE_FULL,
  CIRCE_RESULT_KEX_FAILED,
  CIRCE_RESULT_SIGNATURE_FAILED,
  CIRCE_RESULT_INVALID_SIGNATURE,
  CIRCE_RESULT_INVALID_TIMESTAMP,
  CIRCE_RESULT_DUPLICATE_HS_PACKET,
  CIRCE_RESULT_HS_OUT_OF_ORDER,
};

enum circe_version
{
  CIRCE_VERSION_V1 = 0,
};

struct circe_event
{
  enum
  {
    CIRCE_EVENT_DATA_RECEIVED,
    CIRCE_EVENT_NEW_REMOTE,
    CIRCE_EVENT_REJECTED_REMOTE,
  } event_type;
};

enum circe_deadline
{
  CIRCE_DEADLINE_NOW,
  CIRCE_DEADLINE_INDEFINITE,
  CIRCE_DEADLINE_AS_INDICATED,
};

struct circe_context
{
  struct circe_peer peer_table[CIRCE_PEER_TABLE_LEN];
  uint64_t peer_handshake_pending_mask;
  uint64_t peer_table_free_mask; // 1 if free, 0 if full
  struct circe_outgoing_packet outgoing_packets[CIRCE_MAX_OUTGOING_PACKETS];
  uint64_t outgoing_packet_table_free_mask; // 1 if free, 0 if full
  uint64_t last_tick_ms;
  uint8_t my_identity[CIRCE_IDENTITY_LEN];
  uint8_t my_mldsa_privkey[MLDSA_SECRETKEYBYTES (44)];

  void *ctx_handle;
  void (*random_bytes_callback) (void *ctx_handle, uint8_t *out, uint32_t len);
  bool (*recall_peer_callback) (void *ctx_handle,
                                const uint8_t identity[CIRCE_IDENTITY_LEN],
                                struct circe_peer *out);
};

/// Initialize Circe core's context state
enum circe_result circe_initialize_core (
    struct circe_context *ctx, uint8_t identity[CIRCE_IDENTITY_LEN],
    uint8_t mldsa_privkey[MLDSA_SECRETKEYBYTES (44)], uint64_t now_ms,
    void *ctx_handle,
    void (*random_bytes_callback) (void *, uint8_t *, uint32_t),
    bool (*recall_peer_callback) (void *, const uint8_t[CIRCE_IDENTITY_LEN],
                                  struct circe_peer *));

/// Process a new incoming raw Circe packet.
enum circe_result circe_handle_packet (struct circe_context *ctx,
                                       const struct circe_location remote,
                                       const uint8_t *restrict in, size_t len,
                                       uint8_t *restrict out, size_t *out_len,
                                       uint64_t now_ms,
                                       struct circe_event *events,
                                       size_t *n_events);

/// Put outgoing packet into Circe's internal logic. DOES NOT ACTUALLY SEND IT
/// OVER THE NETWORK; that is handled opaquely by the caller and `circe_tick`.
enum circe_result
circe_send_outgoing_packet (struct circe_context *ctx,
                            const uint8_t remote_identity[CIRCE_IDENTITY_LEN],
                            const uint8_t *in, size_t len, uint64_t now_ms,
                            struct circe_event *events, size_t *n_events);

/// Get deadline and corresponding millisecond timestamp (for
/// `CIRCE_DEADLINE_AS_INDICATED`) for next timer deadline, at which point
/// `circe_tick` should be called. Should always be called immediately after
/// any other core API function is called to stay up-to-date.
enum circe_deadline circe_next_deadline (struct circe_context *ctx,
                                         uint64_t *ms_timestamp);

/// Iterate the Circe core logic. Assumes `now_ms` increases monotonically with
/// time. If `new_packet_out` is true (do not pass in NULL for `out`), then
/// `out` contains a new raw Circe packet to be sent out to the location
/// `out.destination`.
enum circe_result circe_tick (struct circe_context *ctx, uint64_t now_ms,
                              struct circe_outgoing_packet *out,
                              bool *new_packet_out);

#endif