Browse Source

Удалить обмен метриками ETCP (ETCP_SECTION_METRICS)

Полностью убрана фича периодического обмена CSV-метриками с Ed25519-подписью:
- ETCP_SECTION_METRICS и парсинг/верификация секции
- struct etcp_metrics, etcp_metrics_add_*/start/stop и снапшот-таймер
- мёртвый API on_metrics_rcvd/metrics_user_ptr (никто не подписан)
- link->remote_ed25519_pubkey (заполнялся только на клиенте → верификация на сервере всегда падала)
- stats_dir в UTUN_INSTANCE
Общий sc_stream_sign_* (деривация Ed25519 из X25519) и INIT-передача обоих ключей сохранены.
v2
evgeny 3 weeks ago
parent
commit
e3168d1e55
  1. 2
      src/routing_layer/topo_node.c
  2. 221
      src/transport_layer/etcp.c
  3. 45
      src/transport_layer/etcp.h
  4. 14
      src/transport_layer/etcp_api.h
  5. 3
      src/transport_layer/etcp_api_doc.md
  6. 1
      src/transport_layer/etcp_connections.c
  7. 1
      src/transport_layer/etcp_connections.h
  8. 1
      src/transport_layer/etcp_connections_doc.md
  9. 17
      src/utun_instance.c
  10. 2
      src/utun_instance.h
  11. 1
      src/utun_instance_doc.md

2
src/routing_layer/topo_node.c

@ -480,7 +480,7 @@ void topo_node_ping_update_rtt(struct TOPO_GROUPS* groups, uint64_t node_id, uin
nq->connectivity.nat_min_rtt = rtt;
if (nq->connectivity.real_min_rtt == 0 || rtt < nq->connectivity.real_min_rtt)
nq->connectivity.real_min_rtt = rtt;
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "ping_update_rtt: node=%016llx rtt=%u (%llu) group=%016llx",
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "ping_update_rtt: node=%016llx rtt=%u (%llu) group=%016llx",
(unsigned long long)node_id, (unsigned)rtt, (unsigned long long)now, (unsigned long long)g->group_id);
if (groups->instance && groups->instance->topo_sqlite_db)
topo_node_sqlite_update_rtt(groups->instance->topo_sqlite_db, node_id, rtt);

221
src/transport_layer/etcp.c

