/* * msg_transport.h — TCP-сервер транспорта сообщений (local IPC → ETCP) * * Принимает TCP-соединения от локальных приложений. * Каждое соединение привязывается (BIND) к конкретному remote peer node_id. * Сообщения от локального клиента пересылаются пиру через etcp_router, * сообщения от пира доставляются локальному клиенту. * * Формат фрейма на TCP: * [size:2 (uint16_t, native endian)] [type:1] [id:8 (uint64_t)] [options:1] [data...] * size включает само поле size. */ #ifndef MSG_TRANSPORT_H #define MSG_TRANSPORT_H #include #include "../lib/socket_compat.h" #ifdef __cplusplus extern "C" { #endif /* ============================================================================ * Протокол * ============================================================================ */ #define MSG_MAX_MSG_SIZE 8192 #define MSG_SIGN_SIZE 64 /* Ed25519 */ /* Options byte bits */ #define MSG_OPT_SIGNED 0x01 /* Типы сообщений */ #define MSG_CTL_BIND 0x01 /* GUI→utun: привязать TCP-соединение к пиру id */ #define MSG_CTL_UNBIND 0x02 /* GUI→utun: отвязать */ #define MSG_CTL_GET_PUBKEY 0x03 /* GUI→utun: запросить публичный ключ */ #define MSG_CTL_GET_PRIVKEY 0x04 /* GUI→utun: запросить приватный ключ (только localhost) */ #define MSG_CTL_GET_PEER_INFO 0x05 /* GUI→utun: запросить ключи пира id (pubkey + ed25519_pubkey) */ #define MSG_DATA_SEND 0x10 /* GUI→utun: отправить сообщение пиру id */ #define MSG_DATA_RECV 0x11 /* utun→GUI: получено сообщение от пира id */ #define MSG_RSP_BIND_OK 0xE1 /* utun→GUI: BIND успешен */ #define MSG_RSP_PUBKEY 0xE2 /* utun→GUI: публичный ключ (32 байта) */ #define MSG_RSP_PRIVKEY 0xE3 /* utun→GUI: приватный ключ (32 байта) */ #define MSG_RSP_PEER_INFO 0xE4 /* utun→GUI: ключи пира (pubkey+edpub=64 байта) */ #define MSG_RSP_ERROR 0xFF /* utun→GUI: ошибка */ /* Коды ошибок для MSG_RSP_ERROR */ #define MSG_ERR_INVALID_MSG 0x01 #define MSG_ERR_NOT_BOUND 0x02 #define MSG_ERR_NO_ROUTE 0x03 #define MSG_ERR_SEND_FAILED 0x04 #define MSG_ERR_ACCESS_DENIED 0x07 #define MSG_ERR_PEER_NOT_FOUND 0x08 #define MSG_ERR_ID_TAKEN 0x06 #pragma pack(push, 1) struct msg_header { uint16_t size; /* полный размер сообщения, включая это поле */ uint8_t type; /* тип (MSG_CTL_* / MSG_DATA_* / MSG_RSP_*) */ uint64_t id; /* peer node_id */ uint8_t options; /* битовые флаги (MSG_OPT_*) */ }; #pragma pack(pop) #define MSG_HDR_SIZE sizeof(struct msg_header) /* 12 */ static inline void msg_build_header(struct msg_header* hdr, uint16_t payload_size, uint8_t msg_type, uint64_t id, uint8_t options) { hdr->size = MSG_HDR_SIZE + payload_size; hdr->type = msg_type; hdr->id = id; hdr->options = options; } static inline int msg_validate_header(const struct msg_header* hdr) { if (hdr->size < MSG_HDR_SIZE || hdr->size > MSG_MAX_MSG_SIZE) return -1; return 0; } /* ============================================================================ * Счётчики (диагностика) * ============================================================================ */ struct UTUN_INSTANCE; struct UASYNC; struct msg_transport; struct msg_transport_counters { uint64_t accepted; uint64_t closed; uint64_t bind_count; uint64_t unbind_count; uint64_t msg_sent_to_peer; uint64_t msg_recv_from_peer; uint64_t msg_sent_to_client; uint64_t errors; uint64_t drops_no_client; uint64_t drops_no_route; }; /* ============================================================================ * API * ============================================================================ */ int msg_transport_init(struct msg_transport** out, struct UTUN_INSTANCE* instance, struct UASYNC* ua, struct sockaddr_storage* bind_addr, uint32_t max_clients, uint8_t svc_id); void msg_transport_shutdown(struct msg_transport* t); void msg_transport_get_counters(struct msg_transport* t, struct msg_transport_counters* c); #ifdef __cplusplus } #endif #endif /* MSG_TRANSPORT_H */