Browse Source

tests: assign STCP ping and REALITY fallback ports at bind

master
evgeny 3 days ago
parent
commit
b16da44e42
  1. 15
      tests/test_reality_fallback.c
  2. 35
      tests/test_stcp_ping.c

15
tests/test_reality_fallback.c

@ -61,14 +61,15 @@ int main(void) {
socket_set_nonblocking(dest.sock);
CHECK(uasync_add_socket_t(ua, dest.sock, destination_accept, NULL, NULL, "reality_test_listener", &dest));
snprintf(cfg.dest, sizeof(cfg.dest), "127.0.0.1:%u", ntohs(address.sin_port));
uint16_t port = 32000 + (uint16_t)(time(NULL) % 1000);
struct stcp_server *sa = stcp_server_create(ua, port, &keys, NULL, &a, unexpected_stcp, NULL, NULL, NULL, AF_INET);
struct stcp_server *sb = stcp_server_create(ua, port + 1, &keys, NULL, &b, unexpected_stcp, NULL, NULL, NULL, AF_INET);
struct stcp_server *sa = stcp_server_create(ua, 0, &keys, NULL, &a, unexpected_stcp, NULL, NULL, NULL, AF_INET);
struct stcp_server *sb = stcp_server_create(ua, 0, &keys, NULL, &b, unexpected_stcp, NULL, NULL, NULL, AF_INET);
CHECK(sa && sb); stcp_server_set_reality(sa, &cfg); stcp_server_set_reality(sb, &cfg);
uint16_t port_a = stcp_server_get_port(sa), port_b = stcp_server_get_port(sb);
CHECK(port_a && port_b && port_a != port_b);
uint8_t ch[REALITY_MAX_CH_SIZE], answer[4096]; size_t cn;
fake_now = (uint32_t)time(NULL);
CHECK(!reality_client_hello_build_at(&cc, fake_now + 30, ch, sizeof(ch), &cn));
socket_t first = connect_to(port); CHECK(first != SOCKET_INVALID && send(first, ch, cn, 0) == (ssize_t)cn);
socket_t first = connect_to(port_a); CHECK(first != SOCKET_INVALID && send(first, ch, cn, 0) == (ssize_t)cn);
poll_some(ua);
CHECK(recv(first, answer, sizeof(answer), 0) >= 127 && answer[0] == 22);
/* Через 31 секунду тот же future timestamp ещё допустим: replay обязан оставаться в кеше. */
@ -82,18 +83,18 @@ int main(void) {
pos += 5 + rest;
const uint8_t tail[] = {20, 3, 3, 0, 1, 1, 23, 3, 3, 0, 4, 1, 2, 3, 4};
memcpy(split + pos, tail, sizeof(tail)); pos += sizeof(tail);
socket_t replay = connect_to(port); CHECK(replay != SOCKET_INVALID);
socket_t replay = connect_to(port_a); CHECK(replay != SOCKET_INVALID);
CHECK(send(replay, split, 7, 0) == 7); poll_some(ua);
CHECK(send(replay, split + 7, pos - 7, 0) == (ssize_t)(pos - 7)); poll_some(ua);
CHECK(dest.count == 1 && dest.peers[0].len == pos && !memcmp(dest.peers[0].data, split, pos));
CHECK(a.reality_owner.relay_count == 1);
socket_t other = connect_to(port + 1); CHECK(other != SOCKET_INVALID && send(other, ch, cn, 0) == (ssize_t)cn);
socket_t other = connect_to(port_b); CHECK(other != SOCKET_INVALID && send(other, ch, cn, 0) == (ssize_t)cn);
poll_some(ua);
CHECK(recv(other, answer, sizeof(answer), 0) >= 127 && answer[0] == 22 && dest.count == 1);
cc.short_id[0] = 1;
CHECK(!reality_client_hello_build_at(&cc, fake_now, ch, sizeof(ch), &cn));
socket_t unauthorized = connect_to(port + 1);
socket_t unauthorized = connect_to(port_b);
CHECK(unauthorized != SOCKET_INVALID && send(unauthorized, ch, cn, 0) == (ssize_t)cn);
poll_some(ua); CHECK(dest.count == 2 && b.reality_owner.relay_count == 1);
stcp_server_destroy(sb); reality_owner_cleanup(&b.reality_owner); poll_some(ua);

35
tests/test_stcp_ping.c

@ -9,10 +9,10 @@
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
#include "../lib/mem.h"
#include "test_net.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
static int ping_ok = -1, ping_rtt = 0;
static void ping_cb(int success, uint16_t rtt, void *arg, uint64_t nonce,
@ -28,7 +28,7 @@ static void unexpected_ready(struct stcp_conn *c, void *arg) {
ping_ok = 0;
}
static char *build_config(const char *node_id, const char *priv, const char *pub, int port) {
static char *build_config(const char *node_id, const char *priv, const char *pub) {
static char buf[512];
snprintf(buf, sizeof(buf),
"[global]\n"
@ -37,10 +37,10 @@ static char *build_config(const char *node_id, const char *priv, const char *pub
"my_public_key=%s\n"
"\n"
"[server: stcp]\n"
"addr=127.0.0.1:%d\n"
"addr=127.0.0.1:0\n"
"type=public\n"
"transport=tcp\n",
node_id, priv, pub, port);
node_id, priv, pub);
return buf;
}
@ -50,22 +50,20 @@ int main(void) {
debug_set_categories(DEBUG_CATEGORY_GENERAL | DEBUG_CATEGORY_ETCP | DEBUG_CATEGORY_CONNECTION);
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "=== TCP ping (etcp_send_tcp_ping) ===");
srand((unsigned)time(NULL));
struct UASYNC *ua = uasync_create();
if (!ua) return 1;
utun_instance_set_tun_init_enabled(0);
int port = 27000 + rand() % 1000;
struct UTUN_INSTANCE *srv = utun_instance_create_from_str(ua, build_config(
"AAAAAAAAAAAAAAAA",
"38240cb82199e504686507f11f6eaa4f740fde6f0c425c495e49a523019a5d68",
"ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a", port));
"ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a"));
if (!srv || utun_instance_init(srv) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "srv init failed"); return 1; }
struct UTUN_INSTANCE *cli = utun_instance_create_from_str(ua, build_config(
"BBBBBBBBBBBBBBBB",
"704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f",
"b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01", port + 1));
"b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01"));
if (!cli || utun_instance_init(cli) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "cli init failed"); return 1; }
uint8_t srv_pub[SC_PUBKEY_SIZE];
@ -74,9 +72,7 @@ int main(void) {
srv->padding.min = srv->padding.max = ETCP_PADDING_MAX;
/* success path: ping listening STCP server */
struct sockaddr_storage addr; memset(&addr, 0, sizeof(addr));
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f000001); sin->sin_port = htons(port);
struct sockaddr_storage addr = test_etcp_bound_socket(srv, "stcp")->local_addr;
int rc = etcp_send_tcp_ping(cli, srv_pub, &addr, 2000, ping_cb, NULL, NULL, NULL);
if (rc != 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "etcp_send_tcp_ping failed rc=%d", rc); return 1; }
@ -97,14 +93,23 @@ int main(void) {
if (ping_ok != 1) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "TCP ping zero server padding failed"); return 1; }
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "=== reversed padding boundary PASSED ===");
/* failure path: port with no listener */
/* Отрицательный endpoint удерживаем привязанным сокетом без listen(). */
ping_ok = -1; ping_rtt = 0;
struct sockaddr_storage bad_addr; memset(&bad_addr, 0, sizeof(bad_addr));
struct sockaddr_in *bsin = (struct sockaddr_in *)&bad_addr;
bsin->sin_family = AF_INET; bsin->sin_addr.s_addr = htonl(0x7f000001); bsin->sin_port = htons(port + 5000);
bsin->sin_family = AF_INET; bsin->sin_addr.s_addr = htonl(0x7f000001);
socket_t refused = socket(AF_INET, SOCK_STREAM, 0);
if (refused == SOCKET_INVALID || bind(refused, (struct sockaddr*)bsin, sizeof(*bsin)) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "TCP ping: cannot reserve refused endpoint: %s", socket_strerror(socket_get_error()));
if (refused != SOCKET_INVALID) socket_close_wrapper(refused);
return 1;
}
bsin->sin_port = htons(test_bound_port(refused));
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "TCP ping: reserved non-listening port=%u", ntohs(bsin->sin_port));
rc = etcp_send_tcp_ping(cli, srv_pub, &bad_addr, 1000, ping_cb, NULL, NULL, NULL);
ticks = 0;
while (ping_ok < 0 && ticks < 3000) { uasync_poll(ua, 10); ticks++; }
socket_close_wrapper(refused);
if (ping_ok != 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "=== FAILED (failure path): success=%d rtt=%u rc=%d ===", ping_ok, ping_rtt, rc); return 1; }
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "=== failure path PASSED: success=%d ===", ping_ok);
@ -113,11 +118,11 @@ int main(void) {
reality.enabled = 1; reality.short_id_count = 1;
if (reality_generate_keypair(reality.private_key, cc.server_static_pubkey)) return 1;
strcpy(cc.server_name, "www.microsoft.com");
struct stcp_server *rs = stcp_server_create(ua, port + 2, &srv->my_keys, srv->my_ed25519_pubkey,
struct stcp_server *rs = stcp_server_create(ua, 0, &srv->my_keys, srv->my_ed25519_pubkey,
srv, unexpected_ready, NULL, NULL, NULL, AF_INET);
if (!rs) return 1;
stcp_server_set_reality(rs, &reality);
sin->sin_port = htons(port + 2);
((struct sockaddr_in*)&addr)->sin_port = htons(stcp_server_get_port(rs));
/* Одноразовый TCP-пинг не удерживает instance: длина выбирается до асинхронного connect. */
ping_ok = -1;

Loading…
Cancel
Save