@ -17,7 +17,6 @@
#include <sys/time.h>
#include <math.h> // For bandwidth calcs
#include <limits.h> // For UINT16_MAX
#include <time.h> // For strftime in metrics snapshot
#include "../lib/mem.h"
#include "../lib/strbuf.h"
#include "../lib/memory_pool.h"
@ -405,7 +404,6 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
// Cancel active timers
if (etcp->retrans_timer) { uasync_cancel_timeout(etcp->instance->ua, etcp->retrans_timer); etcp->retrans_timer = NULL; }
if (etcp->ack_resp_timer) { uasync_cancel_timeout(etcp->instance->ua, etcp->ack_resp_timer); etcp->ack_resp_timer = NULL; }
etcp_metrics_stop_timer(etcp);
routing_del_conn(etcp);
etcp_router_transit_queues_destroy(etcp);
@ -706,8 +704,6 @@ void etcp_conn_queue_set_ready(struct ETCP_CONN* conn) {
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] moved to ready queue, state=%d peer_node_id=0x%llx",
conn->log_name, conn->state, (unsigned long long)conn->peer_node_id);
etcp_metrics_start_timer(conn);
etcp_cbk_fire(conn, ETCP_CBK_EVENT_INIT);
if (conn->reinit_pending) { conn->reinit_pending = 0; etcp_cbk_fire(conn, ETCP_CBK_EVENT_REINIT); }
if (conn->links_up) etcp_on_up(conn);
@ -973,7 +969,6 @@ static void ack_timeout_check(struct ETCP_CONN* etcp) {
// Update stats
etcp->retransmissions_count++;
etcp_metrics_add_loss(etcp, 1);
}
else {// не надо до конца сканировать - они уже сортированы по таймстемпу т.к. очередь fifo, а timestamp = время добавления в очередь = время отправки
// shedule timer
@ -1176,7 +1171,6 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
inf_pkt->state=INFLIGHT_STATE_WAIT_ACK;
queue_data_put_with_index(etcp->input_wait_ack, &inf_pkt->ll);// move dgram to wait_ack queue
etcp_metrics_add_sent(etcp, inf_pkt->ll.len);
}
size_t ack_q_size = queue_entry_count(etcp->ack_q);
@ -1582,7 +1576,6 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
pkt->link->rtt_last=new_rtt;
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] KA-RTT: rtt=%u cur=%u ret=%u dlen=%u",
etcp->log_name, new_rtt, cur_ts, ret_ts, pkt->data_len);
etcp_metrics_add_rtt(etcp, new_rtt);
int recv_dt_tx1=data[3] | (data[4]<<8);// localtime удаленной стороны момента принятия пакета - timestamp этого пакета (на стороне отправителя, т.е. у нас)
@ -1710,7 +1703,6 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
memcpy(payload_data, data + 5, pkt_len);
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] RX seq=%u need=%u asm_len=%d", etcp->log_name, seq, etcp->last_delivered_id+1, etcp->recv_q->count);
queue_data_put_with_index(etcp->recv_q, (struct ll_entry*)rx_pkt);
etcp_metrics_add_rcvd(etcp, pkt_len);
if ((int32_t)(seq - etcp->last_delivered_id) == 1) etcp_output_try_assembly(etcp);// пробуем собрать выходную очередь из фрагментов
} else {
etcp->rx_dup_count++;
@ -1737,7 +1729,6 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
}
if (link->burst_recv_valid) {
if (seq != link->burst_recv_next_seq) {
if (seq > link->burst_recv_next_seq) etcp_metrics_add_loss(etcp, seq - link->burst_recv_next_seq);
link->burst_recv_valid = 0;
}
if (seq < 16) {
@ -1806,44 +1797,6 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
break;
}
case ETCP_SECTION_METRICS: {
if (len < 2 + SC_SIGN_SIZE) { len = 0; break; }
uint16_t csv_len = data[1] | (data[2] << 8);
if ((uint32_t)(2 + SC_SIGN_SIZE + csv_len) > len) { len = 0; break; }
uint8_t* sig = data + 2;
uint8_t* csv = data + 2 + SC_SIGN_SIZE;
uint8_t* peer_pubkey = pkt->link->remote_ed25519_pubkey;
struct sc_stream_sign_state verify_state;
int sig_ok = (sc_stream_sign_verify_init(&verify_state, peer_pubkey) == SC_OK
&& sc_stream_sign_update(&verify_state, csv, csv_len) == SC_OK
&& sc_stream_sign_verify(&verify_state, sig, SC_SIGN_SIZE) == SC_OK);
if (!sig_ok && verify_state.initialized) /* update failed, then verify didn't run */
sc_stream_sign_cleanup(&verify_state);
if (sig_ok) {
const char* stats_dir = etcp->instance->stats_dir;
if (stats_dir[0] && etcp->peer_node_id != 0) {
char path[768];
snprintf(path, sizeof(path), "%s/from_%016llx.dat", stats_dir, (unsigned long long)etcp->peer_node_id);
FILE* f = fopen(path, "a");
if (f) {
fprintf(f, "%.*s,", csv_len, csv);
for (int i = 0; i < SC_SIGN_SIZE; i++) fprintf(f, "%02x", sig[i]);
fprintf(f, "\n");
fclose(f);
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] Received metrics from peer (%u bytes)", etcp->log_name, csv_len);
if (etcp->instance->api_bindings.on_metrics_rcvd)
etcp->instance->api_bindings.on_metrics_rcvd(etcp->instance->api_bindings.metrics_user_ptr, etcp, csv, csv_len, sig);
} else {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] Cannot open from_metrics file: %s", etcp->log_name, path);
}
}
} else {
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "[%s] Metrics signature verification FAILED", etcp->log_name);
}
data += 2 + SC_SIGN_SIZE + csv_len; len -= 2 + SC_SIGN_SIZE + csv_len;
break;
}
default:
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "unknown section type=0x%02x", type);
len=0;
@ -1883,178 +1836,4 @@ void etcp_update_mtu(struct ETCP_CONN* etcp) {
}
}
// ====================================================================== Метрики: гистограммы RTT/потерь + тотальные счётчики
static const uint16_t etcp_metrics_rtt_bounds[] = { 10, 20, 30, 50, 80, 130, 210, 340, 550, 900, 1500 };
#define ETCP_METRICS_RTT_BOUNDS_COUNT (sizeof(etcp_metrics_rtt_bounds) / sizeof(etcp_metrics_rtt_bounds[0]))
void etcp_metrics_init(struct etcp_metrics* m) {
if (!m) return;
memset(m, 0, sizeof(*m));
}
void etcp_metrics_add_rtt(struct ETCP_CONN* etcp, uint16_t rtt_tb) {
if (!etcp || etcp->state == 2) return;
struct etcp_metrics* m = &etcp->metrics;
int i;
for (i = 0; i < (int)ETCP_METRICS_RTT_BOUNDS_COUNT; i++) {
if (rtt_tb < etcp_metrics_rtt_bounds[i]) break;
}
if (i >= ETCP_METRICS_RTT_BUCKETS) i = ETCP_METRICS_RTT_BUCKETS - 1;
m->rtt_hist[i]++;
m->work_samples++;
}
void etcp_metrics_add_sent(struct ETCP_CONN* etcp, uint32_t len) {
if (!etcp || etcp->state == 2) return;
struct etcp_metrics* m = &etcp->metrics;
m->work_sent++;
m->work_bytes_sent += len;
m->total_sent++;
m->total_bytes_sent += len;
}
void etcp_metrics_add_rcvd(struct ETCP_CONN* etcp, uint32_t len) {
if (!etcp || etcp->state == 2) return;
struct etcp_metrics* m = &etcp->metrics;
m->work_rcvd++;
m->work_bytes_rcvd += len;
m->total_rcvd++;
m->total_bytes_rcvd += len;
}
void etcp_metrics_add_loss(struct ETCP_CONN* etcp, uint32_t count) {
if (!etcp || etcp->state == 2) return;
struct etcp_metrics* m = &etcp->metrics;
m->work_lost += count;
m->total_lost += count;
}
static void etcp_metrics_do_snapshot(struct ETCP_CONN* etcp) {
if (!etcp || !etcp->instance) return;
struct etcp_metrics* m = &etcp->metrics;
// Копируем working → final
memcpy(m->rtt_hist_final, m->rtt_hist, sizeof(m->rtt_hist_final));
memcpy(m->loss_hist_final, m->loss_hist, sizeof(m->loss_hist_final));
m->samples_final = m->work_samples;
m->sent_final = m->work_sent;
m->rcvd_final = m->work_rcvd;
m->bytes_sent_final = m->work_bytes_sent;
m->bytes_rcvd_final = m->work_bytes_rcvd;
m->lost_final = m->work_lost;
// Рассчитываем loss-гистограмму
uint32_t total = m->work_sent + m->work_lost;
if (total > 0) {
uint32_t loss_pct = (m->work_lost * 100 + total / 2) / total;
int bucket = (int)loss_pct;
if (bucket >= ETCP_METRICS_LOSS_BUCKETS) bucket = ETCP_METRICS_LOSS_BUCKETS - 1;
m->loss_hist[bucket]++;
}
// Обнуляем рабочую копию
memset(m->rtt_hist, 0, sizeof(m->rtt_hist));
memset(m->loss_hist, 0, sizeof(m->loss_hist));
m->work_samples = 0;
m->work_sent = 0; m->work_rcvd = 0;
m->work_bytes_sent = 0; m->work_bytes_rcvd = 0;
m->work_lost = 0;
m->last_snapshot_tb = get_time_tb();
// Строим CSV строку
char csv_buf[4096];
int pos = 0;
time_t now = time(NULL);
struct tm* tm = localtime(&now);
char date_str[16], time_str[16];
if (tm) { strftime(date_str, sizeof(date_str), "%Y-%m-%d", tm); strftime(time_str, sizeof(time_str), "%H:%M:%S", tm); }
else { strcpy(date_str, "----"); strcpy(time_str, "----"); }
pos += snprintf(csv_buf + pos, sizeof(csv_buf) - pos, "%s,%s", date_str, time_str);
for (int i = 0; i < ETCP_METRICS_RTT_BUCKETS; i++) pos += snprintf(csv_buf + pos, sizeof(csv_buf) - pos, ",%u", m->rtt_hist_final[i]);
for (int i = 0; i < ETCP_METRICS_LOSS_BUCKETS; i++) pos += snprintf(csv_buf + pos, sizeof(csv_buf) - pos, ",%u", m->loss_hist_final[i]);
pos += snprintf(csv_buf + pos, sizeof(csv_buf) - pos, ",%u,%u,%u,%u,%u,%u", m->samples_final, m->sent_final, m->rcvd_final, m->bytes_sent_final, m->bytes_rcvd_final, m->lost_final);
pos += snprintf(csv_buf + pos, sizeof(csv_buf) - pos, ",%llu,%llu,%llu,%llu,%llu", (unsigned long long)m->total_sent, (unsigned long long)m->total_rcvd, (unsigned long long)m->total_bytes_sent, (unsigned long long)m->total_bytes_rcvd, (unsigned long long)m->total_lost);
uint32_t csv_len = (uint32_t)pos;
// Запись локального файла
const char* stats_dir = etcp->instance->stats_dir;
if (stats_dir[0] && etcp->peer_node_id != 0) {
char path[768];
snprintf(path, sizeof(path), "%s/%016llx.dat", stats_dir, (unsigned long long)etcp->peer_node_id);
FILE* f = fopen(path, "a");
if (f) { fprintf(f, "%s\n", csv_buf); fclose(f); }
else DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] Cannot open metrics file: %s", etcp->log_name, path);
}
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] Metrics snapshot: samples=%u sent=%u rcvd=%u lost=%u", etcp->log_name, m->samples_final, m->sent_final, m->rcvd_final, m->lost_final);
// Подпись Ed25519 и отправка пиру
if (etcp->crypto_ctx.initialized && etcp->initialized) {
struct sc_stream_sign_state sign_state;
if (sc_stream_sign_init(&etcp->crypto_ctx, &sign_state) == SC_OK) {
uint8_t sig[SC_SIGN_SIZE];
size_t sig_len = sizeof(sig);
if (sc_stream_sign_update(&sign_state, (uint8_t*)csv_buf, csv_len) == SC_OK
&& sc_stream_sign_final(&sign_state, sig, &sig_len) == SC_OK) {
// Построить и отправить дграмму с секцией METRICS
struct ETCP_LINK* link = etcp_loadbalancer_select_link(etcp);
if (link) {
struct ETCP_DGRAM* dgram = memory_pool_alloc(etcp->instance->pkt_pool);
if (dgram) {
dgram->link = link;
dgram->noencrypt_len = 0;
dgram->timestamp = get_current_timestamp();
int ptr = 0;
// Минимальная ACK-секция
dgram->data[ptr++] = 1; dgram->data[ptr++] = 0;
dgram->data[ptr++] = etcp->last_delivered_id; dgram->data[ptr++] = etcp->last_delivered_id>>8;
dgram->data[ptr++] = etcp->last_delivered_id>>16; dgram->data[ptr++] = etcp->last_delivered_id>>24;
dgram->data[ptr++] = etcp->rx_dup_count; dgram->data[ptr++] = etcp->rx_dup_count>>8;
// METRICS секция
dgram->data[ptr++] = ETCP_SECTION_METRICS;
uint16_t csv16 = (uint16_t)csv_len;
dgram->data[ptr++] = csv16 & 0xFF; dgram->data[ptr++] = (csv16 >> 8) & 0xFF;
memcpy(dgram->data + ptr, sig, SC_SIGN_SIZE); ptr += SC_SIGN_SIZE;
memcpy(dgram->data + ptr, csv_buf, csv_len); ptr += csv_len;
dgram->data_len = ptr;
etcp_encrypt_send(dgram);
memory_pool_free(etcp->instance->pkt_pool, dgram);
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] Metrics sent to peer (%u bytes)", etcp->log_name, csv_len);
}
}
} else {
sc_stream_sign_cleanup(&sign_state);
}
}
}
}
static void metrics_snapshot_timer_cb(void* arg) {
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
if (!etcp) return;
etcp->metrics.timer = NULL;
if (etcp->metrics.work_sent + etcp->metrics.work_rcvd >= ETCP_METRICS_MIN_PACKETS)
etcp_metrics_do_snapshot(etcp);
// Перезапускаем таймер
etcp->metrics.timer = uasync_set_timeout(etcp->instance->ua, ETCP_METRICS_INTERVAL_TB, etcp, metrics_snapshot_timer_cb, "etcp_metrics");
}
void etcp_metrics_start_timer(struct ETCP_CONN* etcp) {
if (!etcp || etcp->state == 2 || etcp->metrics.timer) return;
etcp_metrics_init(&etcp->metrics);
etcp->metrics.timer = uasync_set_timeout(etcp->instance->ua, ETCP_METRICS_INTERVAL_TB, etcp, metrics_snapshot_timer_cb, "etcp_metrics");
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] Metrics timer started (interval=%ums)", etcp->log_name, ETCP_METRICS_INTERVAL_TB / 10);
}
void etcp_metrics_stop_timer(struct ETCP_CONN* etcp) {
if (!etcp) return;
if (etcp->metrics.timer && etcp->instance) {
uasync_cancel_timeout(etcp->instance->ua, etcp->metrics.timer);
etcp->metrics.timer = NULL;
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] Metrics timer stopped", etcp->log_name);
}
}

