Refresh RTO before RTT callbacks can close the link

This commit is contained in:
evgeny committed 2026-10-24 17:26:59 +02:00
1 parent f00d67ca3c
commit 5420a07ffc
3 files changed
+16 -7

No files matched your search

+2 -2
View File
@@ -1466,14 +1466,14 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
etcp->rtt_avg_10=rtt_max;
etcp->tt_last=tt_sum/cnt;
etcp->jitter=j_sum/cnt;
if (etcp->rtt_last) {
if (new_rtt != prev_rtt) etcp_tx_update_rto(pkt->link);
if (!etcp->close_requested && etcp->rtt_last) {
uint64_t now_tb = get_time_tb();
if (now_tb - etcp->last_rtt_cb_time > RTT_CB_PERIOD_TB) {
topo_node_ping_update_rtt(etcp->instance->topo_groups, etcp->peer_node_id, etcp->rtt_last);
etcp->last_rtt_cb_time = now_tb;
}
}
if (new_rtt != prev_rtt) etcp_tx_update_rto(pkt->link);
break;
}
case ETCP_SECTION_PAYLOAD: {
+2 -1
View File
@@ -1083,7 +1083,8 @@ test_etcp_windows_LDADD = $(LIBUTUN) $(COMMON_LIBS)
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
-Wl,--wrap=u_malloc_impl -Wl,--wrap=u_calloc_impl -Wl,--wrap=u_realloc_impl -Wl,--wrap=random_bytes \
-Wl,--wrap=topo_node_ping_update_rtt
test_etcp_router_tcp_SOURCES = test_etcp_router_tcp.c
test_etcp_router_tcp_LDADD = $(LIBUTUN) $(COMMON_LIBS)
+12 -4
View File
@@ -21,6 +21,7 @@ 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 unsigned fail_shaper_timer;
static unsigned fail_rto_timer;
static unsigned close_rtt_callback;
static unsigned pacer_clock_active, capture_shaper, shaper_arm_count, pacer_ready_count, pacer_ready_action;
static uint64_t pacer_now_tb;
static int captured_shaper_delay;
@@ -49,6 +50,12 @@ uint64_t __wrap_get_time_tb(void) {
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_topo_node_ping_update_rtt(struct TOPO_GROUPS*, uint64_t, uint16_t);
void __wrap_topo_node_ping_update_rtt(struct TOPO_GROUPS* groups, uint64_t node_id, uint16_t rtt) {
if (close_rtt_callback) { close_rtt_callback = 0; etcp_connection_close(conn); return; }
__real_topo_node_ping_update_rtt(groups,node_id,rtt);
}
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; }
@@ -159,6 +166,7 @@ static void setup(void) {
sends = fail_alloc = fail_send = fail_tx_timer = bbr_calls = saw_cwnd_limited = saw_app_limited = 0;
fail_shaper_timer = 0;
fail_rto_timer = 0;
close_rtt_callback = 0;
pacer_clock_active = capture_shaper = shaper_arm_count = pacer_ready_count = pacer_ready_action = 0;
captured_shaper_delay = 0; captured_shaper_callback = NULL; captured_shaper_arg = NULL;
fail_rx_data = fail_rx_fragment = fail_ack_entry = 0;
@@ -770,9 +778,9 @@ static void rto_path_rtt_growth(void) {
teardown();
}
/* Timestamp сокращает срок без новых DATA/ACK; OOM пересчёта безопасно закрывает conn внутри RX. */
/* Timestamp сокращает срок без DATA/ACK; проверяем OOM и close из уведомления RTT внутри RX. */
static void rto_timestamp_rearm(void) {
for (unsigned oom = 0; oom < 2; oom++) {
for (unsigned mode = 0; mode < 3; mode++) {
setup(); b->link_status = 0; a->data_rtt_us = 20000; a->rtt_last = 1000;
ack_now_us = get_time_us(); ack_clock_active = 1;
fill(a,1,1000);
@@ -782,9 +790,9 @@ static void rto_timestamp_rearm(void) {
pkt->link = a; pkt->data_len = 5; memset(pkt->data,0,5); pkt->data[0] = ETCP_SECTION_TIMESTAMP;
uint16_t ret = get_current_timestamp()-200;
pkt->data[1] = ret; pkt->data[2] = ret>>8;
fail_rto_timer = oom;
fail_rto_timer = mode == 1; close_rtt_callback = mode == 2;
etcp_conn_input(pkt);
if (oom) CHECK(conn->close_requested && !conn->callbacks_running && !fail_rto_timer);
if (mode) CHECK(conn->close_requested && !conn->callbacks_running && !fail_rto_timer && !close_rtt_callback);
else {
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Timestamp RTO rearm: RTO_us=%u old_deadline=%llu new_deadline=%llu expected=%llu",
etcp_tx_rto_us(a),(unsigned long long)old_deadline,(unsigned long long)a->retrans_deadline_us,