Apply BBR DATA windows consistently during startup and RTT probes

This commit is contained in:
evgeny committed 2026-10-23 00:42:45 +02:00
1 parent 92a535e009
commit 0f23076f48
3 files changed
+25 -19

No files matched your search

+2 -1
View File
@@ -1319,6 +1319,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
struct PKTNORM* pn = etcp->normalizer;
inf_pkt->is_app_limited = !etcp->input_queue->count && !etcp->input_send_q->count &&
(!pn || (!pn->input->count && !pn->pending && !pn->data_ptr));
if (link->bbr && link->bbr->mode == BBR_PROBE_RTT) inf_pkt->is_app_limited = 1;
// Update last_link for future ACK/retrans
inf_pkt->last_link = link;
@@ -1634,7 +1635,7 @@ void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t d
uint32_t old_pacing = link->bbr_pacing_rate;
uint32_t new_cwnd = old_cwnd;
uint32_t new_pacing = old_pacing;
bbr_main(link->bbr, &rs, &new_cwnd, &new_pacing, link->mtu, link->inflight_bytes,
bbr_main(link->bbr, &rs, &new_cwnd, &new_pacing, etcp->normalizer->frag_size, link->inflight_bytes,
cwnd_limited);
link->cwnd_limited = 0;
etcp_link_update_inflight_lim(link, new_cwnd);
+9 -8
View File
@@ -347,8 +347,8 @@ static void bbr_exit_probe_rtt(struct bbr* bbr)
static uint32_t bbr_probe_rtt_cwnd(const struct bbr* bbr, uint32_t mss)
{
(void)bbr;
return BBR_CWND_MIN_TARGET * mss;
uint32_t bdp = bbr_bdp(bbr, bbr_bw(bbr), BBR_PROBE_RTT_CWND_GAIN, mss);
return bdp > BBR_CWND_MIN_TARGET * mss ? bdp : BBR_CWND_MIN_TARGET * mss;
}
static uint32_t bbr_inflight_with_headroom(const struct bbr* bbr)
@@ -571,11 +571,10 @@ static void bbr_check_probe_rtt_done(struct bbr* bbr, uint32_t* cwnd)
}
static void bbr_update_min_rtt(struct bbr* bbr, const struct bbr_rate_sample* rs,
uint32_t* cwnd, uint32_t mss, uint32_t inflight_packets)
uint32_t* cwnd, uint32_t mss, uint32_t inflight_bytes)
{
uint32_t expire;
int probe_rtt_expired, min_rtt_expired;
(void)mss;
expire = (uint32_t)(bbr->probe_rtt_min_stamp_tb + BBR_PROBE_RTT_WIN_MS * 10U);
probe_rtt_expired = ((int32_t)(expire - (uint32_t)bbr_now(bbr)) < 0);
@@ -597,8 +596,8 @@ static void bbr_update_min_rtt(struct bbr* bbr, const struct bbr_rate_sample* rs
if (BBR_PROBE_RTT_MS > 0 && probe_rtt_expired &&
!bbr->idle_restart && bbr->mode != BBR_PROBE_RTT) {
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[L%u] mode %d→%d →PROBE_RTT cwnd=%u infl_pkt=%u",
bbr->link_id, bbr->mode, BBR_PROBE_RTT, *cwnd, inflight_packets);
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[L%u] mode %d→%d →PROBE_RTT cwnd=%u inflight=%u target=%u DATA_MSS=%u",
bbr->link_id, bbr->mode, BBR_PROBE_RTT, *cwnd, inflight_bytes, bbr_probe_rtt_cwnd(bbr, mss), mss);
bbr->mode = BBR_PROBE_RTT;
bbr_save_cwnd(bbr, *cwnd);
bbr->probe_rtt_done_stamp_tb = 0;
@@ -608,10 +607,12 @@ static void bbr_update_min_rtt(struct bbr* bbr, const struct bbr_rate_sample* rs
if (bbr->mode == BBR_PROBE_RTT) {
if (!bbr->probe_rtt_done_stamp_tb &&
inflight_packets <= bbr_probe_rtt_cwnd(bbr, mss)) {
inflight_bytes <= bbr_probe_rtt_cwnd(bbr, mss)) {
bbr->probe_rtt_done_stamp_tb = (uint32_t)bbr_now(bbr) + BBR_PROBE_RTT_MS * 10U;
bbr->probe_rtt_round_done = 0;
bbr->next_rtt_delivered = bbr->delivered;
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[L%u] PROBE_RTT drained inflight=%u target=%u hold_ms=%u",
bbr->link_id, inflight_bytes, bbr_probe_rtt_cwnd(bbr, mss), BBR_PROBE_RTT_MS);
} else if (bbr->probe_rtt_done_stamp_tb) {
if (bbr->round_start)
bbr->probe_rtt_round_done = 1;
@@ -825,7 +826,7 @@ static int bbr_run_fast_path(struct bbr* bbr, int* update_model,
void bbr_init(struct bbr* bbr)
{
bbr->initialized = 1;
bbr->init_cwnd = 0;
bbr->init_cwnd = BBR_CWND_MIN_TARGET;
bbr->prior_cwnd = 0;
bbr->delivered = 0;
bbr->next_rtt_delivered = 0;
+14 -10
View File
@@ -1058,10 +1058,10 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
link->is_tcp = (uint8_t)is_tcp;
int mtu;
mtu = conn ? conn->mtu : STCP_MAX_MSG_SIZE;
if (is_tcp) { mtu = STCP_MAX_MSG_SIZE; link->mtu_local = mtu; link->mtu = mtu; link->inflight_lim_bytes = mtu * 4; link->handshake_minsize = 100; link->handshake_maxsize = mtu; }
else { if (mtu == 0) mtu = 1280; if (mtu > PACKET_DATA_MAX_MTU) mtu = PACKET_DATA_MAX_MTU; link->mtu_local = mtu; link->mtu = mtu; link->inflight_lim_bytes = mtu * 4; link->handshake_minsize = 100; link->handshake_maxsize = mtu; }
/* mtu init moved above */
etcp_update_mtu(etcp);
if (is_tcp) mtu = STCP_MAX_MSG_SIZE;
else { if (mtu == 0) mtu = 1280; if (mtu > PACKET_DATA_MAX_MTU) mtu = PACKET_DATA_MAX_MTU; }
link->mtu_local = link->mtu = mtu;
link->handshake_minsize = 100; link->handshake_maxsize = mtu;
link->initialized = 0;
link->init_timer = NULL;
link->init_timeout = 0;
@@ -1092,7 +1092,6 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
link->ka_announce_attempts = 0;
link->ka_announce_max_attempts = 0;
link->ka_fail_count = 0;
/* inflight_lim_bytes set above */
link->bandwidth = 10000; // начальная оценка 10 Mbps для шейпера
link->burst_id = 0;
link->burst_active = 0;
@@ -1141,10 +1140,12 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
while (l && l->next) l=l->next;
if (l) l->next = link; else etcp->links = link;
etcp_link_update_inflight_lim(link, link->inflight_lim_bytes);
etcp_update_mtu(etcp);
etcp_link_update_inflight_lim(link, link->bbr->init_cwnd * etcp->normalizer->frag_size);
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "NEW link initialized on etcp=[%s] link=%p socket=%s id=%d is_server=%d mtu=%d is_tcp=%d",
etcp->log_name, link, conn ? conn->name : "tcp", link->local_link_id, link->is_server, link->mtu, link->is_tcp);
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "NEW link etcp=[%s] link=%p socket=%s id=%u server=%u mtu=%u tcp=%u DATA_MSS=%u cwnd=%u",
etcp->log_name, link, conn ? conn->name : "tcp", link->local_link_id, link->is_server, link->mtu, link->is_tcp,
etcp->normalizer->frag_size, link->inflight_lim_bytes);
etcp_fire_link_status_cbk(link, -1, 0);
if (!is_tcp && is_server == 0) {
@@ -1155,10 +1156,13 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
return link;
}
// Установка нового лимита inflight с клампингом в [INFLIGHT_LIM_MIN, max_inflight] и уведомлением коннекта.
// Применить положительное окно DATA с верхним ограничением конфига; минимум выбирает BBR.
void etcp_link_update_inflight_lim(struct ETCP_LINK* link, uint32_t new_lim) {
if (!link || !link->etcp) return;
if (new_lim < INFLIGHT_LIM_MIN) new_lim = INFLIGHT_LIM_MIN;
if (!new_lim) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] link=%u rejected zero DATA window", link->etcp->log_name, link->local_link_id);
return;
}
if (new_lim > link->etcp->max_inflight) new_lim = link->etcp->max_inflight;
link->inflight_lim_bytes = new_lim;