You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

202 lines
9.8 KiB

/**
* @file etcp_api.h
* @brief API для приёма-передачи пакетов через ETCP (per-instance bindings)
*
* Основные функции:
* - etcp_send() - отправить пакет в очередь normalizer
* - etcp_bind() - подписаться на пакеты с определенным ID
* - etcp_int_recv() - коллбэк для сбора пакетов из всех подключений
* !!! для обычной отправки-приёма между узлами используем более универсальный модушь etcp_router.
* это в первую очередь - апи для использования etcp-router-ом
*
* Формат кодограмм: <cmd 1 byte> <data ... n bytes>
* cmd = 0 - пакет для передачи адресату
* cmd = 1 - модуль обмена роутинг-таблицами
*/
#ifndef ETCP_API_H
#define ETCP_API_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "../lib/ll_queue.h"
#define ETCP_MAX_BINDINGS 256
// === Raw ETCP packet IDs (etcp_bind/etcp_send) ===
#define ETCP_ID_DATA 0x00 // Пакет для передачи адресату
#define ETCP_ID_ROUTE_ENTRY 0x01 // Элемент роутинг-таблицы (BGP)
#define ETCP_ID_NAT_DETECTION 0x02 // NAT-детекция (STUN-like ping через третий узел)
#define ETCP_ID_SVC_ROUTE 0x03 // Транспорт роутера (etcp_router)
// === Router-сервисы (etcp_router_bind/etcp_route_send) ===
#define ETCP_RT_ID_DATA 0x00 // routing.c — маршрутизация данных
#define ETCP_RT_ID_NAT 0x02 // NAT трафик между узлами
#define ETCP_RT_ID_SVC_ROUTE 0x03 // etcp_router — транспорт роутера
#define ETCP_RT_ID_TCP_PROXY 0x04 // TCP proxy (клиент ↔ exit)
#define ETCP_RT_ID_UDP_PROXY 0x05 // UDP datagram прокси (client ↔ exit)
#define ETCP_RT_ID_ICMP_PROXY 0x06 // ICMP echo прокси (ping через exit)
#define ETCP_RT_ID_MSG_TRANSPORT 0x10 // msg_transport — локальный IPC транспорт сообщений
#define ETCP_RT_ID_CONN_MGR 0x11 // Connection Manager — management connections
#define ETCP_RT_ID_NTP_TIME 0x12 // NTP time sync между узлами
// Connection status events (instance-level callback)
#define ETCP_CONN_STATUS_NEW 0 // соединение создано
#define ETCP_CONN_STATUS_UP 1 // соединение поднялось
#define ETCP_CONN_STATUS_DOWN 2 // соединение упало
#define ETCP_CONN_STATUS_DELETE 3 // соединение удалено
// Forward declarations
struct ETCP_CONN;
struct UTUN_INSTANCE;
typedef void (*etcp_conn_status_fn)(struct ETCP_CONN* conn, int status, void* arg);
struct etcp_status_cbk_entry {
etcp_conn_status_fn fn;
void* arg;
struct etcp_status_cbk_entry* next;
};
/**
* @brief Тип коллбэка для приёма метрик от пира
* @param user_ptr пользовательский указатель
* @param conn ETCP соединение от которого получены метрики
* @param csv CSV-строка метрик
* @param csv_len длина строки
* @param sig Ed25519 подпись (64 байта) или NULL если ключ неизвестен
*/
typedef void (*etcp_metrics_fn)(void* user_ptr, struct ETCP_CONN* conn,
const uint8_t* csv, uint32_t csv_len,
const uint8_t* sig);
/**
* @brief Тип коллбэка для приёма пакетов
* @param conn ETCP соединение от которого получен пакет
* @param entry Элемент очереди с данными пакета
*
* @note Коллбэк должен освободить entry через queue_entry_free()
* и dgram через queue_dgram_free() после обработки
*/
typedef void (*etcp_recv_fn)(struct ETCP_CONN* conn, struct ll_entry* entry);
// Forward declaration
struct ETCP_CONN;
struct UTUN_INSTANCE;
struct TOPO_NODEQ;
typedef void (*etcp_cbk_fn)(struct ETCP_CONN* conn, void* arg);
// ---- Background connection initialization ----
#define ETCP_CONNECT_EARLY 1
#define ETCP_CONNECT_LATE 2
#define ETCP_CONNECT_BGP_READY 4 // BGP-синхронизация завершена
typedef void (*etcp_connect_callback_t)(void* arg, struct ETCP_CONN* conn, int type);
int etcp_connect(struct UTUN_INSTANCE* instance, struct TOPO_NODEQ* node,
etcp_connect_callback_t cb, void* arg, uint8_t flags);
/**
* @brief Установить callback при создании нового ETCP соединения
*
* @param instance UTUN instance
* @param callback_fn Коллбэк который будет вызван при создании нового соединения
* @param arg Аргумент для коллбэка
*/
void etcp_set_new_conn_cbk(struct UTUN_INSTANCE* instance, etcp_cbk_fn callback_fn, void* arg);
/**
* @brief Структура bindings для ETCP API (per-instance)
*/
struct ETCP_BINDINGS {
etcp_recv_fn callbacks[ETCP_MAX_BINDINGS]; /**< Массив callbacks, NULL = не установлен */
etcp_metrics_fn on_metrics_rcvd; /**< Callback приёма метрик от пира */
void* metrics_user_ptr; /**< Аргумент для on_metrics_rcvd */
};
/**
* @brief Отправить пакет в очередь normalizer. первый байт кодограммы - cmd (на приёмной стороне bind выберет обработчик по cmd).
*
* @param conn ETCP соединение
* @param entry Элемент очереди с данными для отправки
* @return 0 при успехе, -1 при ошибке
*
* @note Функция забирает ownership entry - вызывающий код не должен
* освобождать entry после вызова
*/
int etcp_send(struct ETCP_CONN* conn, struct ll_entry* entry);
/**
* @brief Подписаться на все пакеты с указанным ID для данного instance
*
* @param inst UTUN instance
* @param id Идентификатор пакета (первый байт кодограммы, cmd)
* @param callback Коллбэк для обработки пакетов с этим ID
* @return 0 при успехе, -1 при ошибке
*
* @note ID=0 зарезервирован для обычных пакетов данных
* @note Можно зарегистрировать только один коллбэк на каждый ID в пределах instance
*/
int etcp_bind(struct UTUN_INSTANCE* inst, uint8_t id, etcp_recv_fn callback);
/**
* @brief Отписаться от пакетов с указанным ID для данного instance
*
* @param inst UTUN instance
* @param id Идентификатор пакета
* @return 0 при успехе, -1 если binding не найден
*/
int etcp_unbind(struct UTUN_INSTANCE* inst, uint8_t id);
/**
* @brief Установить callback на событие готовности соединения
*
* После создания подключения надо дождаться conn_ready (соединение инициализировано).
* Только после этого можно передавать сообщения. Иначе сообщения могут потеряться.
* conn_ready может вызываться несколько раз (после каждого переподключения).
*
* @param conn ETCP соединение
* @param callback_fn Коллбэк который будет вызван при готовности
* @param arg Аргумент для коллбэка
*/
void etcp_conn_set_init_cbk(struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg);
void etcp_conn_set_up_cbk (struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg);
void etcp_conn_set_down_cbk (struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg);
void etcp_conn_add_init_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg);
void etcp_conn_remove_init_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg);
void etcp_conn_add_up_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg);
void etcp_conn_remove_up_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg);
void etcp_conn_add_down_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg);
void etcp_conn_remove_down_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg);
void etcp_add_new_conn_cbk(struct UTUN_INSTANCE* inst, etcp_cbk_fn fn, void* arg);
void etcp_remove_new_conn_cbk(struct UTUN_INSTANCE* inst, etcp_cbk_fn fn, void* arg);
void etcp_add_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg);
void etcp_remove_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg);
void etcp_set_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg);
void etcp_set_routing_exchange_state(struct ETCP_CONN* conn, uint8_t new_state);
/**
* @brief Внутренняя функция etcp: Коллбэк для очередей output ll_queue normalizer
*
* Собирает пакеты из всех подключений и отправляет в bind->cbk
* по ID (первый байт кодограммы).
*
* @param queue Очередь из которой получен пакет
* @param arg Аргумент - указатель на ETCP_CONN
*
* @note Этот коллбэк устанавливается автоматически при создании
* ETCP подключения через pn_init()
*/
void etcp_int_recv(struct ll_queue* queue, void* arg);
#ifdef __cplusplus
}
#endif
#endif // ETCP_API_H