From 7737391ded1e61b1295734bbeb4be76410664b1a Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 24 Oct 2026 14:22:16 +0200 Subject: [PATCH] Document absolute ACK scheduling and cross-path precedence --- doc/etcp_multipath_plan.txt | 21 +++++++++++++++++++++ doc/etcp_protocol.txt | 19 +++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/doc/etcp_multipath_plan.txt b/doc/etcp_multipath_plan.txt index 367fdd3a..6f4d60d0 100644 --- a/doc/etcp_multipath_plan.txt +++ b/doc/etcp_multipath_plan.txt @@ -3,6 +3,27 @@ ETCP: независимая обратная связь каналов и до Статус +24.10.2026: исправлены абсолютные сроки ACK и конкуренция ACK/DATA разных путей. +Обычный ACK-only обслуживается от received_at_us головы своего пути + 2 мс; +piggyback готового DATA и срочный ответ остаются немедленными. Среди готовых ACK +выбирается самый старый срок; DATA другого пути уступает ему, DATA того же пути +забирает его piggyback. Ограниченная измерительная серия заканчивается до смены пути. +Один прежний таймер пересчитывается после piggyback/частичной отправки; новый RX +не отодвигает старые записи после callback таймера. Логический till имеет собственный +абсолютный срок вместо отдельного boolean pending. При OOM таймера используется +существующий флаг срочного ACK, исходные received_at_us не меняются. +Новых очередей/таймеров нет; wire-формат, RTO, min_rtt и модель BBR сохранены. + +Две регрессии до фикса воспроизводят ACK в возрасте 0 мкс и обход готового ACK +другого пути исходящим DATA: /tmp/etcp-ack-deadline-before.log, +/tmp/etcp-ack-due-priority-before.log. Новые проверки покрывают границы 1999/2000 мкс, +piggyback разных путей, смену головы, early timer callback, RX между timer/sender, +частичный ACK-кадр, срочный ответ, OOM, sender failure с close, reset и DOWN/UP/удаление. +Диагностика расширена до 106 полей: ранние записи внутри готовой пачки допустимы; +early_ordinary_ack_packets отдельно проверяет отправку всего пакета раньше срока. + +Предыдущий этап: диагностика до исправления ACK. + 24.10.2026: добавлена буферизованная диагностика multipath с шагом 100 мс. Интервал задаётся UTUN_MULTIPATH_DIAG_MS=10..1000. Новых таймеров нет: срез снимается существующим тестовым циклом, фактический dt_us записывается в каждой строке. diff --git a/doc/etcp_protocol.txt b/doc/etcp_protocol.txt index 7c061f14..b05302fd 100644 --- a/doc/etcp_protocol.txt +++ b/doc/etcp_protocol.txt @@ -26,8 +26,9 @@ HELLO/CHALLENGE/CONFIRM и keepalive передаются своим незав При наличии незастрявшего initialized+UP пути застрявшие исключены из повторов, даже если альтернатива занята. Если застряли все, доступны все UP-пути. Прежний путь разрешён лишь при отсутствии других допустимых; иначе ждём альтернативу. DOWN последней альтернативы пробуждает отправителя. - 3. Если DATA не помещается, он остаётся в очереди; для накопленных ACK выбирается - тот же линк, который принял соответствующий DATA, без ограничения DATA-cwnd/pacing. + 3. Наступивший по сроку или срочный ACK обслуживает тот же линк, который принял DATA, + без ограничения DATA-cwnd/pacing. Готовый DATA другого линка уступает этому ACK; + DATA того же линка забирает ACK piggyback. Если DATA не помещается, он остаётся в очереди. Кумулятивный till можно отправить по любому рабочему пути. ACK-only не увеличивает нагрузку DATA-shaper; физическая очередь канала остаётся общей, её накопление ограничивают DATA-cwnd/pacing BBR. 4. Выделить ETCP_DGRAM до удаления DATA из очереди и изменения счётчиков. @@ -61,6 +62,20 @@ HELLO/CHALLENGE/CONFIRM и keepalive передаются своим незав Если логический seq ещё не доставлен и других активных копий нет, он возвращается в input_send_q. Уже доставленный seq не возвращается, даже если его физическая копия истекла позже. +Обычный ACK-only ждёт received_at_us старейшей записи своего пути + 2000мкс. +Piggyback на готовом DATA передаёт ACK сразу. Готовый ACK может включать более свежие записи: +срок проверяется по голове пакета, а не отдельно для каждой записи внутри него. +Среди готовых обычных ACK выбирается самый старый срок; срочный ответ на ACK_REQUEST имеет приоритет. +Короткая ограниченная измерительная burst-серия завершается до перехода к ACK другого пути. +Продвижение логической границы также задаёт срок 2мс от первого неподтверждённого продвижения; +следующие DATA его не отодвигают. Любой принятый пакет с актуальным till снимает этот запрос. +Один ack_resp_timer соединения обслуживает минимум сроков очередей рабочих путей и логической границы. +После piggyback/частичной отправки срок пересчитывается по оставшимся головам. Новый RX между +timer и отложенным sender не задерживает старые ACK: готовность проверяется по абсолютному времени. +При DOWN очередь пути не создаёт таймер; после UP её старый наступивший срок действует сразу. +OOM ACK-таймера логируется и включает существующий срочный ответ, сохраняя received_at_us для RTT. +Reset/close отменяют таймер и очищают сроки; DATA/RTO/BBR и wire-формат этим механизмом не меняются. + inflight - две очереди (ll_queue): - input_send_q: список пакетов ожидающих отправку - input_wait_ack: список неподтвержденных пакетов ожидающих ack