// test_stcp_link.c — STCP link layer: server listen/accept (slim config) + client connect (raw stcp_client) #include "stcp_link.h" #include "stcp_client.h" #include "secure_channel.h" #include "utun_instance.h" #include "../lib/u_async.h" #include "../lib/debug_config.h" #include "../lib/mem.h" #include #include #include static int tests_passed = 0, tests_total = 0; static struct SC_MYKEYS s_keys, c_keys; static int test_failed = 0; #define BASE_PORT 24567 #define TASSERT(cond) do { \ if (!(cond)) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, " FAIL: %s", #cond); test_failed = 1; return test_failed; } \ } while(0) static struct stcp_link *g_on_srv_link = NULL; static void on_srv_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock) { (void)tcp_sock; g_on_srv_link = link; } static void on_cli_ready(struct stcp_conn *conn, void *arg) { (void)conn; int *ready = (int *)arg; *ready = 1; } static struct UTUN_INSTANCE *make_inst(struct UASYNC *ua, struct SC_MYKEYS *keys) { struct UTUN_INSTANCE *inst = u_calloc(1, sizeof(struct UTUN_INSTANCE)); if (!inst) return NULL; inst->ua = ua; inst->my_keys = *keys; inst->keepalive_interval = 200; return inst; } static int test1_basic(void) { struct UASYNC *ua = uasync_create(); TASSERT(ua); struct UTUN_INSTANCE *inst = make_inst(ua, &s_keys); TASSERT(inst); struct stcp_link_config cfg = {.inst = inst, .listen_family = AF_INET}; g_on_srv_link = NULL; struct stcp_server *ss = stcp_server_listen(&cfg, BASE_PORT + 1, on_srv_link, NULL); TASSERT(ss); int cli_ready = 0; struct stcp_client *sc = stcp_client_connect(ua, "127.0.0.1", BASE_PORT + 1, &c_keys, s_keys.public_key, NULL, 0, NULL, 0, 200, 0, on_cli_ready, &cli_ready, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL); TASSERT(sc); int ticks = 0; while ((!g_on_srv_link || !cli_ready) && ticks < 5000) { uasync_poll(ua, 10); ticks++; } TASSERT(g_on_srv_link != NULL); TASSERT(cli_ready); stcp_client_destroy(sc); stcp_link_close(g_on_srv_link); stcp_link_server_destroy(ss); u_free(inst); uasync_destroy(ua, 1); return 0; } static int test2_wrong_key(void) { struct UASYNC *ua = uasync_create(); TASSERT(ua); struct UTUN_INSTANCE *inst = make_inst(ua, &s_keys); TASSERT(inst); struct stcp_link_config cfg = {.inst = inst, .listen_family = AF_INET}; g_on_srv_link = NULL; struct stcp_server *ss = stcp_server_listen(&cfg, BASE_PORT + 2, on_srv_link, NULL); TASSERT(ss); struct SC_MYKEYS rogue; TASSERT(sc_generate_keypair(&rogue) == SC_OK); int cli_ready = 0; struct stcp_client *sc = stcp_client_connect(ua, "127.0.0.1", BASE_PORT + 2, &c_keys, rogue.public_key, NULL, 0, NULL, 0, 200, 0, on_cli_ready, &cli_ready, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL); TASSERT(sc); int ticks = 0; while (ticks < 2000) { uasync_poll(ua, 10); ticks++; } TASSERT(!g_on_srv_link); // should NOT connect with wrong key stcp_client_destroy(sc); stcp_link_server_destroy(ss); u_free(inst); uasync_destroy(ua, 1); return 0; } int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO); debug_set_categories(DEBUG_CATEGORY_GENERAL | DEBUG_CATEGORY_SOCKET | DEBUG_CATEGORY_CRYPTO); TASSERT(sc_generate_keypair(&s_keys) == SC_OK); TASSERT(sc_generate_keypair(&c_keys) == SC_OK); test1_basic(); test2_wrong_key(); DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "Results: %d/%d passed", 2 - (test_failed ? 1 : 0), 2); return test_failed ? 1 : 0; }