Document multipath acceptance criteria and reproduced protocol limitations

This commit is contained in:
evgeny committed 2026-10-22 23:36:21 +02:00
1 parent 076016f34a
commit 0b5a892a88
2 files changed
+37 -11

No files matched your search

+19
View File
@@ -4,6 +4,25 @@
## Текущие задачи
[ ] **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 не выполняются требования утилизации, в том числе из-за повторов и переполнения очередей.
Протокольный фикс не вносился. Отдельно проверить выбор пути повторов, общий RTO, BBR/pacing и блокировку сборки.
После исправлений добавить смену профилей на ходу, повторяющиеся отказы и смешанный UDP/STCP со stalled TCP write.
Полная матрица дольше 90s общего runner и запускается отдельной целью; нарушения завершают её с ошибкой.
[+] **ETCP: единый установщик прямого транспорта через NCD** — исправлено 22.10.2026:
Удалён неиспользуемый рабочим кодом etcp_connect с EARLY/LATE, отдельными линками и таймерами;
три тестовых файла переведены на NCD handles с начала подключения. Сохранены проверки независимых владельцев,
+18 -11
View File
@@ -1,7 +1,7 @@
# Dummynet — UDP Network Emulator
## 1. Назначение
Эмулятор сетевых условий для тестирования: задержка (фиксированная + случайная), ограничение пропускной способности (token bucket) и случайные потери пакетов. Два режима работы: **FULL** (автономный UDP-прокси между портами) и **INLINE** (встраиваемый фильтр в `send_hook` ETCP_LINK без создания своего сокета).
Эмулятор сетевых условий: задержка (фиксированная + случайная), сериализация с BWlim и потери пакетов. **FULL** — UDP-прокси между явно заданными endpoints; **INLINE** — фильтр потерь в `send_hook` ETCP_LINK. Задержка и BWlim реализованы в FULL.
## 2. Как пользоваться
@@ -9,17 +9,17 @@
1. `dummynet_create(ua, bind_ip, listen_port)` — создаёт контекст, открывает UDP-сокет на `listen_port`.
2. `dummynet_set_direction(dn, DUMMYNET_FORWARD, ...)` и `DUMMYNET_BACKWARD` — настраивает параметры для каждого направления.
3. Пакеты от `listen_port-1` идут в направлении FORWARD, от `listen_port+1` — в BACKWARD.
3. Источник FORWARD — endpoint, заданный как назначение BACKWARD, и наоборот. Порты независимы; `listen_port=0` выбирает ОС.
```
[port-1] → [dummynet: delay→loss→shaper] → [dest_forward]
[port+1] → [dummynet: delay→loss→shaper] → [dest_backward]
[dest_backward] → [dummynet: loss/queue limit→delay→serializer] → [dest_forward]
[dest_forward] → [dummynet: loss/queue limit→delay→serializer] → [dest_backward]
```
### Режим INLINE (send_hook в ETCP_LINK)
1. `dummynet_filter_create(ua)` — создаёт фильтр (нет своего сокета).
2. `dummynet_filter_set_loss(df, permille)` / `dummynet_filter_set_delay(df, ms, jitter_ms)` — настройка.
2. `dummynet_filter_set_loss(df, permille)` — настройка потерь. `set_delay` пока только сохраняет параметры.
3. `dummynet_filter_attach(df, link)` — встраивается в `link->send_hook`, перехватывая все вызовы `socket_sendto`.
4. Дополнительно: `dummynet_filter_block_addr/unblock_addr` — блокировка отправки на конкретные адреса.
@@ -28,18 +28,24 @@
| Механизм | Реализация |
|----------|-----------|
| **Delay** (fixed + random) | При приёме пакета создаётся uasync-таймер (`dummynet_delay_callback`). После срабатывания пакет кладётся в ll_queue направления |
| **Bandwidth (token bucket)** | Shaper-таймер забирает из очереди по одному пакету с интервалом `len × 8 / bw_kbps` (timebase 0.1ms). Гарантирует не более `bandwidth_kbps` |
| **Bandwidth (serializer)** | Срок передачи увеличивается на время сериализации текущего пакета; дробные миллисекунды сохраняются. Один таймер направления выпускает все уже готовые пакеты, без накопления ошибки округления таймера |
| **Loss (permille)** | При приёме: `rand() % 1000 < loss_permille` → дроп. В INLINE-режиме — в хуке отправки |
| **DROP** | `dummynet_set_mode(dn, dir, DUMMYNET_DROP)` теряет новые пакеты и удаляет уже ожидающие, включая delay |
| **HOLD** | Останавливает сериализацию, сохраняя ограниченную очередь. RUN начинает сериализацию головы заново; накопленное выпускается с BWlim |
### Статистика
Структура `dummynet_stats`: `recv`, `sent`, `dropped` (переполнение очереди), `lost` (random loss), `queue_size` (текущий), `queue_max` (пиковый).
`recv`/`sent` — число пакетов, `recv_bytes`/`sent_bytes` — UDP-байты без IP/UDP заголовков.
`dropped` — переполнение/ошибка ресурсов или отправки, `lost` — случайные потери и DROP, `blocked` — только DROP.
`queue_size`/`queue_max` учитывают все ожидающие пакеты, включая delay/HOLD. Сброс статистики сохраняет текущий размер очереди.
Дополнительные отладочные счётчики: `delay_timer_set/fire`, `shaper_timer_set/fire`.
### Ключевые нюансы
- В FULL-режиме порты `listen_port-1`, `listen_port`, `listen_port+1` должны быть свободны. Направление определяется по порту источника.
- Шейпер использует burst allowance (`SHAPER_BURST_TB = 10 timebase units`), допуская небольшие всплески.
- При переполнении очереди (> `max_queue_pkts`) пакет дропается, увеличивается `dropped`.
- Оба направления нужно настроить до начала трафика; источник проверяется по IP и порту.
- BWlim задаётся в десятичных кбит/с по UDP-байтам; 0 означает unlimited. RTT без очередей — сумма задержек направлений и сериализации.
- Таймеры uasync имеют миллисекундную точность: несколько готовых пакетов могут выйти вместе; средняя скорость сохраняется.
- При достижении `max_queue_pkts` новый пакет отбрасывается. Лимит включает ещё не сработавшие delay-таймеры.
- Все операции — в потоке ua. Destroy отменяет также delay-таймеры, освобождает их аргументы и пакеты.
- INLINE-фильтр в режиме блокировки адреса не дропает пакет, а возвращает `len` (пакет «успешно отправлен», но фактически никуда не ушёл).
## 3. API
@@ -51,6 +57,7 @@
| `dummynet_create(ua, bind_ip, listen_port)` | Создать контекст, открыть UDP-сокет, зарегистрировать в uasync |
| `dummynet_destroy(dn)` | Закрыть сокет, отменить таймеры, очистить очереди, освободить память |
| `dummynet_set_direction(dn, dir, delay_fixed_ms, delay_random_ms, bw_kbps, max_q, loss_permille, dest_ip, dest_port)` | Настроить параметры направления |
| `dummynet_set_mode(dn, dir, mode)` | RUN/DROP/HOLD направления, 0 / -1 |
| `dummynet_get_stats(dn, dir)` | Получить статистику направления |
| `dummynet_reset_stats(dn, dir)` | Сбросить статистику (-1 = все направления) |
| `dummynet_get_socket(dn)` | Вернуть fd сокета |
@@ -77,7 +84,7 @@
| Структура | Назначение |
|-----------|------------|
| `dummynet_stats` | Статистика: `recv`, `sent`, `dropped`, `lost`, `queue_size`, `queue_max` |
| `dummynet_stats` | Счётчики пакетов/байтов, потерь и размера очереди; точные поля — в dummynet.h |
| `dummynet_dir` | Внутренняя: параметры направления, очередь, таймеры шейпера, отладочные счётчики |
| `dummynet` | Контекст FULL-режима: ua, сокет, два `dummynet_dir`, пул пакетов |
| `dummynet_filter` | Контекст INLINE-режима: ua, loss_permille, delay, link, статистика, список блокировок |