etcp_router: корректный handshake/restart без таймаут-петли
- START на первом пакете сеанса (seq=0), гейт отправки до первого ACK - дедуп рестарта по payload init-пакета (ретрансмит START не триггерит рестарт) - RST переинициализирует только отправку (без CLOSE_ALL), дедуп повторных RST
This commit is contained in:
1 parent
232ad2de6b
commit
53bce51201
3 files changed
+107
-20
No files matched your search
@@ -672,7 +672,7 @@ static int pump_data(etcp_recv_fn recv_cb, struct UTUN_INSTANCE* inst,
|
||||
// ======================== Restart/session tests ========================
|
||||
|
||||
static int test_rst_flag(void) {
|
||||
TEST("RST flag — local state reset, service notified");
|
||||
TEST("RST flag — send-side restart, no service notify");
|
||||
struct UASYNC* ua; struct UTUN_INSTANCE inst; etcp_recv_fn recv_cb;
|
||||
SETUP();
|
||||
g_notify_count = 0;
|
||||
@@ -684,11 +684,13 @@ static int test_rst_flag(void) {
|
||||
|
||||
g_notify_count = 0;
|
||||
inject(recv_cb, &inst, TEST_REMOTE_NODE, TEST_SVC_ID, 0, NULL, 0, 1, ROUTER_FLAG_RST);
|
||||
if (g_notify_count != 1) FAIL("RST should notify service");
|
||||
if (g_notify_count != 0) FAIL("RST should NOT notify service");
|
||||
|
||||
struct ETCP_ROUTER_CONN* c = etcp_router_conn_get(&inst, TOPO_GROUP_UTUN, TEST_REMOTE_NODE, TEST_SVC_ID);
|
||||
if (!c) FAIL("rconn should still exist after reset");
|
||||
if (c->tx_seq != 0 || c->rx_seq != 0 || c->start_sent != 0) FAIL("rconn not reset by RST");
|
||||
if (c->tx_seq != 0 || c->start_sent != 0) FAIL("send side not reset by RST");
|
||||
if (c->rx_seq != (uint32_t)n) FAIL("rx side should be untouched by RST");
|
||||
if (!c->send_restart_pending) FAIL("send_restart_pending not set by RST");
|
||||
etcp_router_conn_close(c);
|
||||
|
||||
TEARDOWN();
|
||||
@@ -696,6 +698,29 @@ static int test_rst_flag(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_start_retransmit_no_restart(void) {
|
||||
TEST("START retransmit (same payload) — no restart");
|
||||
struct UASYNC* ua; struct UTUN_INSTANCE inst; etcp_recv_fn recv_cb;
|
||||
SETUP();
|
||||
g_notify_count = 0;
|
||||
|
||||
int n = rand() % 10 + 1;
|
||||
rx_reset(0xC1);
|
||||
pump_data(recv_cb, &inst, 0xC1, n, 0);
|
||||
if (rx.delivered != n) FAIL("initial pump failed");
|
||||
|
||||
g_notify_count = 0;
|
||||
// ретрансмит первого пакета (seq=0, START, тот же payload) — не должен рестартовать
|
||||
uint8_t data[] = { TEST_SVC_ID, 0xC1, 0 };
|
||||
inject(recv_cb, &inst, TEST_REMOTE_NODE, TEST_SVC_ID, 0, data + 1, 2, 0, ROUTER_FLAG_START);
|
||||
if (g_notify_count != 0) FAIL("START retransmit should NOT restart");
|
||||
if (rx.delivered != n) FAIL("duplicate START should not deliver");
|
||||
|
||||
TEARDOWN();
|
||||
PASS();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int test_client_restart(void) {
|
||||
TEST("client restart — START flag detected after random data");
|
||||
struct UASYNC* ua; struct UTUN_INSTANCE inst; etcp_recv_fn recv_cb;
|
||||
@@ -1157,6 +1182,7 @@ int main(void) {
|
||||
test_timestamp();
|
||||
test_conn_send_no_bgp();
|
||||
test_rst_flag();
|
||||
test_start_retransmit_no_restart();
|
||||
test_client_restart();
|
||||
test_sess_id_increment();
|
||||
test_server_reinit();
|
||||
|
||||
Reference in new issue
Block a user