Reproduce premature ACKs before their absolute deadline
This commit is contained in:
1 parent
2b74d2bf4f
commit
c8051619c1
2 files changed
+31
-2
No files matched your search
+2
-1
@@ -1056,7 +1056,8 @@ test_etcp_multipath_LDFLAGS = $(test_clock_ldflags) -Wl,--wrap=etcp_dump_pkt_sec
|
||||
test_stcp_sigpipe_SOURCES = test_stcp_sigpipe.c
|
||||
test_stcp_sigpipe_LDADD = $(LIBUTUN) $(COMMON_LIBS)
|
||||
test_etcp_windows_LDADD = $(LIBUTUN) $(COMMON_LIBS)
|
||||
test_etcp_windows_LDFLAGS = $(test_clock_ldflags) -Wl,--wrap=get_time_tb -Wl,--wrap=etcp_encrypt_send -Wl,--wrap=memory_pool_alloc_impl \
|
||||
test_etcp_windows_LDFLAGS = $(test_clock_ldflags) -Wl,--wrap=get_time_tb -Wl,--wrap=get_time_us \
|
||||
-Wl,--wrap=etcp_encrypt_send -Wl,--wrap=memory_pool_alloc_impl \
|
||||
-Wl,--wrap=bbr_main -Wl,--wrap=uasync_set_timeout -Wl,--wrap=uasync_call_soon -Wl,--wrap=ll_alloc_lldgram \
|
||||
-Wl,--wrap=u_malloc_impl -Wl,--wrap=u_calloc_impl -Wl,--wrap=u_realloc_impl -Wl,--wrap=random_bytes
|
||||
|
||||
|
||||
@@ -33,13 +33,21 @@ static uint32_t last_mss;
|
||||
static unsigned fail_rx_message_at, fail_tx_inflight, fail_normalizer_timer, fail_normalizer_waiter, fail_session_timer_at;
|
||||
static unsigned no_alloc, unexpected_alloc, fail_rng, session_sends, received, receive_action;
|
||||
static uint8_t received_values[8];
|
||||
static unsigned ack_clock_active, capture_ack_timer, fail_ack_timer;
|
||||
static uint64_t ack_now_us;
|
||||
static timeout_callback_t captured_ack_callback;
|
||||
static void* captured_ack_arg;
|
||||
|
||||
/* Фиксируем только TB на время синхронной проверки pacer; uasync при этих часах не опрашивается. */
|
||||
uint64_t __real_get_time_tb(void);
|
||||
uint64_t __wrap_get_time_tb(void) {
|
||||
if (ack_clock_active) return ack_now_us / 100;
|
||||
return pacer_clock_active ? pacer_now_tb : __real_get_time_tb();
|
||||
}
|
||||
|
||||
uint64_t __real_get_time_us(void);
|
||||
uint64_t __wrap_get_time_us(void) { return ack_clock_active ? ack_now_us : __real_get_time_us(); }
|
||||
|
||||
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) {
|
||||
if (fail_normalizer_timer && conn && arg == conn->normalizer) { fail_normalizer_timer--; return NULL; }
|
||||
@@ -52,6 +60,8 @@ void* __wrap_uasync_call_soon(struct UASYNC* loop, void* arg, timeout_callback_t
|
||||
|
||||
void* __real_uasync_set_timeout(struct UASYNC*, int, void*, timeout_callback_t, const char*);
|
||||
void* __wrap_uasync_set_timeout(struct UASYNC* loop, int delay, void* arg, timeout_callback_t callback, const char* name) {
|
||||
if (capture_ack_timer && !strcmp(name, "etcp_ack_resp")) { captured_ack_callback = callback; captured_ack_arg = arg; }
|
||||
if (fail_ack_timer && !strcmp(name, "etcp_ack_resp")) { fail_ack_timer--; return NULL; }
|
||||
if (capture_shaper && name && !strcmp(name, "etcp_shaper")) {
|
||||
shaper_arm_count++; captured_shaper_delay = delay;
|
||||
captured_shaper_callback = callback; captured_shaper_arg = arg;
|
||||
@@ -152,6 +162,8 @@ static void setup(void) {
|
||||
fail_rx_message_at = fail_tx_inflight = fail_normalizer_timer = fail_normalizer_waiter = fail_session_timer_at = 0;
|
||||
no_alloc = unexpected_alloc = fail_rng = session_sends = received = receive_action = 0;
|
||||
memset(received_values, 0, sizeof(received_values));
|
||||
ack_clock_active = capture_ack_timer = fail_ack_timer = 0;
|
||||
captured_ack_callback = NULL; captured_ack_arg = NULL;
|
||||
last_sent_link = NULL; last_sent_request = last_sent_payload = 0;
|
||||
ua = uasync_create(); CHECK(ua);
|
||||
inst.ua = ua; inst.node_id = 1; inst.config = &cfg; cfg.global.bbr_max_cwnd = INFLIGHT_LIM_MAX;
|
||||
@@ -175,6 +187,7 @@ static void setup(void) {
|
||||
}
|
||||
|
||||
static void teardown(void) {
|
||||
ack_clock_active = 0;
|
||||
check_accounting();
|
||||
etcp_connection_close(conn); conn = NULL;
|
||||
uasync_poll(ua, 0);
|
||||
@@ -1124,6 +1137,21 @@ static void independent_attempt_acks(void) {
|
||||
check_accounting(); teardown();
|
||||
}
|
||||
|
||||
/* Посторонний wake не снимает задержку ACK; точные границы проверяются без опроса uasync при ручных часах. */
|
||||
static void ack_absolute_deadline(void) {
|
||||
setup(); conn->got_initial_pkt = 1;
|
||||
ack_now_us = get_time_us(); ack_clock_active = capture_ack_timer = 1;
|
||||
receive_fragment(a, 2, 1); CHECK(a->ack_q->count == 1 && conn->ack_resp_timer);
|
||||
etcp_conn_wake_sender(conn);
|
||||
struct ETCP_DGRAM* pkt = request();
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "ACK deadline: age_us=0 queued=%d sent_early=%u", a->ack_q->count, pkt != NULL);
|
||||
CHECK(!pkt && a->ack_q->count == 1);
|
||||
ack_now_us += 1999; CHECK(!request() && a->ack_q->count == 1);
|
||||
ack_now_us++; pkt = request(); CHECK(pkt && pkt->link == a && pkt->data[1] == 1);
|
||||
memory_pool_free(inst.pkt_pool, pkt); CHECK(!a->ack_q->count && !conn->ack_resp_timer);
|
||||
teardown();
|
||||
}
|
||||
|
||||
static void receive_admission_and_path_acks(void) {
|
||||
setup(); conn->got_initial_pkt = 1;
|
||||
fail_rx_data = 1; receive_fragment(a, 2, 1);
|
||||
@@ -1545,7 +1573,7 @@ int main(void) {
|
||||
retry_waits_for_alternative, retry_alternative_lifecycle,
|
||||
send_queue_scan, send_queue_input_admission,
|
||||
retry_full_round_history, retry_history_slot_reuse, fast_stall_progress, stalled_retry_selection, input_admission_callbacks,
|
||||
receive_admission_and_path_acks, peer_window_queries, pacing_continuity, pacing_data_units, attempt_memory_limits,
|
||||
ack_absolute_deadline, receive_admission_and_path_acks, peer_window_queries, pacing_continuity, pacing_data_units, attempt_memory_limits,
|
||||
normalizer_rx_oom, normalizer_tx_oom, normalizer_callback_abort, reset_without_allocation, restart_allocation_failures,
|
||||
receiver_bandwidth_bounds, receiver_point_lifecycle, receiver_point_wire, receiver_point_truncated,
|
||||
compact_attempt_identity, compact_attempt_exhaustion, compact_sequence_exhaustion,
|
||||
|
||||
Reference in new issue
Block a user