Verify bounded global NAT pressure and retained destination across mapping reuse
This commit is contained in:
1 parent
8360e48622
commit
80b481827c
1 file changed
+44
-1
@@ -524,7 +524,8 @@ static int test_unexpected_nat_sender(int wrong_group) {
|
||||
|
||||
/* Первый входящий пакет по статическому пробросу ниже динамического диапазона доходит до заданного узла. */
|
||||
static int test_static_forward_delivery(void) {
|
||||
if (eim_nat_add_forward(&inst_provider->nat, IPPROTO_UDP_UINT8, 0x0a0000ce, htobe16(8081), 8080, g_client_node_id)) return 0;
|
||||
if (inst_provider->nat.table[8080].state == EIM_NAT_ENTRY_FREE &&
|
||||
eim_nat_add_forward(&inst_provider->nat, IPPROTO_UDP_UINT8, 0x0a0000ce, htobe16(8081), 8080, g_client_node_id)) return 0;
|
||||
size_t len;
|
||||
uint8_t* packet = build_udp_pkt(0x08080808, 53, inst_provider->nat.gateway_ip, 8080, &len);
|
||||
test_state.capture_count = 0; test_state.captured_len = 0;
|
||||
@@ -730,6 +731,47 @@ static int test_slow_peer_and_shutdown(void) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Общий предел останавливает TUN. После освобождения места адресат и уже преобразованный IP сохраняются. */
|
||||
static int test_global_backpressure(void) {
|
||||
const uint64_t base = UINT64_C(0x8000000010000000);
|
||||
size_t len;
|
||||
for (uint32_t peer = 0; peer <= NAT_PENDING_TOTAL / NAT_PENDING_PER_PEER; peer++) {
|
||||
uint16_t external = 1000 + peer;
|
||||
if (eim_nat_add_forward(&inst_provider->nat, IPPROTO_UDP_UINT8, 0x0a000100 + peer, htobe16(5000), external, base + peer)) return 0;
|
||||
uint8_t* packet = build_udp_pkt(0x08080808, 53, inst_provider->nat.gateway_ip, external, &len);
|
||||
unsigned int count = peer < NAT_PENDING_TOTAL / NAT_PENDING_PER_PEER ? ROUTER_MAX_SEND_Q_PACKETS + NAT_PENDING_PER_PEER : 1;
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
if (tun_inject_packet(inst_provider->nat_tr.nat_tun, packet, len)) { free(packet); return 0; }
|
||||
}
|
||||
free(packet);
|
||||
}
|
||||
struct nat_transport_ctx* tr = &inst_provider->nat_tr;
|
||||
int ok = tr->pending_count == NAT_PENDING_TOTAL && tr->blocked_packet && queue_entry_count(tr->nat_tun->output_queue) == 1;
|
||||
uint64_t saved_destination = tr->blocked_destination;
|
||||
uint16_t external = 1000 + NAT_PENDING_TOTAL / NAT_PENDING_PER_PEER;
|
||||
if (eim_nat_remove(&inst_provider->nat, external) != 1 ||
|
||||
eim_nat_add_forward(&inst_provider->nat, IPPROTO_UDP_UINT8, 0x0a000099, htobe16(9999), external, 0xabcdef)) ok = 0;
|
||||
struct ETCP_ROUTER_CONN* route = etcp_router_conn_get(inst_provider, TOPO_GROUP_UTUN, base, ETCP_RT_ID_NAT);
|
||||
struct ll_entry* consumed = queue_data_get(route->send_q); // Освободить один слот, вызвав реальный producer waiter.
|
||||
if (!consumed) ok = 0;
|
||||
else { queue_dgram_free(consumed); queue_entry_free(consumed); }
|
||||
queue_resume_callback(route->send_q);
|
||||
for (int cycles = 0; cycles < 20 && tr->blocked_packet; cycles++) uasync_poll(ua, 0);
|
||||
if (tr->blocked_packet || queue_entry_count(tr->nat_tun->output_queue) || tr->pending_count >= NAT_PENDING_TOTAL) ok = 0;
|
||||
struct ETCP_ROUTER_CONN* resumed = etcp_router_conn_get(inst_provider, TOPO_GROUP_UTUN, saved_destination, ETCP_RT_ID_NAT);
|
||||
if (!resumed || !resumed->send_q->head || resumed->send_q->head->len != 42) ok = 0;
|
||||
else {
|
||||
uint32_t destination; memcpy(&destination, resumed->send_q->head->dgram + 16, 4);
|
||||
if (destination != htobe32(0x0a000100 + NAT_PENDING_TOTAL / NAT_PENDING_PER_PEER)) ok = 0;
|
||||
}
|
||||
nat_transport_destroy(inst_provider);
|
||||
uasync_poll(ua, 0);
|
||||
if (inst_provider->nat_tr.initialized || inst_provider->nat_tr.pending_count) ok = 0;
|
||||
if (ok) DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS global NAT backpressure: bounded at 1024, TUN pause/resume, mapping reuse and pending shutdown");
|
||||
else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL global NAT backpressure");
|
||||
return ok;
|
||||
}
|
||||
|
||||
// ==================== Main ====================
|
||||
int main(void) {
|
||||
int test_result = 1;
|
||||
@@ -809,6 +851,7 @@ int main(void) {
|
||||
total++; if (test_tun_write_backpressure()) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: tun_write_backpressure");
|
||||
#endif
|
||||
total++; if (test_slow_peer_and_shutdown()) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: slow_peer_shutdown");
|
||||
total++; if (test_global_backpressure()) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: global_backpressure");
|
||||
|
||||
printf("\n=== NAT Transport Tests: %d/%d passed ===\n", passed, total);
|
||||
test_result = (passed == total) ? 0 : 1;
|
||||
|
||||
Reference in new issue
Block a user