Document DATA MSS and shared BBR transport window contracts

This commit is contained in:
evgeny committed 2026-10-23 00:45:09 +02:00
1 parent 5298fe9f6a
commit 08b6b2e2a1
3 files changed
+29 -20

No files matched your search

+4 -1
View File
@@ -63,7 +63,10 @@ BBR каждого линка получает ACK/loss samples и возвра
Скорость — доставленные байты за max(интервал отправки, интервал доставки), по снимкам при отправке.
Интервал между соседними ACK не используется: ACK одной пачки могут обрабатываться в один tick.
Внутренняя полоса — байты/мкс Q16; pacing — байты/с, BDP — байты, без повторного множителя MSS.
Лимит DATA — не менее 8192 байт и не более bbr_max_cwnd (по умолчанию 1048576).
Минимальное окно BBR — четыре DATA-фрагмента normalizer; максимальное — bbr_max_cwnd (по умолчанию 1048576).
8192 — нижняя допустимая граница настройки bbr_max_cwnd; транспорт не повышает до неё текущее окно.
PROBE_RTT осушает flight до max(4*MSS, 0.5*BDP), выдерживает >=200мс и раунд ACK, затем восстанавливает окно.
MSS — размер DATA-фрагмента normalizer без заголовков; начальное окно UDP и STCP равно 4*MSS с верхним лимитом конфига.
Отказ из-за нехватки окна сохраняет cwnd_limited до следующего ACK: вычитание ACK
не должно скрывать этот факт от BBR. app_limited учитывает ожидающие очереди и
pending/частичный буфер normalizer; ограничение окном не означает отсутствие данных.
+21 -15
View File
@@ -1,28 +1,30 @@
# BBR Congestion Control (etcp_bbr)
## 1. Назначение
Реализация алгоритма BBRv3 (Bottleneck Bandwidth and Round-trip propagation time) для контроля перегрузки на каждом ETCP-линке независимо. Вычисляет оптимальный cwnd и pacing rate на основе измерений bandwidth и RTT, а не потерь пакетов (в отличие от loss-based алгоритмов). Моделирует состояние канала через четыре фазы: STARTUP (экспоненциальный поиск bandwidth), DRAIN (слив лишнего inflight), PROBE_BW (циклическое зондирование), PROBE_RTT (периодический замер минимального RTT).
Адаптация BBRv3 (Bottleneck Bandwidth and Round-trip propagation time) для контроля перегрузки каждого ETCP-линка. Вычисляет cwnd и pacing rate по измерениям bandwidth/RTT и ограничивает их при потерях. Состояния: STARTUP (поиск bandwidth), DRAIN (слив лишнего inflight), PROBE_BW (циклическое зондирование), PROBE_RTT (замер минимального RTT).
## 2. Как пользоваться
### Инициализация
```c
struct bbr bbr_state;
struct bbr bbr_state = {0};
bbr_init(&bbr_state); // устанавливает STARTUP, сбрасывает все окна
```
Сразу после init нужно установить `init_cwnd` через etcp/kernel, BBR начинает со STARTUP.
`init_cwnd` равен четырём DATA-фрагментам. ETCP задаёт начальное окно `init_cwnd * normalizer->frag_size`,
ограниченное сверху настройкой `bbr_max_cwnd`. MSS здесь — размер DATA без протокольных заголовков,
а не wire-MTU или максимальный размер кадра STCP.
### Вызов на каждом ACK
```c
struct bbr_rate_sample rs = {
.delivered = packets_delivered_this_ack,
.interval_us = us_since_last_ack,
.delivered = bytes_delivered_in_sample,
.interval_us = max_send_or_delivery_interval_us,
.rtt_us = latest_rtt_us,
.acked_sacked = bytes_acked,
.lost = packets_lost_since_last_ack,
.is_app_limited = is_output_queue_below_target,
.tx_in_flight = current_inflight_packets,
.prior_delivered = cumulative_delivered_before,
.lost = bytes_lost_since_last_ack,
.is_app_limited = sender_was_limited,
.tx_in_flight = inflight_bytes_at_send,
.prior_delivered = cumulative_delivered_at_send,
};
uint32_t cwnd = current_cwnd, pacing_rate = current_pacing;
@@ -42,6 +44,10 @@ Sample использует снимки delivered и времени доста
Интервал — максимум времени отправки и подтверждения; ACK одной пачки не создают искусственную сверхскорость.
`acked_sacked` увеличивает общий счётчик, `delivered` описывает весь интервал и может включать предыдущие ACK.
Окно применяется через `etcp_link_update_inflight_lim`, pacing — к исходящим DATA.
BBR определяет минимум 4*MSS; транспорт ограничивает окно только сверху. `INFLIGHT_LIM_MIN=8192`
задаёт допустимый минимум настройки максимального окна, а не текущее окно.
PROBE_RTT осушает flight до `max(4*MSS, 0.5*BDP)`, выдерживает не менее 200мс и раунд ACK, затем восстанавливает окно.
DATA, отправленные в PROBE_RTT, помечаются app_limited, чтобы низкая скорость осушения не понижала оценку полосы.
ACK-only не ограничивается этим pacing, но проходит общую физическую очередь канала.
### Тестирование
@@ -50,7 +56,7 @@ ACK-only не ограничивается этим pacing, но проходи
### Фиксированная точка
- `BBR_SCALE = 8` — масштаб для gain-коэффициентов (2.77 = 2.77 * 256)
- `BW_SCALE = 16` — байты/мкс Q16; повторного умножения на MSS при получении B/s и BDP нет
- MSS используется для минимального окна. Pacing API ограничен UINT32_MAX B/s, переполнения насыщаются
- MSS используется для минимального окна и бюджета зондирования. Pacing API ограничен UINT32_MAX B/s, переполнения насыщаются
- Все внутренние вычисления в фиксированной точке, преобразование в реальные единицы через `bbr_rate_bytes_per_sec()`
## 3. API
@@ -64,12 +70,12 @@ ACK-only не ограничивается этим pacing, но проходи
| `interval_us` | max(интервал отправки, интервал доставки), мкс; 0 — нет оценки скорости |
| `rtt_us` | последний измеренный RTT |
| `acked_sacked` | байт подтверждено (+SACK) |
| `prior_delivered` | кумулятивно доставлено до этого ACK (для детекта round) |
| `prior_delivered` | кумулятивно доставлено при отправке подтверждаемого пакета (для детекта round) |
| `tx_in_flight` | inflight на момент отправки подтверждённых пакетов |
| `lost` | потерянные байты с последнего ACK |
| `is_app_limited` | приложение не забивает канал (выходная очередь ниже порога) |
| `is_app_limited` | при отправке не было ожидающих данных приложения либо шёл PROBE_RTT |
**`struct bbr`** — состояние BBR на линк (подробности в etcp_bbr.h:55-108)
**`struct bbr`** — состояние BBR на линк (контракт в etcp_bbr.h).
### Функции
@@ -88,7 +94,7 @@ ACK-only не ограничивается этим pacing, но проходи
| `BBR_STARTUP` (0) | Экспоненциальный рост cwnd (gain 2.77 pace, 2.0 cwnd), пока не найден bottleneck |
| `BBR_DRAIN` (1) | Слив избыточного inflight (gain 1000/2885 ≈ 0.35 pace) |
| `BBR_PROBE_BW` (2) | Основной рабочий режим, циклическое зондирование |
| `BBR_PROBE_RTT` (3) | Периодический сброс cwnd до 4*MSS для замера min_rtt |
| `BBR_PROBE_RTT` (3) | Осушение flight до max(4*MSS, 0.5*BDP), удержание >=200мс и раунд ACK |
Циклы внутри `BBR_PROBE_BW`:
- `BBR_BW_PROBE_UP` (1.25× pace) — зондирование большей полосы
@@ -98,4 +104,4 @@ ACK-only не ограничивается этим pacing, но проходи
### Зависимости
- `lib/u_async.h` — `get_time_tb()` для реального времени
- `lib/debug_config.h` — `DEBUG_DEBUG(DEBUG_CATEGORY_BBR, ...)` для отладки
- `lib/debug_config.h` — `DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, ...)` для отладки
+4 -4
View File
@@ -188,7 +188,7 @@ void my_ping_callback(int success, uint16_t rtt, void* arg, uint64_t nonce,
| `etcp_socket_remove(e_sock)` | Закрыть сокет, удалить все линки, освободить память |
| `etcp_link_new(etcp, conn, addr, is_server)` | Создать ETCP_LINK: выделить local_link_id, BBR, вставить в сокет и ETCP_CONN |
| `etcp_link_close(link)` | Удалить линк: таймеры, удаление из списков сокета и ETCP_CONN |
| `etcp_link_update_inflight_lim(link, new_lim)` | Обновить лимит inflight (clamped к [8K, max_inflight]) |
| `etcp_link_update_inflight_lim(link, new_lim)` | Применить положительное окно DATA, ограничив сверху max_inflight; ноль отклоняется |
| `etcp_encrypt_send(dgram)` | Зашифровать dgram (SC_CCM) + UDP-отправка через `etcp_udp_send` |
| `etcp_udp_send(link, fd, buf, len, addr, len)` | Отправка: если `send_hook` — через него, иначе `socket_sendto` |
| `etcp_send_ping(inst, pubkey, addr, timeout, cb, arg, data, len)` | One-shot PING |
@@ -211,10 +211,10 @@ void my_ping_callback(int success, uint16_t rtt, void* arg, uint64_t nonce,
| Константа | Значение | Назначение |
|-----------|----------|-----------|
| `INFLIGHT_LIM_MIN` | 8192 | Минимальный inflight (8K) |
| `INFLIGHT_LIM_MIN` | 8192 | Минимальное допустимое значение настройки bbr_max_cwnd; текущий минимум окна задаёт BBR |
| `INFLIGHT_LIM_MAX` | 1048576 | Максимальный inflight (1M) |
| `PACKET_DATA_SIZE` | 1600 | Размер буфера пакета |
| `PACKET_DATA_MAX_MTU` | 1600 | Максимальный MTU |
| `PACKET_DATA_SIZE` | 2048 | Размер внутреннего буфера пакета |
| `PACKET_DATA_MAX_MTU` | 1500 | Максимальный wire-MTU UDP |
| `KA_PERIOD_MIN_MS` | 200 | Мин. период keepalive |
| `KA_PERIOD_MAX_MS` | 10000 | Макс. период keepalive |
| `KA_TIMEOUT_MULT` | 10 | Множитель таймаута = period×10 |