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.
 
 
 
 
 
 

97 lines
4.9 KiB

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include "utun_instance.h"
#include "config_parser.h"
#include "routing_layer/topo_group.h"
#include "transport_layer/etcp.h"
#include "transport_layer/etcp_connections.h"
#include "transport_layer/node_conn_direct.h"
#include "../lib/u_async.h"
#include "../lib/debug_config.h"
static int links(struct ETCP_CONN* conn) {
int count = 0;
for (struct ETCP_LINK* link = conn->links; link; link = link->next) count++;
return count;
}
static void endpoint(struct CFG_CLIENT_LINK* link, struct CFG_SERVER* local, int port) {
memset(link, 0, sizeof(*link)); link->local_srv = local;
struct sockaddr_in* addr = (struct sockaddr_in*)&link->remote_addr;
addr->sin_family = AF_INET; addr->sin_addr.s_addr = htonl(0x7f000001); addr->sin_port = htons((uint16_t)port);
}
int main(void) {
debug_config_init(); debug_set_level(DEBUG_LEVEL_INFO);
utun_instance_set_tun_init_enabled(0);
struct UASYNC* ua = uasync_create(); assert(ua);
struct UTUN_INSTANCE* inst = utun_instance_create_from_str(ua,
"[global]\n"
"my_private_key=704f2e012c8fa8768130cb0f988a997dccb628372bc5ceccacc78dcbfec5916f\n"
"my_public_key=b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01\n"
"[server: udp]\naddr=127.0.0.1:0\ntype=public\n"
"[server: tcp]\naddr=127.0.0.1:0\ntype=public\ntransport=tcp\n");
assert(inst && utun_instance_init(inst) >= 0);
struct CFG_SERVER *udp = NULL, *tcp = NULL;
for (struct CFG_SERVER* s = inst->config->servers; s; s = s->next) {
if (!strcmp(s->name, "udp")) udp = s;
if (!strcmp(s->name, "tcp")) tcp = s;
}
assert(udp && tcp);
struct CFG_CLIENT client = { .name = "peer" };
struct SC_MYKEYS peer; assert(sc_generate_keypair(&peer) == SC_OK);
for (int i = 0; i < 32; i++) snprintf(client.peer_public_key_hex + i * 2, 3, "%02x", peer.public_key[i]);
struct CFG_CLIENT_LINK first, second, third;
endpoint(&first, udp, 9); endpoint(&second, udp, 10); endpoint(&third, tcp, 11);
first.next = &second; second.next = &third; client.links = &first;
assert(init_client_connections(inst, &client) == 0);
assert(inst->config_conn_handles && !inst->config_conn_handles->next);
struct ETCP_CONN* conn = topo_group_peer_conn(inst->config_conn_handles->request);
assert(conn && links(conn) == 3 && !conn->fin_wait);
struct NODE_CONN_DIRECT* chat = NULL;
assert(node_conn_direct_open(inst, conn->peer_node_id, NULL, NULL, &chat, NULL) == NCD_REUSED);
assert(init_client_connections(inst, &client) == 0);
assert(topo_group_peer_conn(inst->config_conn_handles->request) == conn && links(conn) == 3 && !conn->fin_wait);
/* Ошибка нового набора не освобождает предыдущие handles. */
struct CFG_CLIENT invalid = { .name = "invalid", .peer_public_key_hex = "not-a-key" };
client.next = &invalid;
struct CONFIG_CONN_HANDLE* previous = inst->config_conn_handles;
assert(init_client_connections(inst, &client) < 0 && inst->config_conn_handles == previous);
assert(node_conn_direct_get_conn(chat) == conn && !conn->fin_wait);
client.next = NULL;
/* REALITY идёт по тому же NCD пути; полное SNI не обрезается. */
client.links = &third; client.reality_enabled = 1;
reality_client_config_set_defaults(&client.reality);
memcpy(client.reality.server_static_pubkey, peer.public_key, 32);
memset(client.reality.server_name, 'a', 180); client.reality.server_name[180] = 0;
assert(init_client_connections(inst, &client) == 0);
assert(links(conn) == 3);
struct ETCP_LINK* real = NULL;
for (struct ETCP_LINK* link = conn->links; link; link = link->next) if (link->is_tcp) real = link;
assert(real && real->reality_set && !strcmp(real->reality.server_name, client.reality.server_name));
assert(init_client_connections(inst, &client) == 0 && links(conn) == 3);
assert(init_client_connections(inst, NULL) == 0 && !inst->config_conn_handles);
assert(node_conn_direct_get_conn(chat) == conn && !conn->fin_wait);
node_conn_direct_force_close(chat);
uasync_poll(ua, 0);
/* Клиентский TCP/REALITY не требует локального TCP listen-сокета. */
struct ETCP_SOCKET* sock = inst->etcp_sockets;
while (sock) {
struct ETCP_SOCKET* next = sock->next;
if (sock->is_tcp) etcp_socket_remove(sock);
sock = next;
}
third.local_srv = NULL;
assert(init_client_connections(inst, &client) == 0);
conn = topo_group_peer_conn(inst->config_conn_handles->request);
assert(conn && links(conn) == 1 && conn->links->is_tcp && !conn->links->conn);
assert(conn->links->reality_set && !strcmp(conn->links->reality.server_name, client.reality.server_name));
assert(init_client_connections(inst, NULL) == 0);
inst->running = 0; utun_instance_destroy(inst);
uasync_poll(ua, 0);
uasync_destroy(ua, 0);
return 0;
}