|
|
|
|
@ -199,9 +199,9 @@ static void statistics(struct lab *lab, uint64_t id, int loads) {
|
|
|
|
|
stun.members, stun.generation, stun.evidence_id); |
|
|
|
|
json_string(sockaddr_storage_to_str(&stun.local).str); printf("}"); |
|
|
|
|
} |
|
|
|
|
printf(",\"phase\":%u,\"reason\":\"%s\",\"observer\":\"%" PRIu64 "\",\"helper\":\"%" PRIu64 "\"," |
|
|
|
|
printf(",\"phase\":%u,\"reason\":\"%s\",\"group\":\"%" PRIu64 "\",\"observer\":\"%" PRIu64 "\",\"helper\":\"%" PRIu64 "\"," |
|
|
|
|
"\"rounds\":%u,\"helper_reselections\":%u,\"history_complete\":%u,\"contacts\":[", status.phase, |
|
|
|
|
nat_check_reason_name(status.reason), status.observer, status.helper, status.rounds, |
|
|
|
|
nat_check_reason_name(status.reason), status.group_id, status.observer, status.helper, status.rounds, |
|
|
|
|
status.helper_reselections, status.history_complete); |
|
|
|
|
uint8_t local[ROUTE_ADDR_WIRE_SIZE]; sqlite3_stmt *contacts = NULL; int contact_separator = 0; |
|
|
|
|
if (!socket->is_tcp && !route_ping_addr_encode(local, &socket->local_addr) && |
|
|
|
|
@ -322,6 +322,16 @@ static struct TOPO_NODE *parse_snapshot(struct lab *lab, const char *json) {
|
|
|
|
|
|
|
|
|
|
/* Стенд переносит подписанные снимки через RPC только до запуска группы.
|
|
|
|
|
* NCD handshake, наблюдения и весь трафик всё равно проходят по настоящей сети. */ |
|
|
|
|
/* NAT-стенд имеет настоящую общую группу; UP прямого транспорта начинает групповой обмен. */ |
|
|
|
|
static void nat_link_ready(struct NODE_CONN_DIRECT *handle, enum ncd_event event, void *arg) { |
|
|
|
|
struct lab *lab = arg; |
|
|
|
|
if (event != NCD_EVENT_UP) return; |
|
|
|
|
struct TOPO_GROUP *group = topo_groups_find(lab->inst->topo_groups, TOPO_GROUP_UTUN); |
|
|
|
|
struct ETCP_CONN *connection = node_conn_direct_get_conn(handle); |
|
|
|
|
if (!group || !connection || topo_group_new_conn(group, connection)) |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_NAT, "lab: NAT group connection unavailable"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int nat_command(struct lab *lab, const char *json, const char *operation, uint64_t id) { |
|
|
|
|
if (!strcmp(operation, "chat_start")) { |
|
|
|
|
int result = chat_service_start(lab->inst); |
|
|
|
|
@ -329,6 +339,7 @@ static int nat_command(struct lab *lab, const char *json, const char *operation,
|
|
|
|
|
reply(id, result); return 1; |
|
|
|
|
} |
|
|
|
|
if (!strcmp(operation, "nat_release")) { |
|
|
|
|
if (topo_groups_find(lab->inst->topo_groups, TOPO_GROUP_UTUN)) topo_groups_remove_group(lab->inst->topo_groups, TOPO_GROUP_UTUN); |
|
|
|
|
for (unsigned i = 0; i < lab->nat_handle_count; i++) node_conn_direct_close(lab->nat_handles[i]); |
|
|
|
|
for (unsigned i = 0; i < lab->nat_record_count; i++) topo_node_registry_unref(lab->inst->topo_groups, lab->nat_records[i]); |
|
|
|
|
lab->nat_handle_count = lab->nat_record_count = 0; reply(id, 0); return 1; |
|
|
|
|
@ -369,7 +380,7 @@ static int nat_command(struct lab *lab, const char *json, const char *operation,
|
|
|
|
|
if (!socket) { DEBUG_ERROR(DEBUG_CATEGORY_NAT, "lab: native link source/handle unavailable"); result = -1; } |
|
|
|
|
else { |
|
|
|
|
struct NODE_CONN_DIRECT *handle = NULL; |
|
|
|
|
int opened = node_conn_direct_open_node(lab->inst, node->node_id, NULL, NULL, &handle, node, socket); |
|
|
|
|
int opened = node_conn_direct_open_node(lab->inst, node->node_id, nat_link_ready, lab, &handle, node, socket); |
|
|
|
|
if (opened == NCD_ERR || !handle) result = -1; |
|
|
|
|
else lab->nat_handles[lab->nat_handle_count++] = handle; |
|
|
|
|
} |
|
|
|
|
@ -518,7 +529,12 @@ int main(int argc, char **argv) {
|
|
|
|
|
if (!lab->inst || utun_core_start(lab->inst) || (!core_only && chat_service_start(lab->inst))) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_STREAM, "lab: service startup failed"); return 1; |
|
|
|
|
} |
|
|
|
|
if (core_only) nat_detection_set_automatic(lab->inst->nat_det, 0); |
|
|
|
|
if (core_only) { |
|
|
|
|
nat_detection_set_automatic(lab->inst->nat_det, 0); |
|
|
|
|
if (!topo_groups_create_group(lab->inst->topo_groups, TOPO_GROUP_UTUN, TOPO_GROUP_TYPE_UTUN, "")) { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_NAT, "lab: NAT control group creation failed"); return 1; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
debug_enable_console(0); |
|
|
|
|
if (!core_only) stream_set_event_callback(lab->inst, event, lab); |
|
|
|
|
if (fcntl(STDIN_FILENO, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | O_NONBLOCK) < 0) { |
|
|
|
|
|