Merge origin/master with encrypted attachment ownership fixes
Validation: ./build.sh --no-gui -j4 and make check -j4 passed; 186 tests, no failures.
This commit is contained in:
commit
bafda5ae3a
38 files changed
+2854
-984
No files matched your search
+192
-7
@@ -3,6 +3,188 @@ 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 отдельно проверяет отправку всего пакета раньше срока.
|
||||
|
||||
Проверка после исправления: windows 60 сценариев PASS с управляемыми и реальными
|
||||
часами; восемь профильных тестов ETCP/STCP ASAN/UBSan с detect_leaks=1 PASS без
|
||||
ошибок/утечек. Отдельный ASAN two-stuck с диагностикой 10 мс: 5202 проверенных среза,
|
||||
ранних ACK-пакетов нет, доставка/ресурсы PASS. Полный check.sh: 184/184, proxy 9/9,
|
||||
burst 1/1, load 8/8 PASS, 134217728 проверенных байт, 185 с со сборкой.
|
||||
|
||||
Три последовательных bidirectional с диагностикой: ранних обычных ACK-пакетов 0
|
||||
во всех трёх прогонах. На одиночном 8 Мбит/с пути полоса ACK 0.143..0.169 Мбит/с
|
||||
вместо 0.347/0.390 в предыдущем диагностическом прогоне. Агрегат: A->B
|
||||
8.667..8.804, B->A 8.695..8.796 из 10 Мбит/с. Сам агрегат проходит все свои пороги
|
||||
каждый раз; весь профиль остаётся FAIL из-за одиночных каналов, с 3/2/4 нарушениями.
|
||||
Средний возраст entries ACK-only на 8 Мбит/с может быть меньше 2 мс: внутри готового
|
||||
кадра передаются и новые entries. Это учитывается отдельно от ранней отправки кадра.
|
||||
|
||||
Полная штатная последовательная матрица после калибровки эмулятора: первые шесть
|
||||
скоростных профилей и все 9 профилей отказов PASS. Агрегированный goodput,
|
||||
Мбит/с: equal 14.416/16, bandwidth 9.032/10, rtt 14.516/16, fast-distant 8.857/10,
|
||||
slow-distant 8.978/10, three 11.122/12, bidirectional 8.750/8.768 из 10 на направление.
|
||||
Остаются два FAIL одиночного дуплекса: 1.609 вместо 1.700 Мбит/с (путь 2 Мбит/с)
|
||||
и 6.730 вместо 6.800 Мбит/с (обратное направление пути 8 Мбит/с).
|
||||
Two-stuck: gap 206.227 мс, latency 375.457 мс; load-drop/load-hold: gap 41.402/41.845 мс,
|
||||
steady goodput 7.229/7.466 из 8 Мбит/с. Max latency насыщенного источника
|
||||
180.693/89.239 мс записана; отдельным порогом она здесь не ограничена.
|
||||
Дальше отдельно разбирать недооценку полосы/PROBE_RTT одиночного дуплекса,
|
||||
STCP backpressure и проверки изменения RTT/BW и повторного отказа.
|
||||
|
||||
Логи: /tmp/etcp-ack-deadline-{windows,real-time,full-check}.log,
|
||||
/tmp/etcp-ack-deadline-asan-test_*.log, /tmp/etcp-ack-deadline-asan-two-stuck.log/.csv,
|
||||
/tmp/etcp-ack-deadline-matrix.log/.csv, /tmp/etcp-ack-deadline-duplex-<1..3>.log/.csv.
|
||||
Сводка ACK: /tmp/etcp-ack-deadline-summary.json; актуальный HTML с 106 полями:
|
||||
/tmp/etcp-ack-deadline-duplex.html. Проверка CSV и JS smoke графиков/фильтров PASS.
|
||||
|
||||
Предыдущий этап: диагностика до исправления ACK.
|
||||
|
||||
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 1/1, load 8/8 PASS,
|
||||
134217728 проверенных байт, 166 с. HTML прошёл JS smoke-проверку восьми графиков,
|
||||
104 полей, фильтров, диапазона, курсора, пустого диапазона и сброса.
|
||||
Длинный дуплекс отдельно по-прежнему FAIL по скорости: в последнем прогоне 5 нарушений,
|
||||
агрегат 8.513/8.337 из 10 Мбит/с. Это результат одного прогона, не доказательство эффекта диагностики на скорость.
|
||||
|
||||
На одиночном дуплексном пути 8 Мбит/с итоговые срезы показывают расход ACK 0.347/0.390 Мбит/с.
|
||||
Обычные ACK-only раньше 2 мс: 1774/1828 и 1961/2019 записей; среднее ожидание 230/271 мкс.
|
||||
Наблюдаемый пик очереди ACK — 4 записи, включая короткие пики до немедленной отправки.
|
||||
У side=1 path=1 mask=2 в 4.5..5.4 с есть 4 кодограммы приложения, фрагмент и до 8 DATA
|
||||
в send_q, а pacing составляет около 6.24..6.26 Мбит/с. В 5.5..5.7 с PROBE_RTT уменьшает
|
||||
окно примерно с 81.5 до 32.9 тыс. байт; после него pacing возвращается лишь к 6.27..6.35 Мбит/с.
|
||||
В этих срезах виден заданный моделью темп, а не отсутствие данных у sender.
|
||||
Обнаружен обход 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.
|
||||
Сводка итоговых срезов: /tmp/etcp-duplex-diag-summary.json.
|
||||
|
||||
24.10.2026: реализованы сканирование send_q, история путей пакета и быстрое застревание.
|
||||
Остались прежние input_send_q/input_wait_ack: первый готовый повтор имеет приоритет,
|
||||
иначе выбирается первый готовый новый DATA. Заблокированная запись остаётся на месте
|
||||
и не мешает следующим. Если кандидата нет, допускается одна подгрузка из input_queue
|
||||
в пределах общего бюджета unacked_bytes/optimal_inflight и приёмного окна пира.
|
||||
После синхронного callback проверяются reset/close/эпоха; прежний указатель линка не используется.
|
||||
Во время ограниченной burst-серии готовый повтор другого пути ждёт её завершения;
|
||||
FILLER сохраняет измерение, а новые DATA не обгоняют этот повтор.
|
||||
|
||||
Каждый логический пакет хранит 32 байта битовой истории живых слотов local_link_id.
|
||||
Пока есть неиспользованный допустимый путь, повтор ждёт его cwnd/pacer, а не начинает
|
||||
новый обход уже использованных. После полного обхода прежний путь также уступает
|
||||
другой допустимой альтернативе. История/last_rr_link меняются только после принятия
|
||||
DATA транспортом; rollback их сохраняет. Удаление линка очищает слот до unlink и
|
||||
callbacks, поэтому новый линк с тем же local_link_id не наследует старую историю.
|
||||
|
||||
Три RTO физических попыток без ACK-прогресса ставят tx_stalled. Пока есть хотя бы
|
||||
один незастрявший initialized+UP путь, повторы исключают застрявшие, даже когда
|
||||
рабочий временно занят. Если застряли все — разрешены все UP-пути. Новые DATA
|
||||
используют прежний выбор и могут проверить восстановление: флаг снимает действующий
|
||||
ACK собственной попытки, отправленной после установки флага. Старый/чужой ACK
|
||||
этого не делает. Reset очищает состояние; физический UP, ACK/keepalive и формула RTO
|
||||
сохранены. Новых очередей, payload-копий, таймеров или ранних повторов до RTO нет.
|
||||
|
||||
Windows: 51 сценарий PASS с управляемыми и реальными часами. Покрыты заблокированный
|
||||
префикс 256 записей, приоритет повторов, общий бюджет, OOM, rollback, полный обход,
|
||||
ID 255/переиспользование слота из callback, три RTO, старые ACK, восстановление,
|
||||
все застрявшие пути и reset/close/удаление burst-линка из callback подгрузки.
|
||||
Восемь профильных тестов ASAN/UBSan с detect_leaks=1 проходят без ошибок/утечек.
|
||||
Контроль занятости рабочего пути 1 мс теперь проходит: latency 377.012 мс вместо 736.623 мс,
|
||||
gap 206.810 мс, ready_wait 2.318 мс при бюджете 460.552 мс. Отрицательный контроль 200 мс
|
||||
по-прежнему проваливает ready_wait (200.764 мс), gap и latency; пороги не ослаблены.
|
||||
Логи: /tmp/etcp-send-scan-{windows-final,real-time,busy_1ms,ready_delay_200ms}.log,
|
||||
/tmp/etcp-send-scan-asan-test_*.log.
|
||||
|
||||
Полная последовательная матрица после калибровки эмулятора: все 9 профилей отказов PASS.
|
||||
Two-stuck: gap 217.945 мс, latency 379.997 мс при пределе 462.219 мс, ready_wait 1.184 мс.
|
||||
Ещё три отдельных повтора two-stuck: 3/3 PASS, latency 374.981..378.557 мс,
|
||||
gap 203.057..205.265 мс, ready_wait максимум 13.268 мс. Slow-drop: gap 259.464 мс,
|
||||
latency 264.704 мс при пределе 350.129 мс; это профиль с RTT 200 мс и ожиданием RTO.
|
||||
Load-drop/load-hold: gap 39.234/39.355 мс, steady goodput 7.221/7.468 из 8 Мбит/с.
|
||||
Для насыщенного источника проверяются gap и steady goodput; max_latency 161.287/86.306 мс
|
||||
здесь записана, но отдельным порогом не ограничена. ASAN/UBSan two-stuck/load-drop
|
||||
также PASS с detect_leaks=1, без ошибок и утечек.
|
||||
|
||||
Первые шесть скоростных профилей PASS. Агрегированный goodput
|
||||
(min(application,fresh DATA), Мбит/с): equal 14.390/16, bandwidth 9.048/10,
|
||||
rtt 14.244/16, fast-distant 8.841/10, slow-distant 8.966/10, three 11.017/12.
|
||||
Дуплекс 8.412/8.435 из 10 Мбит/с остаётся FAIL: все 7 нарушений матрицы относятся
|
||||
к его скоростным порогам (одиночные каналы и агрегат). Доставка, порядок и ресурсы
|
||||
проходят. Общая multipath-задача остаётся открытой: далее разбирать дуплекс,
|
||||
STCP backpressure и отдельные проверки смены RTT/BW/повторного отказа.
|
||||
Логи: /tmp/etcp-send-scan-matrix.log/.csv,
|
||||
/tmp/etcp-send-scan-native-two-stuck-<1..3>.log/.csv,
|
||||
/tmp/etcp-send-scan-asan-{two-stuck,load-drop}.log/.csv.
|
||||
|
||||
Полный check.sh после изменений: 184/184, proxy 9/9, burst 1/1, load 8/8 PASS;
|
||||
134217728 проверенных байт, 197 с со сборкой. Отдельная длинная multipath-матрица
|
||||
в check.sh не входит; её оставшиеся нарушения дуплекса перечислены выше.
|
||||
Лог: /tmp/etcp-send-scan-full-check.log.
|
||||
|
||||
Предыдущая диагностика (до реализации сканирования и истории):
|
||||
|
||||
24.10.2026: проверки отказов разделены на RTO, готовность повтора и доставку.
|
||||
В этом этапе менялись только тесты/диагностика, логика ETCP сохранена.
|
||||
TX учитывается после принятия send транспортом, а не при подготовке пакета.
|
||||
@@ -714,11 +896,12 @@ uint8: хранить факт состоявшейся отправки отд
|
||||
Для retry: A->B при обоих UP и меньшем inflight у A; A->B->C->A;
|
||||
посторонние DATA/ACK между попытками; пропуск заблокированных каналов;
|
||||
один доступный путь; все временно заняты; burst старого пути; удаление курсора.
|
||||
После этого повторить всю матрицу скоростей. Выбор пути первоначальных DATA менять только
|
||||
Матрица повторена после сканирования send_q и истории путей; текущие результаты приведены в статусе.
|
||||
Выбор пути первоначальных DATA менять только
|
||||
при сохраняющейся недогрузке: эксперименты уже показывают полную утилизацию
|
||||
без смены алгоритма выбора DATA, поэтому дополнительная эвристика пока лишняя.
|
||||
|
||||
3. Быстрое восстановление и здоровье каналов.
|
||||
3. Быстрое восстановление и здоровье каналов — согласованный этап реализован.
|
||||
Предварительное исправление OOM завершено: выбран сброс всей сессии с сохранением
|
||||
линков, без удержания старого fragment/cursor и без отдельного OOM retry.
|
||||
Очистка не выделяет память, старые callbacks/ожидания отменяются; активные
|
||||
@@ -727,11 +910,13 @@ uint8: хранить факт состоявшейся отправки отд
|
||||
Собственный RTT/RTO и ротация уже обязательны в этапе 2. Проверять ожидание
|
||||
RTO отдельно от задержки готового повтора и доставки альтернативным путём.
|
||||
Ранние копии до RTO исключены по решению пользователя от24.10.2026.
|
||||
При потере ограничить новые DATA на проблемном пути, пробовать восстановление
|
||||
ограниченными probe, повторять недоставленные DATA через рабочие каналы.
|
||||
Не отправлять следующий bulk вслепую в тот же застрявший путь.
|
||||
Проверки: DROP/HOLD отдельно по направлениям и вместе, несколько застрявших
|
||||
каналов, возврат старых копий после HOLD, повторный отказ, смена RTT/BW на ходу.
|
||||
Реализованы флаг после трёх RTO, исключение застрявшего пути только из повторов,
|
||||
полная история обхода, сканирование send_q и восстановление по свежему собственному ACK.
|
||||
Отдельные probes/ограничение новых DATA не входят в выбранное решение: исходный
|
||||
выбор новых DATA сохранён, подтверждённая новая отправка снимает флаг застревания.
|
||||
DROP/HOLD отдельно по направлениям и вместе, несколько застрявших каналов,
|
||||
возврат старых копий после HOLD проходят; повторный отказ и смена RTT/BW на ходу
|
||||
остаются отдельными проверками. Отсутствие рабочих альтернатив и reset/close покрыты.
|
||||
|
||||
4. Учёт нижележащей очереди STCP.
|
||||
Ограниченный tx_queue и уведомление о реальном прогрессе/готовности должны
|
||||
|
||||
+17
-2
@@ -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
|
||||
|
||||
@@ -6,6 +6,14 @@
|
||||
заменяются вместе. Timestamp входит в подпись. Групповые пути и подсети
|
||||
остаются в `TOPO_GROUP_NODE` и не являются частью общей записи узла.
|
||||
|
||||
В NODEINFO секции подсетей присутствуют только при `TOPO_FLAG_SEND_SUBNETS`.
|
||||
Без флага оба счётчика подсетей равны нулю; противоречащий этому заголовок отклоняется.
|
||||
Parser проверяет точную длину пакета и проходит все присутствующие секции независимо
|
||||
от запрошенных `out_*`: например, `out_subnets=NULL` отключает создание объектов подсетей,
|
||||
но сохраняет проверку префиксов и правильное положение следующего hop-list.
|
||||
Выходы выдаются только после полного успеха; при ошибке они обнулены, частичные объекты
|
||||
освобождены. Подпись и допустимость пути проверяются после структурного разбора.
|
||||
|
||||
Получатель проверяет подпись до изменения реестра или маршрутов. Более свежая
|
||||
запись заменяет старую целиком, включая пустые списки адресов. Старые записи
|
||||
игнорируются; разные подписанные записи с одинаковым timestamp — конфликт.
|
||||
@@ -13,6 +21,12 @@
|
||||
8-битный `ver` сохраняется как диагностический счётчик; свежесть определяется
|
||||
только timestamp.
|
||||
|
||||
Локальный узел группы готовится до удаления прежнего `local_node`: сравниваются сами адреса
|
||||
и префиксы подсетей, включая замену при прежнем количестве. При отказе памяти, подписи или
|
||||
конфликте IPv4-маршрутов прежние узел и маршруты сохраняются. Подсети CHAT не публикуются.
|
||||
`topo_group_update_my_nodeinfo` возвращает число IPv4-подсетей, для CHAT — 0, при ошибке — -1;
|
||||
рассылку подготовленного NODEINFO выполняет вызывающий.
|
||||
|
||||
Живая телефонная занятость передаётся без изменения структуры NODEINFO: в существующем
|
||||
`flags` бит `0x04` означает известное состояние, `0x08` — занятость звонком.
|
||||
Это групповые флаги `TOPO_GROUP_NODE.phone_status`, как флаг рации `0x02`;
|
||||
@@ -50,6 +64,8 @@ snapshot загрузка использует его. Локальная пуб
|
||||
Уникальность определяется endpoint и видом адреса,
|
||||
а не отображаемым классом NAT. Старый производный формат пересоздаётся;
|
||||
bootstrap-загрузка без подписанного snapshot не подтверждает NAT-профиль.
|
||||
Такая загрузка требует хотя бы одного адреса; отказ SQL/памяти освобождает все частичные списки
|
||||
и возвращает NULL. Наличие валидного snapshot с пустым списком адресов, напротив, допустимо.
|
||||
При удалении старых `nat_evidence`/`nat_checked` адреса и REALITY сохраняются для bootstrap,
|
||||
старые профили сбрасываются, сериализованные snapshots инвалидируются.
|
||||
Максимальные timestamp snapshots сохраняются, чтобы новая локальная публикация
|
||||
|
||||
@@ -43,6 +43,50 @@
|
||||
Windows/FreeBSD runtime не проверялся.
|
||||
|
||||
[ ] **ETCP: полезная утилизация нескольких каналов и доставка при зависании части линков** — общая задача открыта.
|
||||
24.10.2026: исправлен обход срока ACK посторонним wake. Абсолютный срок головы пути +2 мс,
|
||||
один общий таймер, пересчёт после piggyback/частичной отправки; новые DATA не отодвигают старые ACK.
|
||||
Наступивший ACK другого пути имеет приоритет перед DATA; свой DATA забирает его piggyback.
|
||||
Сохранены срочный ответ, bounded burst, OOM fallback и очистка при reset/close; wire/BBR/RTO не менялись.
|
||||
Windows 60 сценариев с обоими режимами часов PASS; восемь ASAN/UBSan-тестов и ASAN two-stuck без ошибок/утечек.
|
||||
В трёх дуплексных прогонах ранних ACK-пакетов 0; на 8 Мбит/с ACK занимают 0.143..0.169 вместо прежних 0.347/0.390 Мбит/с.
|
||||
Агрегат проходит все свои пороги: 8.667..8.804 / 8.695..8.796 из 10 Мбит/с; одиночные каналы ещё дают FAIL.
|
||||
Полная матрица: первые 6 скоростных профилей и все 9 профилей отказов PASS, агрегат дуплекса 8.750/8.768.
|
||||
Остались 2 FAIL одиночного дуплекса: 1.609<1.700 и 6.730<6.800 Мбит/с; дальше разбирать BW/PROBE_RTT и STCP backpressure.
|
||||
Load-drop/load-hold: паузы 41.402/41.845 мс, steady 7.229/7.466 из 8 Мбит/с; max latency 180.693/89.239 мс записана.
|
||||
Check.sh 184/184, proxy 9/9, burst 1/1, load 8/8 PASS, 134217728 проверенных байт, 185 с.
|
||||
Диагностика 106 полей различает раннюю запись в готовой пачке и отправку всего ACK-пакета раньше срока.
|
||||
Логи/CSV: /tmp/etcp-ack-deadline-*; HTML: /tmp/etcp-ack-deadline-duplex.html; детали — doc/etcp_multipath_plan.txt.
|
||||
Предыдущий этап — диагностика до исправления ACK:
|
||||
Продолжение 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 1/1, load 8/8 PASS, 166 с; JS smoke-проверка графиков/фильтров PASS.
|
||||
На одиночном 8 Мбит/с пути ACK занимают 0.347/0.390 Мбит/с, среднее ожидание ACK-only 230/271 мкс вместо окна 2 мс.
|
||||
В срезах side=1 path=1 DATA готовы, а BBR задаёт около 6.3 Мбит/с; PROBE_RTT временно уменьшает окно до 32.9 тыс. байт.
|
||||
Дедлайн обходит посторонний wake sender. Дальше разбирать абсолютные deadlines ACK; простого !timer недостаточно.
|
||||
Алгоритмы протокола на этом этапе не менялись; полный дуплекс всё ещё не проходит скоростные пороги (5 нарушений, 8.513/8.337).
|
||||
Логи/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.
|
||||
После 3 RTO без ACK-прогресса tx_stalled исключает путь из повторов при наличии незастрявшего UP-пути.
|
||||
Все застрявшие пути допускаются, новые DATA сохраняют прежний выбор; действующий ACK отправки после флага снимает его.
|
||||
Старый/чужой ACK не восстанавливает путь; reset очищает состояние. Новых очередей/таймеров/копий нет, RTO сохранён.
|
||||
Windows: 51 сценарий PASS с управляемыми/реальными часами; восемь ASAN/UBSan-тестов без ошибок/утечек.
|
||||
Контроль занятого на 1 мс рабочего пути: latency 377.012 вместо 736.623 мс, ready_wait 2.318 мс, профиль PASS.
|
||||
Отрицательный контроль задержки готового повтора 200 мс остаётся FAIL по очереди и общей задержке.
|
||||
Полная последовательная multipath-матрица: все 9 профилей отказов PASS, первые 6 скоростных профилей PASS.
|
||||
Two-stuck: latency 379.997 мс при пределе 462.219 мс; ещё 3/3 повтора — 374.981..378.557 мс.
|
||||
Load-drop/load-hold: паузы 39.234/39.355 мс, steady goodput 7.221/7.468 из 8 Мбит/с.
|
||||
Max latency под насыщенной нагрузкой 161.287/86.306 мс записана; отдельным порогом она здесь не ограничена.
|
||||
Two-stuck/load-drop также проходят ASAN/UBSan с detect_leaks=1 без ошибок/утечек.
|
||||
Остаётся дуплекс: 8.412/8.435 из 10 Мбит/с, все 7 нарушений матрицы — его скоростные пороги.
|
||||
Далее — дуплекс, STCP backpressure, отдельные проверки смены RTT/BW и повторного отказа.
|
||||
Полный check.sh: 184/184, proxy 9/9, burst 1/1, load 8/8 PASS, 134217728 проверенных байт, 197 с со сборкой.
|
||||
Длинная multipath-матрица запускается отдельно; её общий результат остаётся FAIL из-за дуплекса.
|
||||
Логи: /tmp/etcp-send-scan-*.log; подробности — doc/etcp_multipath_plan.txt.
|
||||
Предыдущая диагностика:
|
||||
24.10.2026: тесты отдельно проверяют обработку RTO (опоздание<=20мс), ожидание готового повтора (<=100мс)
|
||||
и доставку сверх заданной задержки канала (<=100мс). TX учитывается после принятия send.
|
||||
Быстрые профили сохраняют общий предел100мс; длинные учитывают по одному RTO отказавших путей плюс100мс.
|
||||
|
||||
Reference in new issue
Block a user