13 KiB
etcpmon
1. Назначение
Windows GUI монитор для ETCP соединений uTun. Подключается по обычному IPv4 TCP к control_server внутри uTun и отображает метрики соединений, линков, TUN, роутера и уровней отладки. Все сетевые вызовы и callbacks выполняются в GUI-потоке: WM_TIMER установлен на 10 мс, автоматический запрос метрик — раз в 100 мс при отсутствии предыдущего запроса в pending. Частота полученных сэмплов зависит от ответов сервера.
Connections и локальные сокеты опрашиваются раз в секунду, даже при пустом списке соединений.
Выбор сохраняется по ID узла при изменении порядка и имён. При удалении выбранного соединения
выбирается первое доступное; пустой список или отключение очищает метрики и график.
Одновременно ожидается не более одного ответа на автоматический запрос метрик. Таймаут ответа
на запрос с seq_id — 5 секунд; причина отключения записывается в etcpmon.log.
2. Как пользоваться
Типовой сценарий
-
В конфиге uTun настроить
[control](безallowсервер отклоняет все подключения):[control] ip=127.0.0.1 port=9090 allow=127.0.0.1/32 -
Запустить uTun → он поднимает TCP control server на указанном порту
-
Запустить
etcpmon.exe(Windows, MinGW/MSYS2 сборка) -
Ввести числовой IPv4 и порт сервера, нажать Connect. При создании окна уже начинается попытка подключения к
192.168.40.1:9091; для смены адреса сначала нажать Disconnect. -
Первое доступное соединение выбирается автоматически; другое можно выбрать в Connections.
Канал управления не шифруется и не проверяет ключи ETCP; allow фильтрует только IPv4 источника.
Для удалённого управления требуется доверенный защищённый канал. DNS-имена и IPv6 клиент не принимает.
Что отображает
ETCP Connection:
- RTT last / avg10 и jitter (wire: 0.1 мс, GUI: мс), bytes sent, retransmissions, ACKs, unacked bytes, optimal inflight, links count
- Поле RTT Avg100 в окне есть, но соответствующего значения в протоколе нет: оно не заполняется
- RX/TX дубликаты, таймеры (retrans/ack_resp), WaitAck состояние (suspended/cb/timer)
- ID Sequence: next_tx_id, last_rx_id, last_delivered_id, rx_ack_till
- Счётчики ошибок: reinit, reset, pkt_format_errors
TUN / Routing:
- Bytes/packets read/written, ошибки чтения/записи
- Routed/dropped пакеты, TUN очереди (InQ/OutQ packets/bytes)
- Таблица маршрутов: total, local, learned, BGP senders, BGP nodes
Links:
- Статус (UP/DOWN), encrypt/decrypt/send/recv ошибки
- Total encrypted/decrypted bytes, bandwidth (Kbps), NAT changes
- RTT last, поле с подписью avg10 (фактически BBR minRTT, 0 без BBR), transmit time, keepalive counters (sent/recv)
- Inflight bytes/packets/limit, таймеры (init/keepalive/shaper)
BBR per link:
- mode (STARTUP/DRAIN/PROBE_BW/PROBE_RTT), cycle idx, full_bw/loss_in_round флаги
- pacing_rate (bytes/sec), min_rtt (us), bw_hi/bw_lo (bytes/sec), inflight_hi/lo, pacing_gain
Router Congestion (агрегированные):
- total_conns, total_inflight, total_send_q, total_recv_q (счётчики записей очередей, не байтов)
- pkts sent/recv, send err, ACK sent/recv, dup_dropped, oob_dropped, stale_ack, sign_fail
- RTT max/avg, jitter max, minRTT min
Графики BBR (scrolling canvas, 860 сэмплов, 1px=1sample):
- Inflight Bytes, Cwnd (inflight_lim), minRTT, bwHi, Pacing Rate, bwLo, inflight Hi, BBR Mode
- История первого линка, до 860 сэмплов; если галочек нет, отображаются первые четыре канала
- Вертикальная линия курсора с показом значений в блоках под графиком
Очереди (Queues & Errors):
- InQ, InSend, WaitAck, AckQ, RecvQ, OutQ — bytes/packets
- Нормализатор: input/output pkts/bytes, alloc/logic errors, frag_size, data_ptr/size, cumulative totals
- ACK Debug: hit_inf, hit_sndq, miss, link_wait
- Системные ресурсы: active_timeouts, busy_memory_blocks
Debug Levels (правая колонка):
- Глобальный уровень: NONE/ERROR/WARN/INFO/DEBUG/TRACE (радиокнопки)
- Per-category уровни с метками категорий
- Radio-кнопки отправляют CMD_SET_DEBUG_CONFIG на сервер при клике
Action:
- Текстовое поле + кнопка Send отправляют CMD_ACTION (до 31 байта текста + NUL)
- Сервер распознаёт префиксы
nodes(текстовый дамп узлов) иnat(перезапуск NAT/STUN-проверок) nodesвозвращает текст в отдельное окно Consolas,nat— подтверждение запуска проверки- Имена сравниваются целиком. Неизвестная команда или недоступная служба возвращают
RSP_ERRORс исходным seq; GUI показывает ошибку и сохраняет TCP-соединение
Сборка
cd tools\etcpmon
build.bat # через MSYS2 UCRT64 (рекомендуется)
bash build.sh # Unix/MinGW
make # MinGW Makefile
make check # WinAPI/Winsock регрессии списка, выбора и переподключения
На Linux с MinGW и Wine из каталога tools/etcpmon:
CC=x86_64-w64-mingw32-gcc bash build.sh
make CC=x86_64-w64-mingw32-gcc TEST_RUNNER=wine check
wine etcpmon.exe
Серверная часть (control_server) встроена в utun, собирается стандартным ./configure && make.
Горячие клавиши
- Tab в поле Server/Port — переключение между полями
- Enter в поле Server/Port — Connect, если отключён; Escape — Disconnect
- Enter в поле Action — отправка команды
3. API / Структура
Компоненты
| Файл | Назначение |
|---|---|
etcpmon_main.c |
WinMain: инициализация GUI, создание окна, message loop |
etcpmon_client.h/c |
TCP клиент (Winsock2): connect, send/recv, парсинг протокола, history, pending requests с коллбэками |
etcpmon_gui.h/c |
WinAPI GUI: заданный размер окна 1250×1400, контролы, таймер, callbacks, тултипы |
etcpmon_graph.h/c |
Real-time график: 8 каналов, off-screen буфер, пересчёт min/max, курсор, обновление channel values |
etcpmon_protocol.h |
Бинарный протокол, общие структуры, shared между клиентом и сервером |
Протокол (бинарный, TCP)
Формат: [size:2][type:1][seq_id:1][payload...]
size включает 4-байтовый заголовок, диапазон 4..32768. Все структуры packed(1), целые передаются
в порядке байтов хоста. Константа VERSION=3 не передаётся по сети: клиенту и серверу нужны одинаковые
форматы структур и порядок байтов. TCP-чтение может содержать часть кадра или несколько кадров.
seq=0 не создаёт ожидания в клиенте; seq=1..255 сопоставляет ответ с pending по одному номеру.
SELECT_CONN, SET_DEBUG_CONFIG и DISCONNECT не подтверждаются. GUI отправляет списки с seq=0,
а GET_DEBUG_CONFIG, автоопрос метрик и Action — с ненулевым seq и таймаутом.
Клиент → Сервер:
0x01CMD_LIST_CONN — запрос списка соединений (без payload)0x02CMD_SELECT_CONN — выбор соединения:peer_node_id(uint64_t)0x03CMD_GET_METRICS — запрос метрик для выбранного соединения0x04CMD_DISCONNECT — отключение0x05CMD_LIST_SOCKETS — запрос списка локальных сокетов0x06CMD_ACTION — текстовая команда (32 байта)0x07CMD_GET_DEBUG_CONFIG — запрос текущих debug levels0x08CMD_SET_DEBUG_CONFIG — установка debug levels:[global_level:1][cat_count:1][levels:N]0x09CMD_SUBSCRIBE_NODES — подписка на изменения узлов (topo)
Сервер → Клиент:
0x81RSP_CONN_LIST:count(1) + N × {peer_node_id(8) + name(32)}0x82RSP_METRICS:etcp_metrics + tun_metrics + router_metrics + N × link_metrics0x83RSP_SOCKET_LIST:count(1) + N × socket_info0x84RSP_DEBUG_CONFIG:global_level(1) + cat_count(1) + names_csv(NUL-term) + levels[N]0x85RSP_NODE_INFO — префикс01 04+topo_node_serialize()для UTUN с подсетями, seq=00x86RSP_NODE_INFO_END — конец списка узлов с seq запроса подписки0x88RSP_NODE_REMOVED — узел удалён:node_id(8)0x89RSP_ACTION_RESULT — результат команды:code(1) + text(NUL-term)0xFFRSP_ERROR:error_code(1) + message(NUL-term)
Подписку на узлы поддерживает сервер, но GUI etcpmon её не запрашивает и эти уведомления не отображает.
Очереди, таймауты и единицы
- Все команды клиента копируются в общий TX FIFO (до 64 КиБ/256 кадров). Short send и WSAEWOULDBLOCK сохраняют смещение для следующего прохода. Переполнение не принимает новую команду и возвращает ошибку.
- Pending регистрируется вместе с кадром, срок ответа 5 секунд начинается после его полной отправки.
Тип и payload ответа проверяются до снятия pending/callback;
RSP_ERRORзавершает любой запрос. - Connect и отсутствие прогресса TX также ограничены 5 секундами. Ответы на списки с seq=0 отдельно не отслеживаются; EOF/фатальная ошибка/таймаут закрывают соединение с диагностикой.
- Сервер держит один готовый кадр до 32 КиБ. Чтение и разбор запросов ждут его отправки через отменяемый deferred waiter. Для начального списка узлов хранятся ID, сериализация выполняется порционно.
- Live-изменения UTUN объединяются по ID (до 256); переполнение отключает подписчика с WARN. Серверный таймаут 30 секунд во время TX продлевается только положительным send, иначе — командами.
- История хранит байты, байты/с и minRTT в мс. При выводе используются B/KiB/MiB и B/s/KiB/s/MiB/s, включая строки BBR. Сравнение идёт с текстом самого контрола, поэтому очистка/reconnect не скрывают прежние значения.