# ETCP API ## 1. Назначение Модуль предоставляет публичный API для отправки и приёма пакетов через ETCP-соединения. Это входная точка для всех вышележащих подсистем (роутер, маршрутизация, NAT, TCP-прокси, транспорт сообщений). **Ключевая идея:** приёмный коллбэк `etcp_int_recv` диспетчеризует входящие пакеты по первому байту кодограммы (`cmd`). Любой модуль может зарегистрировать обработчик на свой `cmd` через `etcp_bind` и слать данные через `etcp_send`. Формат кодограммы (сырой пакет внутри ETCP): ` <данные N байт>`. Модуль **тонкий**: отправка — просто `queue_data_put` в очередь normalizer'а, приём — выбор обработчика по ID из массива `ETCP_BINDINGS`. ## 2. Как пользоваться ### Типовой сценарий: модуль хочет принимать пакеты своего типа ```c // Регистрируем коллбэк при инициализации модуля etcp_bind(instance, ETCP_ID_DATA, my_data_recv_callback); // Коллбэк вызывается для каждого входящего пакета с cmd=ETCP_ID_DATA void my_data_recv_callback(struct ETCP_CONN* conn, struct ll_entry* entry) { // entry->dgram[0] = cmd (уже совпал с ETCP_ID_DATA) // entry->dgram[1..len-1] = данные process_data(conn, entry->dgram + 1, entry->len - 1); queue_dgram_free(entry); queue_entry_free(entry); } ``` ### Отправка пакета ```c struct ll_entry* e = queue_entry_new_from_pool(inst->data_pool); memcpy(e->dgram, &my_cmd, 1); memcpy(e->dgram + 1, payload, payload_len); e->len = 1 + payload_len; etcp_send(conn, e); // ownership entry передаётся ``` ### Коллбэки состояния соединения ```c // Срабатывает после INIT-handshake, можно слать данные etcp_conn_set_ready_cbk(conn, on_conn_ready, my_data); // Срабатывает при поднятии/падении соединения etcp_conn_set_up_cbk(conn, on_conn_up, my_data); etcp_conn_set_down_cbk(conn, on_conn_down, my_data); // На уровне instance — при создании нового входящего соединения etcp_set_new_conn_cbk(instance, on_new_conn, my_data); ``` **Важно:** коллбэки `set_*` заменяют всю цепочку одним обработчиком; `add_*`/`remove_*` добавляют/убирают обработчик в связном списке из нескольких коллбэков. ### Сервисные ID (для etcp_router) Используются `ETCP_RT_ID_*`, отличаются от сырых `ETCP_ID_*` (пакет оборачивается в транспортный ID `ETCP_ID_SVC_ROUTE=0x03`): - `ETCP_RT_ID_DATA` (0x00) — маршрутизация данных - `ETCP_RT_ID_NAT` (0x02) — NAT-трафик между узлами - `ETCP_RT_ID_SVC_ROUTE` (0x03) — транспорт роутера - `ETCP_RT_ID_TCP_PROXY` (0x04) — TCP-прокси - `ETCP_RT_ID_UDP_PROXY` (0x05) — UDP-прокси - `ETCP_RT_ID_ICMP_PROXY` (0x06) — ICMP-прокси - `ETCP_RT_ID_CONN_MGR` (0x11) — управление соединениями - `ETCP_ID_NTP_TIME` (0x04) — синхронизация времени (raw ETCP, P2P) ### Фоновые соединения (etcp_connect) ```c etcp_connect(instance, node, on_connect, arg, ETCP_CONNECT_EARLY | ETCP_CONNECT_LATE); ``` Флаги: `ETCP_CONNECT_EARLY` — раннее подключение, `ETCP_CONNECT_LATE` — отложенное. ## 3. API ### Структуры | Структура | Назначение | |-----------|-----------| | `ETCP_BINDINGS` | Per-instance массив `callbacks[256]` | ### Типы коллбэков | Тип | Сигнатура | Назначение | |-----|-----------|-----------| | `etcp_recv_fn` | `void(conn, entry)` | Приём пакета — **обязан** освободить entry/dgram | | `etcp_cbk_fn` | `void(conn, arg)` | События ready/up/down/new_conn | | `etcp_connect_callback_t` | `void(arg, conn, type)` | Результат фонового подключения | ### Функции | Функция | Назначение | |---------|-----------| | `etcp_bind(inst, id, fn)` | Подписаться на пакеты с cmd=`id` | | `etcp_unbind(inst, id)` | Отписаться | | `etcp_send(conn, entry)` | Отправить пакет (забирает ownership entry) | | `etcp_int_recv(queue, arg)` | **Внутренняя:** диспетчер из очереди normalizer'а, вызывает bound-коллбэк по cmd | | `etcp_conn_set_ready_cbk(conn, fn, arg)` | Установить одиночный коллбэк готовности (заменяет существующие) | | `etcp_conn_set_up_cbk(conn, fn, arg)` | Установить коллбэк поднятия соединения | | `etcp_conn_set_down_cbk(conn, fn, arg)` | Установить коллбэк падения соединения | | `etcp_conn_add_ready_cbk/remove_ready_cbk` | Добавить/убрать из цепочки ready-коллбэков | | `etcp_conn_add_up_cbk/remove_up_cbk` | Аналогично для up | | `etcp_conn_add_down_cbk/remove_down_cbk` | Аналогично для down | | `etcp_set_new_conn_cbk(inst, fn, arg)` | Установить коллбэк на входящее соединение | | `etcp_add_new_conn_cbk/remove_new_conn_cbk` | Добавить/убрать из цепочки new_conn | | `etcp_connect(inst, node, cb, arg, flags)` | Фоновое подключение к узлу | ### Командные ID (сырые, первый байт кодограммы) | Константа | Значение | Назначение | |-----------|----------|-----------| | `ETCP_ID_DATA` | 0x00 | Данные для передачи адресату | | `ETCP_ID_SVC_ROUTE` | 0x03 | Транспорт роутера (etcp_router) |