45
src/transport_layer/etcp.h

@ -32,7 +32,6 @@ uint16_t get_current_timestamp(void);
#define ETCP_SECTION_MEAS_TS 0x07 // Measurement timestamp for bandwidth (burst packet)
#define ETCP_SECTION_MEAS_RESP 0x08 // Measurement response (burst result)
#define ETCP_SECTION_FILLER 0x09 // Filler/dummy data (discarded by receiver)
#define ETCP_SECTION_METRICS 0x0A // Metrics CSV exchange (ed25519 signed)
// Burst measurement constants
#define BURST_PACKET_COUNT 12 // число пакетов в burst
@ -56,40 +55,6 @@ uint16_t get_current_timestamp(void);
// MEAS_RESP valid
#define MEAS_RESP_VALID 1
// Метрики: гистограммы RTT и потерь с 10-мин снимками
#define ETCP_METRICS_RTT_BUCKETS 12 // 0-1,1-2,2-3,3-5,5-8,8-13,13-21,21-34,34-55,55-90,90-150,150+ ms
#define ETCP_METRICS_LOSS_BUCKETS 11 // 0%,1%,...,10%+
#define ETCP_METRICS_INTERVAL_TB 6000000 // 10 мин в 0.1ms
#define ETCP_METRICS_MIN_PACKETS 200 // мин пакетов для обновления гистограмм
struct etcp_metrics {
uint32_t rtt_hist[ETCP_METRICS_RTT_BUCKETS]; // рабочая RTT-гистограмма
uint32_t loss_hist[ETCP_METRICS_LOSS_BUCKETS]; // рабочая loss-гистограмма
uint32_t work_samples; // RTT замеров в окне
uint32_t work_sent; // пакетов отправлено в окне
uint32_t work_rcvd; // пакетов принято в окне
uint32_t work_bytes_sent; // байт отправлено в окне
uint32_t work_bytes_rcvd; // байт принято в окне
uint32_t work_lost; // потеряно в окне
uint32_t rtt_hist_final[ETCP_METRICS_RTT_BUCKETS]; // финальная RTT-гистограмма
uint32_t loss_hist_final[ETCP_METRICS_LOSS_BUCKETS]; // финальная loss-гистограмма
uint32_t samples_final;
uint32_t sent_final;
uint32_t rcvd_final;
uint32_t bytes_sent_final;
uint32_t bytes_rcvd_final;
uint32_t lost_final;
uint64_t total_sent;
uint64_t total_rcvd;
uint64_t total_bytes_sent;
uint64_t total_bytes_rcvd;
uint64_t total_lost;
void* timer;
uint64_t last_snapshot_tb;
};
#define INFLIGHT_STATE_WAIT_ACK 0
#define INFLIGHT_STATE_WAIT_SEND 1
@ -252,8 +217,6 @@ struct ETCP_CONN {
uint32_t tx_dup_count; // счетчик дубликатов удаленной стороны (из ACK)
uint32_t debug[8]; // 8 значений для дебага (live watch)
struct etcp_metrics metrics; // гистограммы RTT/потерь, тотальные счётчики
// Logging identifier (format: "XXXX→XXXX [name]" - last 4 digits of local and peer node_id + optional name)
char log_name[256];
char* name; // Connection name from config (e.g., "client_test1"), or NULL/empty
@ -334,14 +297,6 @@ void etcp_on_link_down(struct ETCP_CONN* etcp, struct ETCP_LINK* down_link);
void etcp_update_mtu(struct ETCP_CONN* etcp);
void etcp_metrics_init(struct etcp_metrics* m);
void etcp_metrics_add_rtt(struct ETCP_CONN* etcp, uint16_t rtt_tb);
void etcp_metrics_add_sent(struct ETCP_CONN* etcp, uint32_t len);
void etcp_metrics_add_rcvd(struct ETCP_CONN* etcp, uint32_t len);
void etcp_metrics_add_loss(struct ETCP_CONN* etcp, uint32_t count);
void etcp_metrics_start_timer(struct ETCP_CONN* etcp);
void etcp_metrics_stop_timer(struct ETCP_CONN* etcp);
#ifdef __cplusplus
}
#endif

