Cover INIT liveness with an independent healthy link

This commit is contained in:
evgeny committed 2026-10-23 14:01:57 +02:00
1 parent b167a27e85
commit c5f743a09d
1 file changed
+27 -1
+27 -1
View File
@@ -123,7 +123,10 @@ static void setup(unsigned swapped, unsigned count) {
static void teardown(void) {
close_action = 0;
etcp_conn_ref_free(ep[1].conn);
for (unsigned side = 0; side < 2; side++) utun_instance_destroy(ep[side].inst);
for (unsigned side = 0; side < 2; side++) {
etcp_remove_link_status_cbk(ep[side].inst, link_event, &ep[side]);
utun_instance_destroy(ep[side].inst);
}
uasync_poll(ua, 0);
CHECK(ua->timer_alloc_count == ua->timer_free_count);
uasync_destroy(ua, 0);
@@ -160,6 +163,28 @@ static void close_in_callback(unsigned action) {
teardown();
}
/* INIT на неработающем пути не меняет доступность соединения с другим исправным линком. */
static void healthy_alternative(void) {
setup(0, 2);
struct ETCP_LINK* broken = first_link(0);
CHECK(broken->next && broken->link_status && broken->next->link_status);
ep[1].block_id = broken->remote_link_id;
run_for(15000); CHECK(!broken->link_status && ep[0].conn->links_up && ep[1].conn->links_up);
unsigned before = ep[0].init_zero;
etcp_link_enter_reinit(broken); run_for(5000);
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Alternative: INIT0=%u broken=%u role=%u state=%u up=%u/%u DOWN=%u/%u block_id=%u",
ep[0].init_zero - before, broken->link_status, broken->is_server, broken->link_state,
ep[0].conn->links_up, ep[1].conn->links_up, ep[0].down, ep[1].down, ep[1].block_id);
/* При исправном обходном пути таймер подавляет повторы INIT; первый запрос всё равно принимается. */
CHECK(ep[0].init_zero == before + 1 && !broken->link_status && !ep[0].down && !ep[1].down);
struct ll_entry* entry = ll_alloc_lldgram(2); CHECK(entry);
entry->len = 2; entry->dgram[0] = 253; entry->dgram[1] = 17;
CHECK(etcp_send(ep[0].conn, entry) == 0); run_for(1000); CHECK(ep[1].received == 1);
ep[1].block_id = 0; run_for(10000);
CHECK(broken->link_status && !ep[0].down && !ep[1].down && !ep[0].reinit && !ep[1].reinit);
teardown();
}
/* При отказе показать конкретные живые блоки вместо одного несовпавшего счётчика. */
static void check_memory(size_t baseline) {
if (u_get_allocated_count() == baseline) return;
@@ -179,6 +204,7 @@ int main(void) {
one_way(swapped, 1 - order); check_memory(baseline);
}
for (unsigned action = 1; action <= 2; action++) { close_in_callback(action); check_memory(baseline); }
healthy_alternative(); check_memory(baseline);
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS encrypted INIT liveness: cold start, one-way loss, repeated INIT, recovery and callback close");
test_clock_finish(); socket_platform_cleanup(); return 0;
}