From 72f48d1f145baea61f97f2ea40bc979f1462b16a Mon Sep 17 00:00:00 2001 From: evgeny Date: Fri, 23 Oct 2026 10:59:30 +0200 Subject: [PATCH] Keep DATA pacing units consistent and test startup delay exit --- src/transport_layer/etcp_loadbalancer.c | 6 +---- tests/test_etcp_bbr.c | 31 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/transport_layer/etcp_loadbalancer.c b/src/transport_layer/etcp_loadbalancer.c index 60ad3270..0c60de36 100644 --- a/src/transport_layer/etcp_loadbalancer.c +++ b/src/transport_layer/etcp_loadbalancer.c @@ -103,10 +103,6 @@ int etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) { } struct ETCP_LINK* link = dgram->link; - size_t pkt_size = dgram->data_len + sizeof(uint16_t); // Include timestamp - -// DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] sending dgram on link=%p, size=%zu", etcp->log_name, link, pkt_size); - // Encrypt and send (from etcp_connections.c) int send_result = etcp_encrypt_send(dgram); etcp_tx_complete(dgram, send_result >= 0); @@ -130,7 +126,7 @@ int etcp_loadbalancer_send(struct ETCP_DGRAM* dgram) { link->shaper_load_time_tb = now_tb - SHAPER_BURST_DELAY_TB; link->shaper_sub_nanotime = 0; } // Ставка B/s; SUB_MODULO соответствует 0.1мс, один sub равен 0.1нс. - uint64_t tx_sub = ((uint64_t)pkt_size * 10000000000ULL + link->bbr_pacing_rate - 1) / link->bbr_pacing_rate; + uint64_t tx_sub = ((uint64_t)dgram->payload_len * 10000000000ULL + link->bbr_pacing_rate - 1) / link->bbr_pacing_rate; // Add to load link->shaper_sub_nanotime += tx_sub; diff --git a/tests/test_etcp_bbr.c b/tests/test_etcp_bbr.c index 53f2c1a9..c3fb741a 100644 --- a/tests/test_etcp_bbr.c +++ b/tests/test_etcp_bbr.c @@ -380,6 +380,36 @@ static int test_initial_pacing(void) { PASS(); return 0; } +/* Один всплеск очереди не завершает разгон; целый раунд выше бюджета завершает, не меняя BW искусственно. */ +static int test_startup_delay_exit(void) { + MSEG("STARTUP delay exit requires an entire elevated RTT round"); + for (unsigned enabled = 0; enabled < 2; enabled++) { + struct bbr s = { .now_tb = 10000 }; bbr_init(&s); + s.queue_budget_us = enabled ? 20000 : 0; + s.min_rtt_us = s.probe_rtt_min_us = 200000; s.has_seen_rtt = 1; + uint32_t cwnd = 400000, pacing = 2000000; + struct bbr_rate_sample rs = { .acked_sacked = 1000, .delivered = 100000, .interval_us = 100000, + .rtt_us = 219000, .tx_in_flight = 400000 }; + bbr_main(&s, &rs, &cwnd, &pacing, 1000, 399000, 1); + rs.rtt_us = 250000; + bbr_main(&s, &rs, &cwnd, &pacing, 1000, 399000, 1); + rs.prior_delivered = s.delivered; + bbr_main(&s, &rs, &cwnd, &pacing, 1000, 399000, 1); + if (s.mode != BBR_STARTUP) FAIL("one high RTT must not override a round minimum below the budget"); + rs.rtt_us = 0; + bbr_main(&s, &rs, &cwnd, &pacing, 1000, 399000, 1); + if (s.mode != BBR_STARTUP) FAIL("incomplete RTT round must not terminate startup"); + rs.prior_delivered = s.delivered; + bbr_main(&s, &rs, &cwnd, &pacing, 1000, 399000, 1); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "BBR STARTUP delay: enabled=%u mode=%u full_bw=%u pace=%u", + enabled, s.mode, s.full_bw_reached, pacing); + if (enabled && (s.mode != BBR_DRAIN || !s.full_bw_reached || pacing >= 1000000)) + FAIL("sustained queue must enter DRAIN using the measured bandwidth"); + if (!enabled && s.mode != BBR_STARTUP) FAIL("disabled delay budget must preserve bandwidth-based startup"); + } + PASS(); return 0; +} + int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR); debug_set_category_level(DEBUG_CATEGORY_DEBUG, DEBUG_LEVEL_INFO); @@ -402,6 +432,7 @@ int main(void) test_queue_budget_floor_and_startup(); test_queue_budget_fast_path(); test_initial_pacing(); + test_startup_delay_exit(); printf("\n=== Results: %d/%d passed, %d failed ===\n", test_passed, test_total, test_failed); return test_failed ? 1 : 0; }