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.
82 lines
3.9 KiB
82 lines
3.9 KiB
#ifndef NAT_FIXTURE_H |
|
#define NAT_FIXTURE_H |
|
|
|
#include <assert.h> |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include "test_net.h" |
|
#include "utun_instance.h" |
|
#include "config_parser.h" |
|
#include "transport_layer/etcp.h" |
|
#include "transport_layer/node_conn_direct.h" |
|
#include "routing_layer/topo_group.h" |
|
#include "routing_layer/topo_node_sqlite.h" |
|
#include "routing_layer/nat_detection.h" |
|
#include "routing_layer/route_ping.h" |
|
#include "../lib/u_async.h" |
|
#include "../lib/mem.h" |
|
|
|
struct nat_fixture { |
|
struct UASYNC *ua; |
|
struct UTUN_INSTANCE *nodes[8]; |
|
struct NODE_CONN_DIRECT *handles[24]; |
|
unsigned node_count, handle_count; |
|
size_t allocations; |
|
}; |
|
|
|
static inline void nat_fixture_init(struct nat_fixture *fixture) { |
|
memset(fixture, 0, sizeof(*fixture)); fixture->allocations = u_get_allocated_count(); |
|
fixture->ua = uasync_create(); assert(fixture->ua); |
|
} |
|
|
|
static inline struct UTUN_INSTANCE *nat_fixture_node(struct nat_fixture *fixture, const char *ip, |
|
const struct SC_MYKEYS *keys, const char *extra) { |
|
struct SC_MYKEYS generated; |
|
if (!keys) { assert(sc_generate_keypair(&generated) == SC_OK); keys = &generated; } |
|
char private_key[65], public_key[65], config[4096]; |
|
for (unsigned i = 0; i < 32; i++) { |
|
snprintf(private_key + i * 2, 3, "%02x", keys->private_key[i]); |
|
snprintf(public_key + i * 2, 3, "%02x", keys->public_key[i]); |
|
} |
|
snprintf(config, sizeof(config), "[global]\nmy_private_key=%s\nmy_public_key=%s\nauto_sockets=no\n" |
|
"[ntp]\nenabled=no\n[server:udp]\naddr=%s:0\ntype=public\n[allowed_keys]\nallow_all=1\n%s", |
|
private_key, public_key, ip, extra ? extra : ""); |
|
struct UTUN_INSTANCE *node = utun_instance_create_from_str(fixture->ua, config); |
|
assert(node && fixture->node_count < 8 && utun_core_start(node) == 0); |
|
nat_detection_set_allow_local(node->nat_det, 1); |
|
fixture->nodes[fixture->node_count++] = node; return node; |
|
} |
|
|
|
/* Без групповой автосвязности: A контактирует только с явно указанным B. |
|
* NCD переносит настоящую подписанную запись, handshake идёт по UDP. */ |
|
static inline struct ETCP_CONN *nat_fixture_connect(struct nat_fixture *fixture, struct UTUN_INSTANCE *from, |
|
const char *source, struct UTUN_INSTANCE *to) { |
|
assert(fixture->handle_count < 24); |
|
struct TOPO_NODE *peer = topo_node_registry_find(to->topo_groups, to->node_id); assert(peer); |
|
struct NODE_CONN_DIRECT **handle = &fixture->handles[fixture->handle_count++]; |
|
assert(node_conn_direct_open_node(from, to->node_id, NULL, NULL, handle, peer, |
|
test_etcp_bound_socket(from, source)) != NCD_ERR); |
|
uint64_t end = get_time_tb() + 50000; |
|
struct ETCP_CONN *connection = NULL; |
|
while (get_time_tb() < end) { |
|
connection = node_conn_direct_get_conn(*handle); |
|
if (connection && connection->links_up) return connection; |
|
uasync_poll(fixture->ua, 10); |
|
} |
|
DEBUG_ERROR(DEBUG_CATEGORY_NAT, "fixture connection timed out from=%016llx to=%016llx", |
|
(unsigned long long)from->node_id, (unsigned long long)to->node_id); |
|
abort(); |
|
} |
|
|
|
static inline void nat_fixture_cleanup(struct nat_fixture *fixture) { |
|
for (unsigned i = 0; i < fixture->handle_count; i++) node_conn_direct_force_close(fixture->handles[i]); |
|
for (unsigned i = 0; i < fixture->node_count; i++) utun_instance_destroy(fixture->nodes[i]); |
|
uasync_poll(fixture->ua, 0); |
|
assert(fixture->ua->timer_alloc_count == fixture->ua->timer_free_count); |
|
assert(fixture->ua->socket_alloc_count == fixture->ua->socket_free_count); |
|
uasync_destroy(fixture->ua, 0); |
|
if (u_get_allocated_count() != fixture->allocations) u_report_unfreed_blocks(); |
|
assert(u_get_allocated_count() == fixture->allocations); |
|
} |
|
|
|
#endif
|
|
|