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.
181 lines
7.9 KiB
181 lines
7.9 KiB
#ifndef CONN_MGR_PRIV_H |
|
#define CONN_MGR_PRIV_H |
|
|
|
#include "conn_mgr.h" |
|
#include <stdint.h> |
|
#include "../lib/ll_queue.h" |
|
#include "etcp_api.h" |
|
#include "secure_channel.h" |
|
#include "../transport_layer/node_conn_direct.h" |
|
#include "topo_node.h" |
|
|
|
struct UTUN_INSTANCE; |
|
struct ETCP_CONN; |
|
struct ETCP_LINK; |
|
struct ETCP_SOCKET; |
|
struct ETCP_ROUTER_CONN; |
|
struct TOPO_GROUP_NODE; |
|
struct TOPO_GROUP; |
|
struct stcp_link; |
|
struct stcp_client; |
|
|
|
/* ═══════ константы ═══════ */ |
|
|
|
#define CONN_MGR_MAX_CANDIDATES 3 |
|
#define CONN_MGR_CANDIDATE_STALE_TB 300000 |
|
#define CONN_MGR_CANDIDATE_PING_TB 20000 |
|
#define CONN_MGR_BG_PING_INTERVAL_TB 1000 |
|
#define CONN_MGR_BG_PING_CYCLE_MIN_TB 600000 |
|
#define CONN_MGR_LOCAL_SCAN_ATTEMPTS 3 |
|
#define CONN_MGR_LOCAL_SCAN_TIMEOUT_MS 100 |
|
#define CONN_MGR_CONNECT_DIRECT_TIMEOUT_MS 2000 |
|
#define CONN_MGR_CONNECT_REVERSE_TIMEOUT_MS 3000 |
|
#define CONN_MGR_INTERM_EXCHANGE_TIMEOUT_MS 15000 |
|
#define CONN_MGR_REVERSE_RETRANSMIT_MS 1000 |
|
#define CONN_MGR_EXCHANGE_RETRANSMIT_MS 1000 |
|
#define CACHE_MS 20000 /* время жизни RTT-замера ~20с (через cm_is_rtt_fresh, мс) */ |
|
#define CONN_MGR_MAX_INTERMEDIARIES 3 |
|
|
|
/* ═══════ состояния ═══════ */ |
|
|
|
enum CONN_MGR_STATE { |
|
CONN_MGR_STATE_DISCONNECTED = 0, |
|
CONN_MGR_STATE_CONNECTING = 1, |
|
CONN_MGR_STATE_CONNECTED = 2, |
|
CONN_MGR_STATE_FAILED = 3, |
|
}; |
|
|
|
enum CM_TRY_STATE { |
|
CM_TRY_NONE = 0, |
|
CM_TRY_PENDING = 1, |
|
CM_TRY_OK = 2, |
|
CM_TRY_FAILED = 3, |
|
}; |
|
|
|
/* ═══════ протокол CONN_MGR (ETCP_RT_ID_CONN_MGR) ═══════ */ |
|
|
|
enum { |
|
CM_SUBCMD_DIRECT_REQ = 0x01, |
|
CM_SUBCMD_DIRECT_RESP = 0x02, |
|
CM_SUBCMD_INTERM_EXCHANGE_REQ = 0x03, |
|
CM_SUBCMD_INTERM_EXCHANGE_RESP= 0x04, |
|
CM_SUBCMD_INTERM_SELECTED = 0x05, |
|
CM_SUBCMD_DISCONNECT = 0x06, |
|
}; |
|
|
|
struct CONN_MGR_CANDIDATE { uint64_t node_id; uint16_t rtt; } __attribute__((packed)); |
|
|
|
#pragma pack(push, 1) |
|
struct CM_DIRECT_REQ { uint8_t cmd, subcmd; uint32_t request_id; uint8_t addr_count; }; |
|
struct CM_DIRECT_RESP { uint8_t cmd, subcmd; uint32_t request_id; uint8_t accepted; }; |
|
struct CM_EXCHANGE_REQ { uint8_t cmd, subcmd; uint32_t request_id; uint8_t candidate_count; struct CONN_MGR_CANDIDATE candidates[4]; }; |
|
struct CM_EXCHANGE_RESP { uint8_t cmd, subcmd; uint32_t request_id; uint8_t my_count, your_count; struct CONN_MGR_CANDIDATE my_candidates[4], your_candidates[4]; }; |
|
struct CM_INTERM_SEL { uint8_t cmd, subcmd; uint32_t request_id; uint8_t count; struct CONN_MGR_CANDIDATE selected[3]; }; |
|
struct CM_DISCONNECT { uint8_t cmd, subcmd; uint64_t node_id; }; |
|
#pragma pack(pop) |
|
|
|
#define CM_DIRECT_REQ_H_SIZE (sizeof(struct CM_DIRECT_REQ)) |
|
#define CM_DIRECT_RESP_HDR_SIZE (sizeof(struct CM_DIRECT_RESP)) |
|
#define CM_EXCHANGE_REQ_SIZE (sizeof(struct CM_EXCHANGE_REQ)) |
|
#define CM_EXCHANGE_RESP_SIZE (sizeof(struct CM_EXCHANGE_RESP)) |
|
#define CM_INTERM_SEL_SIZE (sizeof(struct CM_INTERM_SEL)) |
|
#define CM_DISCONNECT_SIZE (sizeof(struct CM_DISCONNECT)) |
|
|
|
/* ═══════ внутренние структуры ═══════ */ |
|
|
|
struct cm_reverse_pending { struct cm_reverse_pending* next; uint32_t request_id; struct CONN_MGR_ENTRY* entry; uint8_t* pkt; size_t pkt_len; }; |
|
|
|
struct cm_exchange_pending { |
|
struct cm_exchange_pending* next; uint32_t request_id; |
|
struct CONN_MGR_ENTRY* entry; void* timer; |
|
struct CM_EXCHANGE_RESP cached; uint8_t received, probed; |
|
uint8_t* pkt; size_t pkt_len; |
|
}; |
|
|
|
struct CONN_MGR_HANDLE { |
|
uint64_t node_id; uint64_t group_id; conn_mgr_cb_t cb; void* cb_arg; |
|
struct CONN_MGR_ENTRY* entry; struct CONN_MGR_HANDLE* next; |
|
void* deliver_up_token; /* токен отложенного cm_deliver_up_cb (uasync_call_soon), NULL если не постился/уже сработал */ |
|
}; |
|
|
|
struct CONN_MGR_ENTRY { |
|
struct ll_entry ll; /* ll_queue entry — первый элемент */ |
|
uint64_t node_id; /* хеш-ключ 8B, offset от data = 0 */ |
|
uint8_t state, conn_type; |
|
uint64_t last_traffic_tb; |
|
struct CONN_MGR_HANDLE* handles; struct NODE_CONN_DIRECT* ncd_handle; |
|
uint8_t ncd_down_notified; |
|
uint64_t intermediaries[3]; uint8_t intermediariy_count, rr_idx; |
|
uint8_t local_scan_state, main_connect_state, db_loaded; |
|
uint8_t reverse_active, indirect_active, indirect_ready; |
|
void* reverse_timer; |
|
uint64_t reverse_deadline_tb, indirect_deadline_tb; |
|
struct { void* timer; uint32_t request_id; void* conn_ctx; } main; |
|
struct CONN_MGR* mgr; |
|
}; |
|
|
|
struct CONN_MGR { |
|
struct UTUN_INSTANCE* instance; struct TOPO_GROUP* group; |
|
struct ll_queue* entries; |
|
void *bg_ping_timer, *candidate_ping_timer; |
|
void *bg_ping_wait, *candidate_ping_wait; /* standby_wait handle (Android) */ |
|
size_t bg_ping_cursor; uint64_t bg_ping_cycle_start_tb; |
|
struct CONN_MGR_CANDIDATE best_candidates[CONN_MGR_MAX_CANDIDATES]; uint8_t best_candidate_count; |
|
struct stcp_client* cand_tcp_pings[CONN_MGR_MAX_CANDIDATES]; /* влётные candidate TCP-пинги (для отмены при destroy) */ |
|
uint32_t next_request_id, direct_timeout_ms; uint8_t initialized; |
|
struct cm_reverse_pending* reverse_pending; |
|
struct cm_exchange_pending* exchange_pending; |
|
uint8_t _unused[0]; |
|
}; |
|
|
|
/* ═══════ декларации внутренних функций ═══════ */ |
|
|
|
/* core — публичные (в priv.h, не в conn_mgr.h) */ |
|
int cm_open(struct CONN_MGR* mgr, uint64_t node_id, |
|
conn_mgr_cb_t cb, void* cb_arg, struct CONN_MGR_HANDLE** out_handle); |
|
|
|
/* core */ |
|
struct CONN_MGR_ENTRY* cm_find_entry(struct CONN_MGR* mgr, uint64_t node_id); |
|
struct CONN_MGR_ENTRY* cm_ensure_entry(struct CONN_MGR* mgr, uint64_t node_id); |
|
void cm_entry_cleanup(struct CONN_MGR_ENTRY* entry); |
|
void cm_cleanup_db_node(struct CONN_MGR_ENTRY* entry); |
|
void cm_deliver_event(struct CONN_MGR_ENTRY* entry, enum conn_mgr_event event); |
|
void cm_update_nodeinfo(struct CONN_MGR_ENTRY* entry); |
|
void cm_clear_nodeinfo(struct CONN_MGR* mgr, uint64_t node_id); |
|
void cm_ncd_callback(struct NODE_CONN_DIRECT* ncd_h, enum ncd_event ncd_ev, void* arg); |
|
void cm_start_phase_direct(struct CONN_MGR_ENTRY* entry); |
|
void cm_start_phase_reverse(struct CONN_MGR_ENTRY* entry); |
|
void cm_start_phase_indirect(struct CONN_MGR_ENTRY* entry); |
|
void cm_start_local_scan(struct CONN_MGR_ENTRY* entry); |
|
void cm_handle_direct_req(uint64_t src, struct CONN_MGR* mgr, const uint8_t* data, size_t len); |
|
void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id); |
|
void cm_reverse_tick_cb(void* arg); |
|
void cm_finalize_indirect(struct CONN_MGR_ENTRY* entry); |
|
void cm_add_v4_link(struct ETCP_CONN* conn, const uint8_t* addr, uint16_t port, struct ETCP_SOCKET* s); |
|
void cm_add_v6_link(struct ETCP_CONN* conn, const uint8_t addr[16], uint16_t port, struct ETCP_SOCKET* s); |
|
int cm_has_direct_ip(struct CONN_MGR* mgr, struct TOPO_GROUP_NODE* nq); |
|
int cm_has_local_addr(struct CONN_MGR* mgr, struct TOPO_GROUP_NODE* nq); |
|
uint8_t cm_classify_v6_addr(const uint8_t addr[16]); |
|
uint8_t cm_sock_v6_classify(const struct ETCP_SOCKET* s); |
|
|
|
#define CM_V6_LL 0 |
|
#define CM_V6_LOC 1 |
|
#define CM_V6_DIR 2 |
|
#define CM_V6_OTH 3 |
|
#define CM_V6_ANY 4 |
|
|
|
/* indirect */ |
|
void cm_exchange_tick_cb(void* arg); |
|
void cm_compute_intermediaries(struct CONN_MGR_ENTRY* entry, struct CM_EXCHANGE_RESP* resp); |
|
void cm_exchange_probe_retry_cb(void* arg); |
|
void cm_handle_interm_exchange_req(uint64_t src, struct CONN_MGR* mgr, struct CM_EXCHANGE_REQ* req); |
|
void cm_handle_interm_exchange_resp(struct CONN_MGR* mgr, const uint8_t* data, size_t len); |
|
void cm_handle_interm_selected(struct CONN_MGR* mgr, uint64_t src, const uint8_t* data, size_t len); |
|
|
|
/* monitor */ |
|
void cm_bg_ping_timer_cb(void* arg); |
|
void cm_candidate_ping_timer_cb(void* arg); |
|
uint64_t cm_get_node_max_probe_time(struct TOPO_GROUP_NODE* nq); |
|
int cm_is_rtt_fresh(struct TOPO_GROUP_NODE* nq, uint64_t now_tb); |
|
|
|
#endif
|
|
|