You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

138 lines
6.4 KiB

// test_stcp_ping.c — TCP-ping (etcp_send_tcp_ping / stcp_ping_send) end-to-end check
#include "stcp_client.h"
#include "stcp_server.h"
#include "etcp_connections.h"
#include "etcp.h"
#include "topo_group.h"
#include "topo_node.h"
#include "../src/utun_instance.h"
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
#include "../lib/mem.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,
const uint8_t *resp_data, size_t resp_data_len) {
(void)arg; (void)nonce; (void)resp_data; (void)resp_data_len;
ping_ok = success; ping_rtt = rtt;
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "TCP ping cb: success=%d rtt=%u", success, rtt);
}
static void unexpected_ready(struct stcp_conn *c, void *arg) {
(void)c; (void)arg;
DEBUG_ERROR(DEBUG_CATEGORY_REALITY, "TCP ping unexpectedly entered DATA callback");
ping_ok = 0;
}
static char *build_config(const char *node_id, const char *priv, const char *pub, int port) {
static char buf[512];
snprintf(buf, sizeof(buf),
"[global]\n"
"my_node_id=0x%s\n"
"my_private_key=%s\n"
"my_public_key=%s\n"
"\n"
"[server: stcp]\n"
"addr=127.0.0.1:%d\n"
"type=public\n"
"transport=tcp\n",
node_id, priv, pub, port);
return buf;
}
int main(void) {
debug_config_init();
debug_set_level(DEBUG_LEVEL_INFO);
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));
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));
if (!cli || utun_instance_init(cli) < 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "cli init failed"); return 1; }
uint8_t srv_pub[SC_PUBKEY_SIZE];
memcpy(srv_pub, srv->my_keys.public_key, SC_PUBKEY_SIZE);
cli->padding.min = cli->padding.max = 0;
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);
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; }
int ticks = 0;
while (ping_ok < 0 && ticks < 5000) { uasync_poll(ua, 10); ticks++; }
if (ping_ok != 1) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "=== FAILED (success path): success=%d rtt=%u ===", ping_ok, ping_rtt); return 1; }
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "=== success path PASSED: rtt=%u ===", ping_rtt);
/* Обратная граница: нулевой ответ сервера должен завершиться без ожидания следующего пакета. */
ping_ok = -1;
cli->padding.min = cli->padding.max = ETCP_PADDING_MAX;
srv->padding.min = srv->padding.max = 0;
rc = etcp_send_tcp_ping(cli, srv_pub, &addr, 2000, ping_cb, NULL, NULL, NULL);
if (rc != 0) return 1;
ticks = 0;
while (ping_ok < 0 && ticks < 5000) { uasync_poll(ua, 10); ticks++; }
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 */
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);
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++; }
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);
struct reality_config reality; reality_config_set_defaults(&reality);
struct reality_client_config cc; reality_client_config_set_defaults(&cc);
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,
srv, unexpected_ready, NULL, NULL, NULL, AF_INET);
if (!rs) return 1;
stcp_server_set_reality(rs, &reality);
sin->sin_port = htons(port + 2);
/* Одноразовый TCP-пинг не удерживает instance: длина выбирается до асинхронного connect. */
ping_ok = -1;
rc = etcp_send_tcp_ping(cli, srv_pub, &addr, 2000, ping_cb, NULL, NULL, &cc);
if (rc != 0) return 1;
cli->running = 0; utun_instance_destroy(cli); cli = NULL;
ticks = 0;
while (ping_ok < 0 && ticks < 5000) { uasync_poll(ua, 10); ticks++; }
if (ping_ok != 1) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "TCP ping outliving instance failed"); return 1; }
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "=== TCP ping without retained instance PASSED ===");
stcp_server_destroy(rs);
srv->running = 0;
utun_instance_destroy(srv);
uasync_destroy(ua, 0);
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "=== PASSED ===");
return 0;
}