diff --git a/doc/etcp_multipath_plan.txt b/doc/etcp_multipath_plan.txt index 37f02ea0..56b1a151 100644 --- a/doc/etcp_multipath_plan.txt +++ b/doc/etcp_multipath_plan.txt @@ -3,19 +3,49 @@ ETCP: независимая обратная связь каналов и до Статус -Бюджет очереди BBR уже реализован в fix/etcp-multipath-recovery: 20мс в PROBE_BW, -все резервы входят в предел max(4*MSS, BDP + BW*20мс). Это мягкая цель модели; -STARTUP/DRAIN, сериализация и обратный трафик не дают гарантии физической очереди <=20мс. -В штатном тесте equal получено 14.464/16Мбит/с, bandwidth — 9.060/10Мбит/с; -очередь медленного канала в bandwidth сократилась примерно с 47 до 21мс. -Изменения протокола и учёта попыток ниже ещё не реализованы. -По уточнению пользователя расчётный RTO ограничен снизу 10мс, сверху 1с. -Текущая общая формула 2*(RTT+jitter) сохранена; нижняя граница уже исправлена. -test_etcp_windows: 17 сценариев PASS, включая семь проверок RTO на управляемых -и обычных часах (нижняя граница, RTT20/200мс, jitter, верхняя граница). -Логи: /tmp/etcp-rto-windows.log, /tmp/etcp-rto-windows-real.log. +В fix/etcp-multipath-recovery реализованы начальный pacing, точные DATA B/s, +пересчёт pacing-долга, ограниченный кредит 1мс для округления таймеров и выход +STARTUP в DRAIN после целого раунда RTT выше min_rtt+бюджет очереди. +Предел PROBE_BW — max(4*MSS, BDP + BW*20мс), включая ACK/PROBE_UP резервы. +Это мягкая цель модели, не гарантия физической очереди <=20мс во всех состояниях. -Что подтверждено кодом и диагностикой +Логический seq/payload отделён от физических ETCP_TX_ATTEMPT. Новый DATA содержит +seq+attempt_id; ACK своего пути содержит seq+attempt_id+receiver_delay_us. +Till подтверждает только логическую доставку. Собственные очереди попыток, +ACK, RTT/jitter и RTO принадлежат линку. RTO=clamp(2*(RTT+jitter),10мс,1с); +до DATA ACK используется KA RTT того же пути, без него начальное значение 1с. +Retry обходит каналы относительно last_link фрагмента; курсор фиксируется только +после принятия send транспортом. Поздние/чужие ACK не меняют чужой flight/BBR. +ACK создаётся после сохранения DATA в recv_q. Потерянный till запрашивается, +когда окно sequence заполнено; ответ идёт по запросившему пути, без DATA. +Физические попытки ограничены 16384 на линк/32768 на соединение, ACK — 16384 на линк. + +Точечные проверки: BBR 20/20, windows 26 сценариев PASS. Семь тестов +BBR/windows/session/transport/STCP traffic/NCD/stream_tx_stats проходят ASAN/UBSan +с detect_leaks=1, без отчётов об ошибках/утечках. +Логи: /tmp/etcp-bounds-windows.log, /tmp/etcp-delay-bbr.log, +/tmp/etcp-attempts-asan-test_*.log. + +Вся штатная multipath-матрица пока FAIL: 20 нарушений порогов. +RTT20/200мс: 13.552/16Мбит/с, длинный канал wire7.173/8Мбит/с; +после исправления STARTUP пики очереди около 23мс вместо 220мс. +Есть недобор bidirectional (обратное направление 7.116/10Мбит/с). +Обычный DROP/HOLD с RTT20мс: пауза около 61–62мс. slow-drop с RTT200мс: +пауза 401мс; два застрявших канала — 676мс; под нагрузкой — 229–243мс. +Ни пороги, ни прогрев тестов не ослаблены. Ранние копии/здоровье каналов и +ограничение нижележащей STCP-очереди ещё не реализованы. +Полный лог: /tmp/etcp-attempts-matrix.log. + +Дополнительно подтверждена потеря уже ACKed DATA при OOM в pn_unpacker_cb: +ll_alloc_lldgram не выделяется, исходный фрагмент освобождается, till=1, +ACK_queued=1, messages=0, удерживаемых данных нет. Повтор отбрасывается как дубликат. +Это существующий дефект следующей ступени приёма, не устранённый переносом ACK +после recv_q. Воспроизведение: /tmp/etcp-unpack-admission-review.c/.mk/.log +(exit=1, учёт памяти при teardown проверен). Следующее исправление должно +сохранять недообработанный фрагмент и cursor при OOM до повторной сборки, +а reset/close — снимать retry и освобождать его ровно один раз. + +Исходные нарушения до реализации (пункты 1–5 и вход recv_q из пункта 8 исправлены) 1. ACK выбирает канал независимо от DATA: select_link(conn, 0), inflight/RR. Одна общая ack_q смешивает подтверждения DATA разных каналов. Поэтому интервал @@ -63,6 +93,8 @@ test_etcp_windows: 17 сценариев PASS, включая семь пров только после сохранения фрагмента либо проверки, что он уже сохранён/доставлен. Инъекция отказа data_pool подтвердила: ACK_queued=1, DATA_stored=0, delivered_till=0. Это дефект надёжности, а не только неточность статистики BBR. + После исправления этой ступени дополнительно проверен unpacker: его OOM + также не должен уничтожать уже подтверждённые фрагменты (см. текущий статус). Экспериментальная проверка причин @@ -103,7 +135,7 @@ test_etcp_windows: 17 сценариев PASS, включая семь пров её удаление из протокола сломало бы ограничение окна приёмника. Прототип не проверяет новый wire-формат, владение попытками или отказоустойчивость. -Предлагаемый контракт +Контракт (базовый учёт реализован; ранний повтор и STCP-очередь остаются открытыми) Разделить логическую доставку фрагмента и физическую попытку передачи. @@ -208,16 +240,17 @@ uint8: хранить факт состоявшейся отправки отд модель на канал и независимость отказов. Общая логическая граница при этом может распространяться любым рабочим каналом. -Последовательность реализации и критерии завершения +Последовательность реализации и критерии завершения (до завершения открытых проверок задача не закрыта) -1. Начальный pacing как отдельное исправление без смены wire-формата. +1. Начальный pacing — реализован и проверен отдельно от смены wire-формата. Инициализировать от настоящего начального окна и первого валидного RTT. Сохранить точные B/s до shaper, отделить unlimited от округления. При смене ставки пересчитать оставшийся pacing-долг и таймер, не создавая новый burst. Проверки: короткий служебный DATA -> пауза -> bulk, RTT20/200мс, скорость ниже 1Kbit/s, увеличение/уменьшение ставки с активным таймером, полный STARTUP. -2. Цельный переход на логические фрагменты и идентифицируемые попытки. +2. Цельный переход на логические фрагменты и идентифицируемые попытки — реализован; + функциональные и sanitizer-проверки проходят, вся матрица скорости пока нет. Добавить индекс attempt_id в очереди попыток каждого линка и отдельную ACK-очередь. Общий индекс попыток не нужен: ACK ищется на принявшем его линке. Разделить обработчики logical till и ACK попытки; одновременно обновить DATA, @@ -245,6 +278,9 @@ uint8: хранить факт состоявшейся отправки отд без смены алгоритма выбора DATA, поэтому дополнительная эвристика пока лишняя. 3. Быстрое восстановление и здоровье каналов. + До изменения этой политики исправить удержание ACKed DATA при OOM unpacker: + ограниченный retry сборки, сохранённый fragment/cursor, reentrant reset/close, + OOM на первой и последующей кодограмме одного фрагмента, повтор DATA во время OOM. Собственный RTT/RTO и ротация уже обязательны в этапе 2. Проверить срок первой повторной отправки, отдельно от объявления потери/снятия окна старой попытки. При потере ограничить новые DATA на проблемном пути, пробовать восстановление diff --git a/doc/tasks.md b/doc/tasks.md index 92fb36f0..13899446 100644 --- a/doc/tasks.md +++ b/doc/tasks.md @@ -4,60 +4,22 @@ ## Текущие задачи -[ ] **ETCP: полезная утилизация нескольких каналов и доставка при зависании части линков** — тестовый стенд добавлен 22.10.2026: - test_dummynet_channels калибрует BWlim 2/8 Мбит/с на смешанных размерах, delay, ограниченный HOLD, - выпуск с BWlim, DROP ожидающих пакетов и уничтожение с активными delay/shaper. Включён в обычный Linux-набор. - dummynet хранит все delay callbacks, сериализация не теряет доли миллисекунды, добавлены режимы RUN/DROP/HOLD. - test_etcp_multipath использует настоящие instance/NCD/ETCP/BBR, независимые UDP-прокси и пассивное наблюдение пакетов. - Полный запуск: make -C tests check-multipath; один сценарий: tests/test_etcp_multipath <имя>. - Профили: equal, bandwidth, rtt, fast-distant, slow-distant, three, bidirectional; - отказы: drop, hold, drop-forward, drop-reverse, short-hold, slow-drop, two-stuck, load-drop, load-hold. - UTUN_MULTIPATH_CSV=/tmp/multipath.csv сохраняет очереди, RTT, pacing, inflight/cwnd, повторы и доставку по фазам. - Пороги: wire >=90% BWlim каждого канала, уникальные DATA >=80%, полезная скорость >=85% суммы BWlim - и >=90% суммы отдельных измерений. Выдача старой очереди сборки не может завысить полезную скорость. - При отказе: доставка до восстановления пути, пауза <=100мс и latency <=100мс при ограниченном источнике; - при насыщении оставшийся набор должен давать >=85% своей ёмкости после переходного периода. - Начальные прогоны выявили нарушения: RTT 20/20мс, DROP одного пути — пауза 204мс, latency 344мс; - при разных RTT/BWlim не выполняются требования утилизации, в том числе из-за повторов и переполнения очередей. - Базовые исправления BBR/pacing внесены 23.10.2026 в fix/etcp-multipath-recovery (см. завершённую подзадачу ниже). - Выбор пути повторов, общий RTO и блокировка сборки ещё не исправлены. - Прогон девяти отказов до бюджета очереди: drop-reverse/short-hold PASS, остальные семь FAIL по целевым требованиям; - повтор на обычных часах slow-drop: пауза 450мс, latency 1267мс. Trace показывает повторную отправку в зависший путь. - Связанные регрессии 5/5 PASS. ASAN/UBSan + detect_leaks=1: calibration и short-hold PASS; - slow-drop сохраняет функциональный FAIL, ошибок санитайзеров/утечек во всех трёх запусках нет. - Логи: /tmp/etcp-multipath-complete.log, /tmp/etcp-multipath-final-*.log/.csv, - /tmp/etcp-multipath-fault-results.log, /tmp/etcp-channels-regression-results.log, - /tmp/etcp-channels-asan-final-results.log, /tmp/test_*-asan-final.log. - После исправлений добавить смену профилей на ходу, повторяющиеся отказы и смешанный UDP/STCP со stalled TCP write. - Полная матрица дольше 90s общего runner и запускается отдельной целью; нарушения завершают её с ошибкой. - Окно PROBE_RTT и DATA MSS согласованы 23.10.2026 (см. завершённую подзадачу ниже). - Пользователь выбрал бюджет задержки; реализация и проверки завершены (см. подзадачу ниже). - После бюджета equal PASS (14.464 из 16 Мбит/с), bandwidth PASS (9.060 из 10), очередь медленного пути - 25мс отдельно / 20.7мс в агрегате. RTT 20/200мс остаётся FAIL: 7.1–7.7 из 16 Мбит/с, быстрый путь недогружен. - Пороги очереди и утилизации не ослаблены. Логи: /tmp/etcp-queue-limited-{equal,bandwidth,rtt}.log/.csv. - Диагностика подтвердила несовместимость интервалов ACK и отдельного RTT last_link, обновление чужого BBR - через общий till и неоднозначность ACK повторов. Найден отдельный дефект начального pacing от окна/RTT. - Подробные причины, проверенный контракт попыток, этапы и критерии: [doc/etcp_multipath_plan.txt](etcp_multipath_plan.txt). - Диагностический прототип без правок протокола: после разгона контроль 8.055/16Мбит/с; свой путь ACK, - отдельный till и RTT попытки без фильтрации неоднозначной скорости дают лишь 8.831–8.945/16. - После фильтрации неоднозначных повторов — 14.127 и 14.559/16Мбит/с, steady-проверки PASS. - Разные BWlim 2+8 и 8+2Мбит/с при RTT20/200мс: 8.735 и 8.979/10Мбит/с, steady PASS. - Контроль прототипа по штатному rtt с прогревом 3с: 14.312/16Мбит/с, очередь 23.4/24.9мс, PASS. - Это проверка причин, а не реализация новой архитектуры: нужны attempt_id, владение очередями и lifecycle. - Начать с начального pacing, затем согласованно разделить логический seq и физические попытки/ACK, - после этого исправлять сроки/здоровье линка и DROP/HOLD. Выбор первоначального DATA-пути пока не менять: - прототип уже утилизирует пути без неё. Штатные проверки разгона и отказов остаются обязательными. - Дополнительный архитектурный разбор: ротации повтора относительно пути пакета сейчас нет. - /tmp/etcp-retry-review.log: оба канала UP и готовы, seq1 A->A, seq2 B->B, retry_rotation=2. - В контракт добавлены A->B->C->A с пропуском занятых и возвратом на прежний только без готовых альтернатив; - burst не навязывает путь DATA. Ротация, очереди попыток и собственные RTO входят в единый этап перехода. - ACK сохраняет seq вместе с attempt_id: поздний ACK освобождает логические данные и после удаления попытки, - не меняя её уже снятое окно/BBR. Отдельная история потерянных попыток не требуется. - Найдено подтверждение DATA до успешного сохранения в recv_q: включить исправление admission/ACK и OOM-тесты. - Воспроизведение с отказом data_pool: ACK_queued=1, DATA_stored=0, delivered_till=0; false_ack=1. - Также нужны передача till без DATA по другому пути и запрос потерянной границы при полном окне. - Ранний повтор не равен loss: его старая копия остаётся в учёте до ACK/потери/close. - Одна ротация не обеспечивает паузу <=100мс, если срок первой повторной отправки больше 100мс. +[ ] **ETCP: полезная утилизация нескольких каналов и доставка при зависании части линков** — работа в fix/etcp-multipath-recovery. + Реализованы начальный pacing от 4*MSS/RTT, точные DATA B/s и ограниченный кредит shaper, + разделение логического seq/payload и физических attempt_id, ACK/RTT/RTO каждого пути, + ротация повторов A→B→C→A при UP-каналах, rollback отказавшего send и запрос потерянного till. + RTO=clamp(2*(RTT+jitter),10мс,1с). Пределы памяти: попытки 16384/линк, 32768/соединение, ACK 16384/линк. + STARTUP завершается после целого раунда устойчивой очереди выше бюджета, без искусственного изменения BW. + BBR20/20, windows26 сценариев PASS; семь транспортных тестов ASAN/UBSan с detect_leaks=1 PASS. + Полная штатная multipath-матрица: FAIL, 20 нарушений. Есть недобор RTT20/200мс и bidirectional; + slow-drop даёт паузу401мс, два зависших пути676мс, DROP/HOLD под нагрузкой229–243мс. + Ранние копии до RTO, здоровье/пробы каналов и STCP backpressure пока не реализованы; пороги тестов сохранены. + Приоритетный новый результат проверки: pn_unpacker_cb при OOM уничтожает уже ACKed фрагмент, + продвигает till, повтор отбрасывает как дубликат. Подтверждено fault injection: ACK=1, till=1, messages=0. + Нужны удержание fragment/cursor и повтор сборки с корректным reset/close, затем возврат к отказоустойчивости. + План и подробные результаты: [doc/etcp_multipath_plan.txt](etcp_multipath_plan.txt). + Логи: /tmp/etcp-attempts-matrix.log, /tmp/etcp-attempts-asan-test_*.log, + /tmp/etcp-unpack-admission-review.log; диагностический стенд OOM оставлен в /tmp. [+] **ETCP/BBR: бюджет очереди в установившемся режиме** — реализовано 23.10.2026 по выбору пользователя: В PROBE_BW окно ограничено max(4*MSS, BDP + BW*20мс), с насыщением арифметики и учётом ACK/PROBE_UP резервов