Document receiver-bounded BBR samples and diagnostic input contracts

This commit is contained in:
evgeny committed 2026-10-24 00:33:19 +02:00
1 parent 9459b43211
commit 2715faffff
3 files changed
+21 -9

No files matched your search

+3 -2
View File
@@ -1,5 +1,6 @@
/* etcp_bbr — модель congestion control одного ETCP-линка: состояния BBR, окно и pacing rate.
* ETCP собирает bbr_rate_sample из ACK/потерь и вызывает init/main/note_loss/tx_start в uasync-потоке.
* ETCP собирает bbr_rate_sample из ACK/потерь и вызывает init/main/note_loss в uasync-потоке.
* tx_start — отдельный helper возобновления после idle, текущая интеграция ETCP его не вызывает.
* Модуль не отправляет пакеты: возвращённые лимиты применяет линк/loadbalancer.
* cwnd/inflight/delivered — байты DATA, interval/rtt — микросекунды, pacing_rate — байты в секунду.
* MSS — максимальный DATA-фрагмент normalizer, без заголовков; не wire-MTU и не размер кадра STCP.
@@ -54,7 +55,7 @@ enum bbr_ack_phase { BBR_ACKS_INIT = 0, BBR_ACKS_REFILLING, BBR_ACKS_PROBE_ST
struct bbr_rate_sample {
uint32_t delivered; // байты, подтверждённые за измерительный интервал; не только текущим ACK
uint32_t interval_us; // max(интервал отправки, интервал доставки), мкс; 0 — нет достоверной оценки скорости
uint32_t interval_us; // измерительный интервал, мкс; ETCP берёт max(send,ACK,приёмная граница); 0 — нет оценки BW
uint32_t rtt_us; // RTT линка, мкс; 0 — пока неизвестен
uint32_t acked_sacked; // новые подтверждённые байты текущего ACK; только они увеличивают общий delivered
uint32_t prior_delivered; // счётчик delivered при отправке подтверждённого пакета, modulo 2^32
+12 -4
View File
@@ -18,7 +18,7 @@ bbr_init(&bbr_state); // устанавливает STARTUP, сбрасывае
```c
struct bbr_rate_sample rs = {
.delivered = bytes_delivered_in_sample,
.interval_us = max_send_or_delivery_interval_us,
.interval_us = measurement_interval_us,
.rtt_us = latest_rtt_us,
.acked_sacked = bytes_acked,
.lost = bytes_lost_since_last_ack,
@@ -32,12 +32,15 @@ bbr_main(&bbr_state, &rs, &cwnd, &pacing_rate, MSS, inflight_bytes, is_cwnd_limi
// применять cwnd, pacing_rate к линку
```
### Нотификация о потерях и старте передачи
### Нотификация о потерях и helper старта передачи
```c
bbr_note_loss(&bbr_state); // вызывать при обнаружении потери
bbr_tx_start(&bbr_state); // вызывать при возобновлении отправки после idle
```
`bbr_tx_start` доступен как отдельный API, текущая интеграция ETCP его не вызывает.
Базу измерений после пустого flight заново задаёт `etcp_tx_complete`.
### Интеграция с ETCP_LINK
BBR создаётся в `etcp_link_new()` как `link->bbr`. `etcp_tx_ack()` передаёт sample только известной попытки своего линка.
Sample использует неизменные снимки delivered и времени доставки/отправки из `ETCP_TX_ATTEMPT`.
@@ -46,7 +49,12 @@ DATA несёт `seq:u32+attempt_no:u16`, ACK возвращает их и за
Исчерпание номера или seq меняет эпоху потока до повторного использования пары; старые DATA/ACK отсекаются сессией.
RTT попытки равен времени до ACK минус эта задержка. Неизвестный/истёкший ID не обновляет BBR/RTT или физическое окно.
`etcp_ack_recv()` освобождает только логическую запись; кумулятивный till не создаёт BBR samples.
Интервал — максимум времени отправки и подтверждения; ACK одной пачки не создают искусственную сверхскорость.
Базовый интервал — максимум времени отправки и подтверждения; соседние ACK одной пачки не используются как интервал.
ACK с подтверждениями передаёт также точку приёма пути: накопленные DATA-байты и монотонное время получателя.
Попытка хранит известную точку при отправке. При достоверных положительных дельтах interval дополнительно
ограничивается снизу `ceil(delivered * delta_rx_us / delta_rx_bytes)`. Итог — максимум трёх границ:
коррекция может только снизить BW sample. Часы разных сторон не сравниваются, RTT/min_rtt не меняются.
Неизвестные/нулевые дельты не создают границу; при непредставимом uint32-интервале оценка BW не используется.
`acked_sacked` увеличивает общий счётчик, `delivered` описывает весь интервал и может включать предыдущие ACK.
Окно применяется через `etcp_link_update_inflight_lim`, точный pacing B/s — через `etcp_loadbalancer_set_pacing_rate`.
Shaper списывает DATA-байты, без заголовков и piggyback ACK. При смене ставки остаток долга пересчитывается;
@@ -94,7 +102,7 @@ ACK-only не ограничивается этим pacing, но проходи
| Поле | Назначение |
|------|-----------|
| `delivered` | байты, доставленные за измерительный интервал |
| `interval_us` | max(интервал отправки, интервал доставки), мкс; 0 — нет оценки скорости |
| `interval_us` | Измерительный интервал, мкс; в ETCP max(send,ACK,приёмная граница); 0 — нет оценки скорости |
| `rtt_us` | последний измеренный RTT |
| `acked_sacked` | байт подтверждено (+SACK) |
| `prior_delivered` | кумулятивно доставлено при отправке подтверждаемого пакета (для детекта round) |
+6 -3
View File
@@ -1,5 +1,6 @@
/* etcp_debug — форматирование IPv4 в host order и диагностический разбор секций ETCP_DGRAM.
* ip_to_string возвращает строку по значению. dump_pkt_sections пишет DEBUG категории dump,
/* etcp_debug — форматирование IPv4 и диагностический разбор секций ETCP_DGRAM.
* ip_to_string печатает байты uint32 в порядке [3..0]; на little-endian это IPv4 в host order.
* Строка возвращается по значению. dump_pkt_sections пишет DEBUG категории dump,
* не меняет пакет и не проверяет его криптографию; состояние pkt/link читается в uasync-потоке. */
#ifndef ETCP_DEBUG_H
#define ETCP_DEBUG_H
@@ -11,10 +12,12 @@ extern "C" {
#include "etcp_connections.h"
typedef struct { char a[16]; } IP_STR;
typedef struct { char a[16]; } IP_STR; // IPv4 a.b.c.d с завершающим нулём.
// ip — число; на little-endian 0x0A000001 даёт 10.0.0.1. Входной network order сначала преобразовать через ntohl.
IP_STR ip_to_string(uint32_t ip);
// pkt->data содержит секции без SESSION_DATA; is_send!=0 — SEND, иначе RECV. Указатели заимствованы.
void etcp_dump_pkt_sections(struct ETCP_DGRAM* pkt, struct ETCP_LINK* link, int is_send);