From 0f23076f48c23e105b9fdc3320b0eb5e71dce49a Mon Sep 17 00:00:00 2001 From: evgeny Date: Fri, 23 Oct 2026 00:42:45 +0200 Subject: [PATCH] Apply BBR DATA windows consistently during startup and RTT probes --- src/transport_layer/etcp.c | 3 ++- src/transport_layer/etcp_bbr.c | 17 +++++++++-------- src/transport_layer/etcp_connections.c | 24 ++++++++++++++---------- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/transport_layer/etcp.c b/src/transport_layer/etcp.c index 77f0326c..9d80fc62 100644 --- a/src/transport_layer/etcp.c +++ b/src/transport_layer/etcp.c @@ -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); diff --git a/src/transport_layer/etcp_bbr.c b/src/transport_layer/etcp_bbr.c index e0f580d9..cdbd6c65 100644 --- a/src/transport_layer/etcp_bbr.c +++ b/src/transport_layer/etcp_bbr.c @@ -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; diff --git a/src/transport_layer/etcp_connections.c b/src/transport_layer/etcp_connections.c index e39c222a..9d683cb4 100644 --- a/src/transport_layer/etcp_connections.c +++ b/src/transport_layer/etcp_connections.c @@ -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;