all repos — circe-vpn @ 556b655293e9ce71509a72ef3c98ea334b5aa85b

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
#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 100

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,
};

/// Initialize Circe core's global state
enum circe_result
circe_initialize_core (uint8_t identity[CIRCE_IDENTITY_LEN],
                       uint8_t mldsa_privkey[MLDSA_SECRETKEYBYTES (44)],
                       uint64_t now_ms);

/// Process a new incoming raw Circe packet.
enum circe_result circe_handle_packet (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 (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 (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 (uint64_t now_ms,
                              struct circe_outgoing_packet *out,
                              bool *new_packet_out);

#endif