diff --git a/doc/etcp_multipath_plan.txt b/doc/etcp_multipath_plan.txt index 7010a575..48d1d8e1 100644 --- a/doc/etcp_multipath_plan.txt +++ b/doc/etcp_multipath_plan.txt @@ -3,6 +3,64 @@ ETCP: независимая обратная связь каналов и до Статус +24.10.2026: добавлена буферизованная диагностика multipath с шагом 100 мс. +Интервал задаётся UTUN_MULTIPATH_DIAG_MS=10..1000. Новых таймеров нет: срез снимается +существующим тестовым циклом, фактический dt_us записывается в каждой строке. +Конец фазы добавляет короткий срез, поэтому скорость считают по dt_us, а не всегда по 100 мс. +Данные сохраняются в память и выводятся в CSV/лог после drain каждого стенда; +при провале CHECK уже собранные срезы выводятся перед exit. Переполнение буфера — ошибка. +Этот этап меняет только диагностику теста, алгоритмы ETCP/BBR сохранены. + +Запуск из корня репозитория: + UTUN_MULTIPATH_DIAG=/tmp/etcp-duplex.csv ./tests/test_etcp_multipath bidirectional > /tmp/etcp-duplex.log 2>&1 + python3 tools/etcp_diag_report.py /tmp/etcp-duplex.csv /tmp/etcp-duplex.html +Для подробного отказа: UTUN_MULTIPATH_DIAG_MS=10 и профиль two-stuck. +Уровень категории debug явно включается самим тестом; без UTUN_MULTIPATH_DIAG новый вывод выключен. + +104 поля связывают очередь приложения, partial/pending/ожидания normalizer, очередь +фрагментов, send_q (новые/повторы), wait_ack и recv_q с физическим flight/cwnd пути. +Видны suspended/resume/deferred callbacks, состояние sender, номера seq/till, +общий бюджет DATA, очередь ACK и возраст её головы, возраст старейшей попытки, +RTT/jitter/RTO, BW, режим/фаза BBR, pacing, долг и срок готовности pacer, флаг застревания. +Отдельно записываются DATA TX/первые DATA RX, ACK-only/ACK в DATA, задержки ACK, +обычные ACK-only раньше 2 мс, samples BBR, проверки блокировки окном и pacer, +наблюдаемые min/max flight/cwnd/долга и пики send_q/ACK внутри интервала. + +Очереди соединения повторяются в строках его линков — их нельзя суммировать между путями. +У pacer положительный долг допускается строго меньше 1 мс; отрицательное значение — +сырой кредит, который при отправке ограничивается 1 мс. Блокировки выбора — число +проверок, а не длительность ожидания. Пики внутри среза — наблюдения на TX/RX/ACK/выборе, +не непрерывная запись каждого изменения. channel_pending включает propagation delay, +сериализацию и HOLD; channel_peak/delay_max накапливаются с последнего reset_stats. +Wire-байты — UDP без IP/UDP headers; ACK-only включает timestamp, crypto и SESSION. +Piggyback учитывает только положительную ACK-секцию, без повторного начисления crypto. + +HTML автономен, без библиотек/сети: выбор стенда/направления/канала/фазы/интервала, +восемь графиков и все поля выбранного курсором среза. PROBE_RTT выделен фоном. +Перед построением проверяются схема CSV, учёт очередей, счётчиков и непрерывность интервалов. +Проверены 598 срезов дуплекса (100 мс), 5208 срезов two-stuck (10 мс) и 5196 срезов +ASAN/UBSan two-stuck с detect_leaks=1 без ошибок/утечек. Намеренный CHECK сохранил +72 среза до выхода. Неверные интервалы 6/6 и повреждённые CSV 3/3 отклонены. +Общий check.sh: 184/184, proxy 9/9, burst/load PASS, 163 с; длинный дуплекс отдельно +по-прежнему FAIL по скорости. После уточнения учёта timestamp повторены целевые +дуплекс/two-stuck/ASAN-проверки диагностики. Файл full-check отражает общий прогон до этого уточнения. + +На одиночном дуплексном пути 8 Мбит/с итоговые срезы показывают расход ACK 0.313/0.383 Мбит/с. +Обычные ACK-only раньше 2 мс: 1542/1584 и 1956/2056 записей; среднее ожидание 219/375 мкс. +Обнаружен обход ACK_DELAY посторонним wake sender. Диагностическое отключение PROBE_RTT +повышает скорость одиночного 8 Мбит/с пути примерно с 6.8 до 7.1 Мбит/с, но не закрывает +весь дуплекс. Прототип ожидания общего таймера уменьшает полосу ACK примерно до 0.21 Мбит/с, +однако также не закрывает все пороги. Эти прототипы остаются в /tmp, в протокол не внесены. +Следующий разбор: абсолютные deadlines ACK и переустановка единственного таймера после +piggyback/частичной отправки. Проверка одного наличия timer недостаточна: новый RX между +срабатыванием timer и отложенным sender может повторно задержать уже готовые старые ACK. + +Артефакты: /tmp/etcp-duplex-diag-{100ms,10ms,asan,abort}.csv/.log, +/tmp/etcp-duplex-diag-view.html, /tmp/etcp-fault-diag-view.html, +/tmp/etcp-duplex-diag-full-check.log. Полный пакетный трейс и контроль PROBE_RTT: +/tmp/etcp-duplex-next-{trace,no-probe-control,ack-control}.log, +/tmp/etcp-duplex-next-analysis.json; observer — /tmp/etcp-probe-review.c/.mk. + 24.10.2026: реализованы сканирование send_q, история путей пакета и быстрое застревание. Остались прежние input_send_q/input_wait_ack: первый готовый повтор имеет приоритет, иначе выбирается первый готовый новый DATA. Заблокированная запись остаётся на месте diff --git a/doc/tasks.md b/doc/tasks.md index 03cfb467..75455226 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -25,6 +25,15 @@ Windows/FreeBSD runtime не проверялся. [ ] **ETCP: полезная утилизация нескольких каналов и доставка при зависании части линков** — общая задача открыта. + Продолжение 24.10.2026: диагностика срезов 100 мс (настройка 10..1000 мс), 104 поля; CSV и лог буферизуются до drain. + Видны очереди, callbacks/deferred waiter, DATA/ACK, flight/cwnd, BBR/RTT/RTO, долг/готовность pacer и канал эмулятора. + tools/etcp_diag_report.py проверяет CSV и строит автономные интерактивные графики с исходными срезами. + Дуплекс: 598 срезов; two-stuck/ASAN: 5208/5196 срезов, без ошибок sanitizer/утечек; CHECK сохраняет накопленный лог. + Общий check.sh 184/184, proxy 9/9, burst/load PASS, 163 с; после уточнения учёта ACK+timestamp повторены целевые проверки. + На одиночном 8 Мбит/с пути ACK занимают 0.313/0.383 Мбит/с, среднее ожидание ACK-only 219/375 мкс вместо окна 2 мс. + Дедлайн обходит посторонний wake sender. Дальше разбирать абсолютные deadlines ACK; простого !timer недостаточно. + Алгоритмы протокола на этом этапе не менялись; полный дуплекс всё ещё не проходит скоростные пороги. + Логи/CSV: /tmp/etcp-duplex-diag-*; просмотр: /tmp/etcp-duplex-diag-view.html; детали — doc/etcp_multipath_plan.txt. 24.10.2026: реализованы сканирование send_q с приоритетом готовых повторов и ограниченная подгрузка новых DATA. Заблокированный пакет пропускается. История путей пакета (32 байта) исключает новый обход до перебора допустимых; история/RR фиксируются после принятого send, удаление линка очищает слот до callbacks/повторной выдачи ID.