Reproduce inflated delivery-rate samples when ACKs arrive together

This commit is contained in:
evgeny committed 2026-10-23 00:05:48 +02:00
1 parent 3c38072b9b
commit c2f4f048d7
1 file changed
+22 -1
+22 -1
View File
@@ -17,6 +17,7 @@ static struct utun_config cfg;
static struct ETCP_CONN* conn;
static struct ETCP_LINK *a, *b;
static unsigned sends, fail_alloc, fail_send, fail_tx_timer, bbr_calls, saw_cwnd_limited, saw_app_limited;
static struct bbr_rate_sample last_sample;
void* __real_uasync_call_soon(struct UASYNC*, void*, timeout_callback_t);
void* __wrap_uasync_call_soon(struct UASYNC* loop, void* arg, timeout_callback_t callback) {
@@ -47,6 +48,7 @@ void __real_bbr_main(struct bbr*, const struct bbr_rate_sample*, uint32_t*, uint
void __wrap_bbr_main(struct bbr* model, const struct bbr_rate_sample* sample, uint32_t* cwnd,
uint32_t* pacing, uint32_t mss, uint32_t inflight, int limited) {
bbr_calls++; saw_cwnd_limited |= !!limited; saw_app_limited |= !!sample->is_app_limited;
last_sample = *sample;
__real_bbr_main(model, sample, cwnd, pacing, mss, inflight, limited);
}
@@ -323,6 +325,25 @@ static void ack_without_data_pacing(void) {
etcp_conn_wake_sender(conn); wait_sends(2); ack_all(); teardown();
}
/* ACK одной пачки приходят в один tick: скорость определяется доставкой всей группы, а не промежутком между ACK. */
static void bbr_delivery_clock(void) {
setup(); b->link_status = 0;
a->bbr = u_calloc(1, sizeof(*a->bbr)); CHECK(a->bbr); bbr_init(a->bbr);
fill(a, 8, 1000);
uint64_t sent_tb = get_time_tb();
test_clock_run_for(ua, 200);
for (unsigned seq = 1; seq <= 8; seq++) {
ack(seq);
uint64_t elapsed_us = (get_time_tb() - sent_tb) * 100;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Delivery sample: seq=%u delivered=%u acked=%u interval_us=%u flight_us=%llu",
seq, last_sample.delivered, last_sample.acked_sacked, last_sample.interval_us, (unsigned long long)elapsed_us);
CHECK(last_sample.delivered == seq * 1000 && last_sample.acked_sacked == 1000);
CHECK(last_sample.interval_us >= 19000 && last_sample.interval_us <= elapsed_us + 1000);
}
CHECK(a->bbr->delivered == 8000);
teardown();
}
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_ERROR);
if (getenv("UTUN_TEST_DEBUG")) debug_set_category_level(DEBUG_CATEGORY_ETCP, DEBUG_LEVEL_DEBUG);
@@ -330,7 +351,7 @@ int main(void) {
size_t baseline = u_get_allocated_count();
void (*cases[])(void) = {selection, boundaries_ack_burst, late_ack_and_migration, lost_ack_and_shrink,
grow_and_session, allocation_and_send_failure, removed_link_and_bbr, pacing_reset_close, initial_readiness,
config_limits, timer_failure, immediate_send, ack_without_data_pacing};
config_limits, timer_failure, immediate_send, ack_without_data_pacing, bbr_delivery_clock};
for (unsigned i = 0; i < sizeof(cases) / sizeof(cases[0]); i++) {
cases[i](); CHECK(u_get_allocated_count() == baseline);
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS ETCP window scenario %u", i);