Keep BBR loss bounds above the DATA window minimum

This commit is contained in:
evgeny committed 2026-10-23 00:43:54 +02:00
1 parent aefa8ff680
commit 5298fe9f6a
3 files changed
+14 -4

No files matched your search

+1 -1
View File
@@ -792,8 +792,8 @@ static void bbr_bound_cwnd_for_inflight_model(struct bbr* bbr, uint32_t* cwnd, u
(bbr->mode == BBR_PROBE_BW && bbr->cycle_idx == BBR_BW_PROBE_CRUISE))
cap = bbr_inflight_with_headroom(bbr);
cap = (uint32_t)(cap > BBR_CWND_MIN_TARGET * mss ? cap : BBR_CWND_MIN_TARGET * mss);
cap = (uint32_t)(cap < bbr->inflight_lo ? cap : bbr->inflight_lo);
cap = (uint32_t)(cap > BBR_CWND_MIN_TARGET * mss ? cap : BBR_CWND_MIN_TARGET * mss);
*cwnd = (uint32_t)(cap < *cwnd ? cap : *cwnd);
}
+10 -2
View File
@@ -1,7 +1,10 @@
/* etcp_bbr — модель congestion control одного ETCP-линка: состояния BBR, окно и pacing rate.
* ETCP собирает bbr_rate_sample из ACK/потерь и вызывает init/main/note_loss/tx_start в uasync-потоке.
* Модуль не отправляет пакеты: возвращённые лимиты применяет линк/loadbalancer.
* cwnd/inflight/delivered — байты, interval/rtt — микросекунды, pacing_rate — байты в секунду. */
* cwnd/inflight/delivered — байты DATA, interval/rtt — микросекунды, pacing_rate — байты в секунду.
* MSS — максимальный DATA-фрагмент normalizer, без заголовков; не wire-MTU и не размер кадра STCP.
* Минимальное окно — 4*MSS; PROBE_RTT осушает до max(4*MSS, 0.5*BDP), затем ждёт >=200мс и раунд ACK.
* Транспорт применяет окно с верхним ограничением конфига и не повышает его до собственного минимума. */
#pragma once
#include <stdint.h>
@@ -96,7 +99,7 @@ struct bbr {
uint8_t extra_acked_win_idx : 1;
uint8_t extra_acked_win_rtts : 5;
uint32_t prior_cwnd;
uint8_t init_cwnd : 7;
uint8_t init_cwnd : 7; // начальное окно в DATA-фрагментах; init задаёт BBR_CWND_MIN_TARGET
uint8_t full_bw_cnt : 2;
uint8_t ack_phase : 3;
uint8_t loss_events_in_round : 4;
@@ -112,7 +115,12 @@ struct bbr {
void* cwnd_update_ctx;
};
// Инициализировать выделенную модель: STARTUP, начальное окно 4 DATA-фрагмента, неизвестные RTT/полоса.
void bbr_init(struct bbr* bbr);
/* Обработать ACK rs и обновить входные/выходные cwnd_out (байты DATA) и pacing_rate_out (B/s).
* mss>0 — frag_size normalizer; inflight_bytes — текущий занятый DATA-flight после ACK;
* is_cwnd_limited — отправитель упирался в окно до ACK. Все указатели обязательны.
* При неверных аргументах логирует ошибку и сохраняет выходы; void. */
void bbr_main(struct bbr* bbr, const struct bbr_rate_sample* rs,
uint32_t* cwnd_out, uint32_t* pacing_rate_out,
uint32_t mss, uint32_t inflight_bytes, int is_cwnd_limited);
+3 -1
View File
@@ -30,7 +30,7 @@ extern "C" {
#define ACK_REZERV 100// сколько байт резервировать под ack и прочие заголовки
#define WIRE_OVERHEAD(fam) ((fam) == AF_INET6 ? IP_UDP_OVERHEAD_V6 + SC_ENCRYPT_OVERHEAD : IP_UDP_OVERHEAD_V4 + SC_ENCRYPT_OVERHEAD)
#define INFLIGHT_LIM_MIN 8192 // 8K
#define INFLIGHT_LIM_MIN 8192 // минимально допустимый bbr_max_cwnd в конфиге; не минимум текущего окна BBR
#define INFLIGHT_LIM_MAX 1048576 // 1M
#define PACKET_DATA_SIZE 2048
@@ -386,6 +386,8 @@ void tcp_server_on_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock);
struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn,
const struct sockaddr_storage* remote_addr, uint8_t is_server);
// Применить окно DATA new_lim>0 (байты), ограничить сверху max_inflight и разбудить отправитель.
// Минимум выбирает BBR; ноль отклоняется с логом без изменения окна. Неверный link игнорируется.
void etcp_link_update_inflight_lim(struct ETCP_LINK* link, uint32_t new_lim);
void etcp_link_close(struct ETCP_LINK* link);