14
src/transport_layer/etcp_api.h

@ -67,18 +67,6 @@ struct etcp_status_cbk_entry {
struct etcp_status_cbk_entry* next;
};
/**
* @brief Тип коллбэка для приёма метрик от пира
* @param user_ptr пользовательский указатель
* @param conn ETCP соединение от которого получены метрики
* @param csv CSV-строка метрик
* @param csv_len длина строки
* @param sig Ed25519 подпись (64 байта) или NULL если ключ неизвестен
*/
typedef void (*etcp_metrics_fn)(void* user_ptr, struct ETCP_CONN* conn,
const uint8_t* csv, uint32_t csv_len,
const uint8_t* sig);
/**
* @brief Тип коллбэка для приёма пакетов
* @param conn ETCP соединение от которого получен пакет
@ -165,8 +153,6 @@ int etcp_connect(struct UTUN_INSTANCE* instance, struct TOPO_GROUP_NODE* node,
*/
struct ETCP_BINDINGS {
etcp_recv_fn callbacks[ETCP_MAX_BINDINGS]; /**< Массив callbacks, NULL = не установлен */
etcp_metrics_fn on_metrics_rcvd; /**< Callback приёма метрик от пира */
void* metrics_user_ptr; /**< Аргумент для on_metrics_rcvd */
};
/**

3
src/transport_layer/etcp_api_doc.md

@ -81,14 +81,13 @@ etcp_connect(instance, node, on_connect, arg,
| Структура | Назначение |
|-----------|-----------|
| `ETCP_BINDINGS` | Per-instance массив `callbacks[256]` + коллбэк приёма метрик (`on_metrics_rcvd`) |
| `ETCP_BINDINGS` | Per-instance массив `callbacks[256]` |
### Типы коллбэков
| Тип | Сигнатура | Назначение |
|-----|-----------|-----------|
| `etcp_recv_fn` | `void(conn, entry)` | Приём пакета — **обязан** освободить entry/dgram |
| `etcp_metrics_fn` | `void(user_ptr, conn, csv, csv_len, sig)` | Приём метрик (CSV + Ed25519-подпись) |
| `etcp_cbk_fn` | `void(conn, arg)` | События ready/up/down/new_conn |
| `etcp_connect_callback_t` | `void(arg, conn, type)` | Результат фонового подключения |

1
src/transport_layer/etcp_connections.c

@ -1779,7 +1779,6 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D
link->etcp->log_name);
}
memcpy(link->remote_ed25519_pubkey, resp->ed25519_pubkey, SC_PUBKEY_SIZE);
memcpy(link->etcp->peer_ed25519_pubkey, resp->ed25519_pubkey, SC_PUBKEY_SIZE);
DEBUG_DEBUG(DEBUG_CATEGORY_CRYPTO, "[%s] Received Ed25519 pubkey from peer", link->etcp->log_name);

1
src/transport_layer/etcp_connections.h

@ -221,7 +221,6 @@ struct ETCP_LINK {
uint8_t remote_only_local; // only_local flag from peer
uint8_t remote_type; // CFG_SERVER_TYPE_* (type of peer's socket)
uint8_t nat_type; // NAT_TYPE_* (detected for this client link)
uint8_t remote_ed25519_pubkey[SC_PUBKEY_SIZE]; // Ed25519 pubkey пира (из INIT handshake)
uint8_t recv_keepalive; // 1 - up, 0 - down (принимаются ли пакеты)
uint8_t remote_keepalive; // 1 - up, 0 - down (удаленная сторона сообщает - принимаются ли у нее пакеты)
uint8_t link_status; // 1 - up, 0 - down (итоговый статус - если есть проблемы на любой стороне - линк down)

1
src/transport_layer/etcp_connections_doc.md

@ -130,7 +130,6 @@ void my_ping_callback(int success, uint16_t rtt, void* arg, uint64_t nonce,
- `link_status` — итоговый статус: `recv_keepalive && remote_keepalive`
- `link_state`: 0=init, 1=handshake, 2=reconnect, 3=connected
- `init_timer` / `keepalive_timer` / `shaper_timer` — таймеры uasync
- `remote_ed25519_pubkey` — Ed25519-ключ пира из INIT handshake
- `bbr` — состояние BBR congestion control per-link
- Поля burst-измерений bandwidth (sender + receiver)
- `send_hook` — перехватчик отправки (для net_emulator)

17
src/utun_instance.c

@ -334,23 +334,6 @@ struct UTUN_INSTANCE* utun_instance_create(struct UASYNC* ua, const char *config
}
instance->etcp_connect_timeout_tb = 20000;
// Init stats_dir from config file path
{
const char* last_sep = NULL;
for (const char* p = config_file; *p; p++) if (*p == '/' || *p == '\\') last_sep = p;
size_t dir_len = last_sep ? (size_t)(last_sep - config_file) : 1;
if (last_sep) {
memcpy(instance->stats_dir, config_file, dir_len);
instance->stats_dir[dir_len] = '\0';
} else {
instance->stats_dir[0] = '.'; instance->stats_dir[1] = '\0';
}
int remaining = (int)(sizeof(instance->stats_dir) - dir_len - 8);
if (remaining > 0) snprintf(instance->stats_dir + dir_len, remaining, "/stats");
utun_mkdir(instance->stats_dir, 0755);
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "Metrics stats dir: %s", instance->stats_dir);
}
// Initialize using common function
if (instance_init_common(instance, ua, config) != 0) {
// Cleanup on error

2
src/utun_instance.h

@ -112,8 +112,6 @@ struct UTUN_INSTANCE {
// Identification
uint64_t node_id;
char stats_dir[512]; // <config_dir>/stats/ для файлов метрик
struct SC_MYKEYS my_keys;
uint8_t my_ed25519_pubkey[SC_PUBKEY_SIZE]; // свой Ed25519 pubkey (для подписи метрик)

1
src/utun_instance_doc.md

@ -87,7 +87,6 @@ inst = utun_instance_reload(inst, ua, "utun.conf");
| `networks` | `struct ll_queue*` | Очередь сетей (NETWORK_ENTRY, индекс по 56-bit id) |
| `pending_connects` | `struct ETCP_CONNECT*` | Ожидающие фоновые подключения |
| `ntp` / `ntp_node` | `struct NTP_TIME` / `NTP_NODE_TIME` | Синхронизация времени |
| `stats_dir` | `char[512]` | Путь `<config_dir>/stats/` для файлов метрик |
| `next_socket_id` | `uint8_t` | Счётчик уникальных ID сокетов (0–255) |
| `socket_init_status` | `int` | Статус инициализации сокетов: 0=OK, 1=частично, -1=ошибка |
| `routed_packets` / `dropped_packets` | `uint64_t` | Счётчики маршрутизированных/отброшенных пакетов |

Loading…
Cancel
Save