Restrict NAT delivery to its group and configured provider
This commit is contained in:
1 parent
909005c1a4
commit
bfa23afae9
3 files changed
+32
No files matched your search
@@ -111,6 +111,14 @@ static void nat_transport_etcp_recv_cb(struct ETCP_CONN* conn, struct ll_entry*
|
||||
|
||||
uint64_t src_node_id;
|
||||
memcpy(&src_node_id, entry->dgram + ROUTER_SVC_SRC_OFF, 8);
|
||||
uint64_t group_id;
|
||||
memcpy(&group_id, entry->dgram + ROUTER_SVC_GROUP_OFF, 8);
|
||||
if (group_id != TOPO_GROUP_UTUN || (tr->nat_via_node_id && src_node_id != tr->nat_via_node_id)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_NAT, "NAT receive rejected: group=%016llx source=%016llx configured_provider=%016llx",
|
||||
(unsigned long long)group_id, (unsigned long long)src_node_id, (unsigned long long)tr->nat_via_node_id);
|
||||
queue_dgram_free(entry); queue_entry_free(entry);
|
||||
return;
|
||||
}
|
||||
uint8_t* ip_data = entry->dgram + ROUTER_SVC_PAYLOAD_OFF;
|
||||
size_t ip_len = entry->len - ROUTER_SVC_PAYLOAD_OFF;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* IPv4 NAT через отдельный TUN и сервис ETCP_RT_ID_NAT в UTUN-router.
|
||||
* nat_via_node_id задаёт удалённого провайдера; при 0 узел сам выполняет eim_nat для клиентов.
|
||||
* Приём ограничен группой UTUN; клиент принимает ответы только от настроенного провайдера.
|
||||
* init создаёт TUN/обработчики по nat_enabled; destroy снимает их и освобождает ресурсы.
|
||||
* Контекст принадлежит UTUN_INSTANCE; очереди и callbacks работают в uasync. */
|
||||
#ifndef NAT_TRANSPORT_H
|
||||
|
||||
@@ -496,6 +496,27 @@ static int test_send_failure_ownership(int provider) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Loopback проходит реальный router API: клиент не принимает IP от постороннего узла/группы. */
|
||||
static int test_unexpected_nat_sender(int wrong_group) {
|
||||
size_t len;
|
||||
uint8_t* packet = build_udp_pkt(0x08080808, 53, 0x0a0000cd, 44444, &len);
|
||||
struct ll_entry* entry = ll_alloc_lldgram((uint16_t)(len + 1));
|
||||
if (!entry) { free(packet); DEBUG_ERROR(DEBUG_CATEGORY_NAT, "NAT sender test allocation failed"); return 0; }
|
||||
entry->dgram[0] = ETCP_RT_ID_NAT; memcpy(entry->dgram + 1, packet, len); entry->len = len + 1;
|
||||
free(packet);
|
||||
uint64_t saved_provider = inst_client->nat_tr.nat_via_node_id;
|
||||
if (wrong_group) inst_client->nat_tr.nat_via_node_id = g_client_node_id;
|
||||
int r = etcp_route_send(inst_client, wrong_group ? 1234 : TOPO_GROUP_UTUN, g_client_node_id, entry, 0, 0);
|
||||
inst_client->nat_tr.nat_via_node_id = saved_provider;
|
||||
test_state.captured_len = 0; test_state.capture_count = 0;
|
||||
capture_tun_read(inst_client->nat_tr.nat_tun);
|
||||
int ok = r == 0 && !test_state.capture_count;
|
||||
if (ok) DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS NAT client rejects unexpected %s", wrong_group ? "group" : "sender");
|
||||
else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL NAT client accepted unexpected %s: result=%d captured=%d",
|
||||
wrong_group ? "group" : "sender", r, test_state.capture_count);
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* Первый входящий пакет по статическому пробросу ниже динамического диапазона доходит до заданного узла. */
|
||||
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;
|
||||
@@ -656,6 +677,8 @@ int main(void) {
|
||||
total++; if (test_send_failure_ownership(0)) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: client send ownership");
|
||||
total++; if (test_send_failure_ownership(1)) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: provider send ownership");
|
||||
#endif
|
||||
total++; if (test_unexpected_nat_sender(0)) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: unexpected_sender");
|
||||
total++; if (test_unexpected_nat_sender(1)) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: unexpected_group");
|
||||
// Реальная доставка после инъекций проверяет восстановление обеих веток без перезапуска NAT.
|
||||
total++; if (test_full_roundtrip()) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: full_roundtrip");
|
||||
total++; if (test_static_forward_delivery()) passed++; else DEBUG_ERROR(DEBUG_CATEGORY_NAT, "FAIL: static_forward");
|
||||
|
||||
Reference in new issue
Block a user