test(nat): cover accepted UDP and TCP profiles and LAN exclusions
This commit is contained in:
1 parent
df2f6ff300
commit
094a8bb499
2 files changed
+50
-2
No files matched your search
+10
-1
@@ -5,6 +5,13 @@
|
|||||||
при обращении к разным IP и проходят ли к нему пакеты от незнакомого IP.
|
при обращении к разным IP и проходят ли к нему пакеты от незнакомого IP.
|
||||||
Проверяется именно сокет, через который работает приложение.
|
Проверяется именно сокет, через который работает приложение.
|
||||||
|
|
||||||
|
Есть быстрый путь без помощников: если рабочий сокет принял подключение
|
||||||
|
и локальный IP и фактический IP подключившегося узла публичные,
|
||||||
|
ему сразу ставится direct/open (UNCHANGED + OPEN). Это правило действует
|
||||||
|
для UDP и TCP, даже если с IP пира раньше уже был исходящий обмен.
|
||||||
|
Локальные подключения и SOCKS интернет-вход не подтверждают. Для TCP
|
||||||
|
фактический локальный IP должен совпадать с IP интерфейса сокета.
|
||||||
|
|
||||||
Нужны три узла: A проверяет себя, B наблюдает его внешний адрес,
|
Нужны три узла: A проверяет себя, B наблюдает его внешний адрес,
|
||||||
C помогает проверить входящие пакеты. Команды и результаты передаются
|
C помогает проверить входящие пакеты. Команды и результаты передаются
|
||||||
по уже работающей сети uTun, в том числе через TCP или промежуточные узлы.
|
по уже работающей сети uTun, в том числе через TCP или промежуточные узлы.
|
||||||
@@ -96,5 +103,7 @@ TCP-пира: по готовому защищённому соединению
|
|||||||
IP совпали — трансляция IP не обнаружена; отличаются — NAT есть, тип UNKNOWN.
|
IP совпали — трансляция IP не обнаружена; отличаются — NAT есть, тип UNKNOWN.
|
||||||
Порты при сравнении не учитываются. Публичный внешний IP сохраняется с портом 0:
|
Порты при сравнении не учитываются. Публичный внешний IP сохраняется с портом 0:
|
||||||
входящий порт неизвестен, поэтому NCD не использует эту запись для подключения.
|
входящий порт неизвестен, поэтому NCD не использует эту запись для подключения.
|
||||||
Тип NAT и доступность TCP-входа не проверяются. Через SOCKS внешний IP прокси
|
Активных проб типа NAT и TCP-входа нет; OPEN устанавливается по принятому
|
||||||
|
публичному подключению и сохраняется при последующих совпавших наблюдениях IP.
|
||||||
|
Через SOCKS внешний IP прокси
|
||||||
не записывается как собственный адрес.
|
не записывается как собственный адрес.
|
||||||
@@ -48,7 +48,41 @@ static void check_snapshot(struct UTUN_INSTANCE *owner, struct ETCP_SOCKET *sock
|
|||||||
sqlite3_finalize(statement);
|
sqlite3_finalize(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Один TCP-пир даёт только наличие NAT и IP:0; локальный IP сам по себе достаточен для NAT. */
|
/* Настоящий входящий UDP/STCP публикует direct/open только у получателя; LAN не подтверждает интернет-вход. */
|
||||||
|
static void test_incoming_connections(void) {
|
||||||
|
struct nat_fixture fixture; nat_fixture_init(&fixture);
|
||||||
|
const char *tcp_config = "[server:tcp]\naddr=127.0.0.2:0\ntype=public\ntransport=tcp\n";
|
||||||
|
struct UTUN_INSTANCE *client = nat_fixture_node(&fixture, "127.0.0.2", NULL, tcp_config);
|
||||||
|
struct UTUN_INSTANCE *server = nat_fixture_node(&fixture, "127.0.0.3", NULL,
|
||||||
|
"[server:tcp]\naddr=127.0.0.3:0\ntype=public\ntransport=tcp\n");
|
||||||
|
struct UTUN_INSTANCE *lan = nat_fixture_node(&fixture, "127.0.0.4", NULL,
|
||||||
|
"[server:tcp]\naddr=127.0.0.4:0\ntype=public\ntransport=tcp\n");
|
||||||
|
nat_detection_set_automatic(client->nat_det, 0); nat_detection_set_automatic(server->nat_det, 0);
|
||||||
|
nat_detection_set_automatic(lan->nat_det, 0); nat_detection_set_allow_local(lan->nat_det, 0);
|
||||||
|
struct ETCP_SOCKET *udp = test_etcp_bound_socket(server, "udp"), *tcp = test_etcp_bound_socket(server, "tcp");
|
||||||
|
nat_fixture_connect(&fixture, client, "udp", server);
|
||||||
|
assert(udp->address_profile.mapping == ADDRESS_MAP_UNCHANGED && udp->address_profile.inbound == ADDRESS_IN_OPEN);
|
||||||
|
assert(test_etcp_bound_socket(client, "udp")->address_profile.inbound == ADDRESS_IN_UNKNOWN);
|
||||||
|
check_snapshot(server, udp);
|
||||||
|
nat_fixture_connect(&fixture, client, "tcp", server);
|
||||||
|
assert(tcp->address_profile.mapping == ADDRESS_MAP_UNCHANGED && tcp->address_profile.inbound == ADDRESS_IN_OPEN);
|
||||||
|
assert(route_ping_addr_equal(&tcp->nat_addr, &tcp->interface_addr, 0));
|
||||||
|
assert(!((struct sockaddr_in *)&tcp->nat_addr)->sin_port);
|
||||||
|
assert(test_etcp_bound_socket(client, "tcp")->address_profile.inbound == ADDRESS_IN_UNKNOWN);
|
||||||
|
check_snapshot(server, tcp);
|
||||||
|
/* Отчёт пира уже принят по настоящему TCP: OPEN у listener сохранён, исходящий порт остаётся нулём. */
|
||||||
|
struct nat_check_status status;
|
||||||
|
assert(!nat_detection_get_status(server->nat_det, tcp, &status) && !status.rounds && !status.helper && !status.reason);
|
||||||
|
nat_fixture_connect(&fixture, client, "udp", lan);
|
||||||
|
nat_fixture_connect(&fixture, client, "tcp", lan);
|
||||||
|
assert(test_etcp_bound_socket(lan, "udp")->address_profile.inbound == ADDRESS_IN_UNKNOWN);
|
||||||
|
assert(test_etcp_bound_socket(lan, "tcp")->address_profile.inbound == ADDRESS_IN_UNKNOWN);
|
||||||
|
assert(tcp->address_profile.inbound == ADDRESS_IN_OPEN && udp->address_profile.inbound == ADDRESS_IN_OPEN);
|
||||||
|
nat_fixture_cleanup(&fixture);
|
||||||
|
DEBUG_INFO(DEBUG_CATEGORY_NAT, "PASS incoming UDP/TCP: receiving socket DIRECT/OPEN, outbound unchanged, IP:0, signed profile, LAN ignored");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Исходящий TCP даёт только наличие NAT и IP:0; локальный IP сам по себе достаточен для NAT. */
|
||||||
static void test_tcp_presence(void) {
|
static void test_tcp_presence(void) {
|
||||||
struct nat_fixture fixture; nat_fixture_init(&fixture);
|
struct nat_fixture fixture; nat_fixture_init(&fixture);
|
||||||
struct UTUN_INSTANCE *owner = nat_fixture_node(&fixture, "127.0.0.2", NULL,
|
struct UTUN_INSTANCE *owner = nat_fixture_node(&fixture, "127.0.0.2", NULL,
|
||||||
@@ -249,6 +283,10 @@ int main(void) {
|
|||||||
nat_fixture_connect(&fixture, observer, "udp", owner);
|
nat_fixture_connect(&fixture, observer, "udp", owner);
|
||||||
owner->ntp.reachable = 0; /* ни измерение, ни публикация не требуют интернет-NTP */
|
owner->ntp.reachable = 0; /* ни измерение, ни публикация не требуют интернет-NTP */
|
||||||
nat_detection_request_check_all(owner->nat_det);
|
nat_detection_request_check_all(owner->nat_det);
|
||||||
|
struct nat_check_status initial_status;
|
||||||
|
uint64_t initial_end = get_time_tb() + 180000;
|
||||||
|
do { uasync_poll(fixture.ua, 10); assert(!nat_detection_get_status(owner->nat_det, socket, &initial_status)); }
|
||||||
|
while (get_time_tb() < initial_end && (!initial_status.rounds || initial_status.phase || initial_status.cycling));
|
||||||
wait_profile(&fixture, socket, ADDRESS_MAP_UNCHANGED, ADDRESS_IN_OPEN);
|
wait_profile(&fixture, socket, ADDRESS_MAP_UNCHANGED, ADDRESS_IN_OPEN);
|
||||||
wait_profile(&fixture, second_socket, ADDRESS_MAP_UNCHANGED, ADDRESS_IN_OPEN);
|
wait_profile(&fixture, second_socket, ADDRESS_MAP_UNCHANGED, ADDRESS_IN_OPEN);
|
||||||
|
|
||||||
@@ -302,5 +340,6 @@ int main(void) {
|
|||||||
nat_fixture_cleanup(&fixture);
|
nat_fixture_cleanup(&fixture);
|
||||||
test_all_groups_tcp();
|
test_all_groups_tcp();
|
||||||
test_tcp_presence();
|
test_tcp_presence();
|
||||||
|
test_incoming_connections();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user