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.
210 lines
8.9 KiB
210 lines
8.9 KiB
#ifndef ROUTE_NODE_H |
|
#define ROUTE_NODE_H |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#include <stdint.h> |
|
#include <stddef.h> |
|
#include "../lib/ll_queue.h" |
|
#include "secure_channel.h" |
|
|
|
struct ROUTE_BGP; |
|
struct ETCP_SOCKET; |
|
struct UTUN_INSTANCE; |
|
|
|
// ---- типы адресов в плоском списке NODEINFO_IPV4_ADDR ---- |
|
|
|
#define ADDR_TYPE_INTERFACE 0 // interface_addr сокета (LAN) |
|
#define ADDR_TYPE_NAT 1 // nat_addr после детекции NAT |
|
#define ADDR_TYPE_REAL 2 // подтверждённый прямой интернет-адрес (nat проверка показала совпадение с interface_addr) |
|
|
|
// ---- протоколы транспорта (поле protocol в NODEINFO_IPV4_ADDR/NODEINFO_IPV6_ADDR) ---- |
|
#define NODE_PROTO_UDP 0x01 |
|
#define NODE_PROTO_TCP 0x02 |
|
|
|
// ---- типы NAT (etcp_connections.h) ---- |
|
// NAT_TYPE_UNKNOWN(0), NAT_TYPE_EIM(1), NAT_TYPE_STRICT(2) |
|
// NAT_VERIFIED_UNKNOWN(4), NAT_VERIFIED_EIM(5), NAT_VERIFIED_STRICT(6), NAT_VERIFIED_DIRECT(7) |
|
|
|
// ---- статусы зондирования связности ---- |
|
|
|
#define PROBE_STATUS_NONE 0 |
|
#define PROBE_STATUS_IN_PROGRESS 1 |
|
#define PROBE_STATUS_DONE 2 |
|
|
|
#define PROBE_RESULT_UNKNOWN 0 |
|
#define PROBE_RESULT_REACHABLE 1 |
|
#define PROBE_RESULT_UNREACHABLE 2 |
|
|
|
#define CONN_PROBE_COUNT 3 |
|
#define CONN_PROBE_TIMEOUT_MS 1000 |
|
|
|
#define CONN_TYPE_NONE 0 |
|
#define CONN_TYPE_DIRECT 1 |
|
#define CONN_TYPE_REVERSE 2 |
|
#define CONN_TYPE_INDIRECT 3 |
|
#define CONN_MGR_MAX_INTERMEDIARIES 3 |
|
|
|
// ---- состояние связности с удалённым узлом (локальное, не передаётся по BGP) ---- |
|
|
|
struct NODE_CONNECTIVITY { |
|
uint8_t probe_status; // PROBE_STATUS_* |
|
uint8_t pending_count; // активных probe series |
|
uint64_t probe_start_time; // timebase |
|
uint16_t interface_min_rtt; // x0.1ms |
|
uint16_t nat_min_rtt; |
|
uint16_t real_min_rtt; |
|
uint8_t interface_status; // PROBE_RESULT_* |
|
uint8_t nat_status; |
|
uint8_t real_status; |
|
uint8_t reserved; |
|
uint64_t interface_probe_time; |
|
uint64_t nat_probe_time; |
|
uint64_t real_probe_time; |
|
uint64_t ping_req_time; // время последнего полученного ping request от этого узла (0.1ms tb) |
|
void* probe_list; // linked list of active conn_probe_ctx (для cancel) |
|
}; |
|
|
|
/** |
|
* @brief Информация о узле (передаётся по BGP) |
|
*/ |
|
struct NODEINFO { |
|
uint64_t node_id; // (big-endian) |
|
uint8_t ver; // версия пакета (циклический счетчик чтобы быстро сравнивать с локальной копией - были ли обновления) |
|
uint8_t public_key[SC_PUBKEY_SIZE]; // X25519 pubkey |
|
uint8_t ed25519_public_key[SC_PUBKEY_SIZE]; // Ed25519 pubkey for signature verification |
|
uint8_t node_name_len; // размер в байтах (без null терминации) |
|
uint8_t local_v4_sockets; // NODEINFO_IPV4_SOCKET_META число метаданных ipv4 сокетов |
|
uint8_t local_v4_addrs; // NODEINFO_IPV4_ADDR число типизированных ipv4 адресов узла (плоский список) |
|
uint8_t local_v6_sockets; // NODEINFO_IPV6_SOCKET_META число метаданных ipv6 сокетов |
|
uint8_t local_v6_addrs; // NODEINFO_IPV6_ADDR число типизированных ipv6 адресов узла |
|
uint8_t local_v4_subnets; // NODEINFO_IPV4_SUBNET число локальных ipv4 подсетей узла |
|
uint8_t local_v6_subnets; // NODEINFO_IPV6_SUBNET число локальных ipv6 подсетей узла |
|
uint8_t tranzit_nodes; // NODEINFO_TRANZIT_NODE лучшие транзитные узлы для этой ноды |
|
uint8_t hop_count; // hop list: маршрут по которому распространялся этот NODEINFO_PACKET |
|
// далее идут динамические поля по порядку: |
|
// char node_name[node_name_len] |
|
// NODEINFO_IPV4_SOCKET_META[local_v4_sockets] |
|
// NODEINFO_IPV4_ADDR[local_v4_addrs] |
|
// NODEINFO_IPV6_SOCKET_META[local_v6_sockets] |
|
// NODEINFO_IPV6_ADDR[local_v6_addrs] |
|
// NODEINFO_IPV4_SUBNET[local_v4_subnets] |
|
// NODEINFO_IPV6_SUBNET[local_v6_subnets] |
|
// NODEINFO_TRANZIT_NODE[tranzit_nodes] |
|
// uint64_t hop_list[hop_count] |
|
} __attribute__((packed)); |
|
|
|
// метаданные одного сокета |
|
struct NODEINFO_IPV4_SOCKET_META { |
|
uint8_t id; // unique socket id (0-255) |
|
uint8_t config_type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE |
|
uint8_t nat_type; // NAT_TYPE_* / NAT_VERIFIED_* |
|
} __attribute__((packed)); |
|
|
|
// одна типизированная адресная запись (плоский список) |
|
struct NODEINFO_IPV4_ADDR { |
|
uint8_t addr[4]; // IP (network byte order) |
|
uint16_t port; // port (host byte order) |
|
uint8_t type; // ADDR_TYPE_INTERFACE/NAT/REAL |
|
uint8_t socket_id; // к какому сокету относится |
|
uint8_t protocol; // битовая маска NODE_PROTO_UDP/NODE_PROTO_TCP |
|
} __attribute__((packed)); |
|
|
|
struct NODEINFO_IPV6_SOCKET_META { |
|
uint8_t id; // unique socket id (0-255) |
|
uint8_t config_type; // CFG_SERVER_TYPE_PUBLIC/NAT/PRIVATE |
|
uint8_t nat_type; // NAT_TYPE_* / NAT_VERIFIED_* |
|
} __attribute__((packed)); |
|
|
|
struct NODEINFO_IPV6_ADDR { |
|
uint8_t addr[16]; |
|
uint16_t port; |
|
uint8_t type; |
|
uint8_t socket_id; |
|
uint8_t protocol; // битовая маска NODE_PROTO_UDP/NODE_PROTO_TCP |
|
} __attribute__((packed)); |
|
|
|
struct NODEINFO_IPV4_SUBNET { |
|
uint8_t addr[4];// network byte order |
|
uint8_t prefix_length; |
|
} __attribute__((packed)); |
|
|
|
struct NODEINFO_IPV6_SUBNET { |
|
uint8_t addr[16]; |
|
uint8_t prefix_length; |
|
} __attribute__((packed)); |
|
|
|
struct NODEINFO_TRANZIT_NODE { |
|
uint64_t node_id; // (big-endian) |
|
uint16_t rtt; // x0.1 ms (измеренный удаленным узлом RTT до транзитного узла) |
|
uint16_t link_q; // меньше - лучше (потери + 1/BW) |
|
} __attribute__((packed)); |
|
|
|
struct NODEINFO_PATH { |
|
struct ll_entry ll; |
|
struct ETCP_CONN* conn; |
|
uint8_t hop_count; // hop list: маршрут этого path |
|
}; |
|
|
|
struct NODEINFO_Q { |
|
struct ll_entry ll; |
|
struct ll_queue* paths; // сюда помещаем struct NODEINFO_PATH |
|
uint8_t dirty; |
|
uint8_t last_ver; |
|
uint8_t alien; // 1 = чужой узел (не запрашиваем роутинг при connect) |
|
uint8_t conn_mgr_type; // CONN_TYPE_* — тип managed-подключения |
|
uint64_t conn_mgr_intermediaries[CONN_MGR_MAX_INTERMEDIARIES]; // посредники для INDIRECT |
|
uint8_t conn_mgr_intermediariy_count; |
|
struct NODE_CONNECTIVITY connectivity; // состояние связности (локальное) |
|
struct ETCP_SOCKET* best_socket; |
|
struct NODEINFO node; // Всегда в конце структуры - динамически расширяемый блок |
|
}; |
|
|
|
|
|
/** |
|
* @brief Создаёт/обновляет nodeinfo для собственного узла |
|
*/ |
|
int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BGP* bgp); |
|
|
|
/** |
|
* @brief Получает указатель на массив IPv4-подсетей узла (без malloc/копирования). |
|
*/ |
|
int get_node_routes(struct NODEINFO_Q *node, const struct NODEINFO_IPV4_SUBNET **out_subnets); |
|
|
|
/** |
|
* @brief Получает указатель на массив IPv6-подсетей узла (без malloc/копирования). |
|
*/ |
|
int get_node_v6_routes(struct NODEINFO_Q *node, const struct NODEINFO_IPV6_SUBNET **out_subnets); |
|
|
|
/** |
|
* @brief Получает указатель на массив метаданных IPv4-сокетов узла. |
|
*/ |
|
int get_node_v4_sockets_meta(struct NODEINFO_Q *node, const struct NODEINFO_IPV4_SOCKET_META **out_meta); |
|
|
|
/** |
|
* @brief Получает указатель на плоский список IPv4-адресов узла. |
|
*/ |
|
int get_node_v4_addrs(struct NODEINFO_Q *node, const struct NODEINFO_IPV4_ADDR **out_addrs); |
|
|
|
/** |
|
* @brief Получает указатель на массив метаданных IPv6-сокетов узла. |
|
*/ |
|
int get_node_v6_sockets_meta(struct NODEINFO_Q *node, const struct NODEINFO_IPV6_SOCKET_META **out_meta); |
|
|
|
/** |
|
* @brief Получает указатель на плоский список IPv6-адресов узла. |
|
*/ |
|
int get_node_v6_addrs(struct NODEINFO_Q *node, const struct NODEINFO_IPV6_ADDR **out_addrs); |
|
|
|
struct NODEINFO_Q* nodeinfo_find_by_id(struct ROUTE_BGP* bgp, uint64_t node_id); |
|
|
|
void route_node_dump_all(struct ROUTE_BGP* bgp); |
|
int route_node_format_all(struct ROUTE_BGP* bgp, char* buf, size_t buf_size); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif |
|
|
|
#endif // ROUTE_NODE_H
|
|
|