From 2715faffffe8dd3533d443c1b78b3a228a0d0b19 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 24 Oct 2026 00:33:19 +0200 Subject: [PATCH] Document receiver-bounded BBR samples and diagnostic input contracts --- src/transport_layer/etcp_bbr.h | 5 +++-- src/transport_layer/etcp_bbr_doc.md | 16 ++++++++++++---- src/transport_layer/etcp_debug.h | 9 ++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/transport_layer/etcp_bbr.h b/src/transport_layer/etcp_bbr.h index 5bad8f6b..9fea04ad 100644 --- a/src/transport_layer/etcp_bbr.h +++ b/src/transport_layer/etcp_bbr.h @@ -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 diff --git a/src/transport_layer/etcp_bbr_doc.md b/src/transport_layer/etcp_bbr_doc.md index d0fd05e2..0c109591 100644 --- a/src/transport_layer/etcp_bbr_doc.md +++ b/src/transport_layer/etcp_bbr_doc.md @@ -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) | diff --git a/src/transport_layer/etcp_debug.h b/src/transport_layer/etcp_debug.h index c599410c..c0730a22 100644 --- a/src/transport_layer/etcp_debug.h +++ b/src/transport_layer/etcp_debug.h @@ -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);