Fix: Remove usleep from event loops and fix segfault in tests
- Removed usleep(5000) from all test event loops - Changed to use single shared uasync for server and client instances - Removed uasync_destroy from utun_instance_destroy to prevent double-free - Added explicit uasync_destroy calls in all tests and main program - Fixed segfault in test_pkt_normalizer_etcp and test_etcp_100_packets - Added DEBUG_TRACE to all functions in etcp.c and etcp_connections.c Tests now run without artificial delays and complete successfully.
This commit is contained in:
1 parent
8a3f01fbf8
commit
beafb9b198
20 files changed
+599
-251
No files matched your search
+67
-51
@@ -36,9 +36,10 @@ static void input_send_q_cb(struct ll_queue* q, void* arg);
|
||||
static void wait_ack_cb(struct ll_queue* q, void* arg);
|
||||
static void etcp_conn_process_send_queue(struct ETCP_CONN* etcp);
|
||||
|
||||
// Get current time in 0.1ms units
|
||||
uint64_t get_current_time_units() {
|
||||
struct timeval tv;
|
||||
// Get current time in 0.1ms units
|
||||
uint64_t get_current_time_units() {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
uint64_t time_units = ((uint64_t)tv.tv_sec * 10000ULL) + (tv.tv_usec / 100);
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "get_current_time_units: tv_sec=%ld, tv_usec=%ld, result=%llu",
|
||||
@@ -46,24 +47,26 @@ uint64_t get_current_time_units() {
|
||||
return time_units;
|
||||
}
|
||||
|
||||
uint16_t get_current_timestamp() {
|
||||
uint16_t timestamp = (uint16_t)(get_current_time_units() & 0xFFFF);
|
||||
uint16_t get_current_timestamp() {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
uint16_t timestamp = (uint16_t)(get_current_time_units() & 0xFFFF);
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "get_current_timestamp: result=%u", timestamp);
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
// Timestamp diff (with wrap-around)
|
||||
static uint16_t timestamp_diff(uint16_t t1, uint16_t t2) {
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "timestamp_diff: t1=%u, t2=%u", t1, t2);
|
||||
if (t1 >= t2) {
|
||||
// Timestamp diff (with wrap-around)
|
||||
static uint16_t timestamp_diff(uint16_t t1, uint16_t t2) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (t1 >= t2) {
|
||||
return t1 - t2;
|
||||
}
|
||||
return (UINT16_MAX - t2) + t1 + 1;
|
||||
}
|
||||
|
||||
// Create new ETCP connection
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
|
||||
if (!instance) return NULL;
|
||||
// Create new ETCP connection
|
||||
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!instance) return NULL;
|
||||
|
||||
|
||||
struct ETCP_CONN* etcp = calloc(1, sizeof(struct ETCP_CONN));
|
||||
@@ -122,9 +125,10 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
|
||||
return etcp;
|
||||
}
|
||||
|
||||
// Close connection with NULL pointer safety (prevents double free)
|
||||
void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
if (!etcp) return;
|
||||
// Close connection with NULL pointer safety (prevents double free)
|
||||
void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp) return;
|
||||
|
||||
// Drain and free input_queue (contains ETCP_FRAGMENT with pkt_data from data_pool)
|
||||
if (etcp->input_queue) {
|
||||
@@ -232,6 +236,7 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
|
||||
// Reset connection (stub)
|
||||
void etcp_conn_reset(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
// Reset IDs, queues, etc. as per protocol.txt
|
||||
etcp->next_tx_id = 1;
|
||||
etcp->last_rx_id = 0;
|
||||
@@ -241,6 +246,7 @@ void etcp_conn_reset(struct ETCP_CONN* etcp) {
|
||||
|
||||
// Update log_name when peer_node_id becomes known
|
||||
void etcp_update_log_name(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp || !etcp->instance) return;
|
||||
uint64_t local_id = etcp->instance->node_id % 10000;
|
||||
uint64_t peer_id = etcp->peer_node_id % 10000;
|
||||
@@ -251,11 +257,11 @@ void etcp_update_log_name(struct ETCP_CONN* etcp) {
|
||||
|
||||
// ====================================================================== Отправка данных
|
||||
|
||||
// Send data through ETCP connection
|
||||
// Allocates memory from data_pool and places in input queue
|
||||
// Returns: 0 on success, -1 on failure
|
||||
int etcp_send(struct ETCP_CONN* etcp, const void* data, uint16_t len) {
|
||||
// DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "etcp_send: ENTER etcp=%p, data=%p, len=%zu", etcp, data, len);
|
||||
// Send data through ETCP connection
|
||||
// Allocates memory from data_pool and places in input queue
|
||||
// Returns: 0 on success, -1 on failure
|
||||
int etcp_send(struct ETCP_CONN* etcp, const void* data, uint16_t len) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
|
||||
if (!etcp || !data || len == 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] invalid parameters (etcp=%p, data=%p, len=%zu)", etcp->log_name, etcp, data, len);
|
||||
@@ -314,7 +320,7 @@ int etcp_send(struct ETCP_CONN* etcp, const void* data, uint16_t len) {
|
||||
|
||||
|
||||
static void input_queue_try_resume(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "[%s] ENTER etcp=%p", etcp->log_name, etcp);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
|
||||
// если размер input_wait_ack+input_send_q в байтах < optimal_inflight то resume сейчас.
|
||||
size_t wait_ack_bytes = queue_total_bytes(etcp->input_wait_ack);
|
||||
@@ -330,6 +336,7 @@ static void input_queue_try_resume(struct ETCP_CONN* etcp) {
|
||||
}
|
||||
|
||||
void etcp_stats(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp) return;
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] stats for conn=%p:", etcp->log_name, etcp);
|
||||
@@ -371,10 +378,10 @@ void etcp_stats(struct ETCP_CONN* etcp) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] rx_ack_till: %u", etcp->log_name, etcp->rx_ack_till);
|
||||
}
|
||||
|
||||
// Input callback for input_queue (добавление новых кодограмм в стек)
|
||||
// input_queue -> input_send_q
|
||||
static void input_queue_cb(struct ll_queue* q, void* arg) {
|
||||
|
||||
// Input callback for input_queue (добавление новых кодограмм в стек)
|
||||
// input_queue -> input_send_q
|
||||
static void input_queue_cb(struct ll_queue* q, void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
struct ETCP_FRAGMENT* in_pkt = (struct ETCP_FRAGMENT*)queue_data_get(q);
|
||||
|
||||
@@ -423,8 +430,9 @@ static void input_queue_cb(struct ll_queue* q, void* arg) {
|
||||
}
|
||||
|
||||
|
||||
static void input_send_q_cb(struct ll_queue* q, void* arg) {// etcp->input_send_q processing
|
||||
struct ETCP_CONN* etcp=(struct ETCP_CONN*)arg;
|
||||
static void input_send_q_cb(struct ll_queue* q, void* arg) {// etcp->input_send_q processing
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_CONN* etcp=(struct ETCP_CONN*)arg;
|
||||
|
||||
// size_t send_q_bytes = queue_total_bytes(etcp->input_send_q);
|
||||
// size_t send_q_pkts = queue_entry_count(etcp->input_send_q);
|
||||
@@ -433,9 +441,10 @@ static void input_send_q_cb(struct ll_queue* q, void* arg) {// etcp->input_send_
|
||||
}
|
||||
|
||||
|
||||
static void ack_timeout_check(void* arg) {
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
uint64_t now = get_current_time_units();
|
||||
static void ack_timeout_check(void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
uint64_t now = get_current_time_units();
|
||||
uint64_t timeout = 1000;//(uint64_t)(etcp->rtt_avg_10 * RETRANS_K1) + (uint64_t)(etcp->jitter * RETRANS_K2);
|
||||
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "ack_timeout_check: starting check, now=%llu, timeout=%llu, rtt_avg_10=%u, jitter=%u",
|
||||
@@ -495,15 +504,16 @@ static void ack_timeout_check(void* arg) {
|
||||
queue_resume_callback(etcp->input_wait_ack);
|
||||
}
|
||||
|
||||
static void wait_ack_cb(struct ll_queue* q, void* arg) {
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
ack_timeout_check(etcp);// ack_cb срабатывает когда init (таймер не инициализирован) или когда empty (таймер не активен)
|
||||
static void wait_ack_cb(struct ll_queue* q, void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
ack_timeout_check(etcp);// ack_cb срабатывает когда init (таймер не инициализирован) или когда empty (таймер не активен)
|
||||
}
|
||||
|
||||
// Подготовить и отправить кодограмму
|
||||
// вызывается линком когда освобождается или очередью если появляются данные на передачу
|
||||
struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
|
||||
|
||||
// Подготовить и отправить кодограмму
|
||||
// вызывается линком когда освобождается или очередью если появляются данные на передачу
|
||||
struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_LINK* link = etcp_loadbalancer_select_link(etcp);
|
||||
if (!link) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] no link available", etcp->log_name);
|
||||
@@ -603,24 +613,27 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
|
||||
return dgram;
|
||||
}
|
||||
|
||||
// Callback for when a link is ready to send data
|
||||
static void etcp_link_ready_callback(struct ETCP_CONN* etcp) {
|
||||
if (!etcp) return;
|
||||
// Callback for when a link is ready to send data
|
||||
static void etcp_link_ready_callback(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp) return;
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_link_ready_callback: processing send queue for etcp=%p", etcp);
|
||||
etcp_conn_process_send_queue(etcp);
|
||||
}
|
||||
|
||||
// Process packets in send queue and transmit them
|
||||
static void etcp_conn_process_send_queue(struct ETCP_CONN* etcp) {
|
||||
struct ETCP_DGRAM* dgram;
|
||||
// Process packets in send queue and transmit them
|
||||
static void etcp_conn_process_send_queue(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_DGRAM* dgram;
|
||||
while(dgram = etcp_request_pkt(etcp)) {
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_conn_process_send_queue: sending packet");
|
||||
etcp_loadbalancer_send(dgram);
|
||||
}
|
||||
}
|
||||
|
||||
static void ack_response_timer_cb(void* arg) {// проверяем неотправленные ack response и отправляем если надо.
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
static void ack_response_timer_cb(void* arg) {// проверяем неотправленные ack response и отправляем если надо.
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
struct ETCP_CONN* etcp = (struct ETCP_CONN*)arg;
|
||||
etcp_conn_process_send_queue(etcp);// проталкиваем (она же должна отправлять только ack если больше ничего нет)
|
||||
// если ack все еще заняты - обновляем таймаут
|
||||
if (etcp->ack_q->count) etcp->ack_resp_timer = uasync_set_timeout(etcp->instance->ua, ACK_DELAY_TB, etcp, ack_response_timer_cb);
|
||||
@@ -631,6 +644,7 @@ static void ack_response_timer_cb(void* arg) {// проверяем неотпр
|
||||
|
||||
|
||||
void etcp_output_try_assembly(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
// пробуем собрать выходную очередь из фрагментов
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] etcp=%p, last_delivered_id=%u, recv_q_count=%d",
|
||||
// etcp->log_name, etcp, etcp->last_delivered_id, queue_entry_count(etcp->recv_q));
|
||||
@@ -678,9 +692,10 @@ void etcp_output_try_assembly(struct ETCP_CONN* etcp) {
|
||||
etcp->log_name, delivered_count, delivered_bytes, etcp->last_delivered_id, queue_entry_count(etcp->output_queue));
|
||||
}
|
||||
|
||||
// Process ACK receipt - remove acknowledged packet from inflight queues
|
||||
void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t dts) {
|
||||
if (!etcp) return;
|
||||
// Process ACK receipt - remove acknowledged packet from inflight queues
|
||||
void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t dts) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!etcp) return;
|
||||
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] processing ACK for seq=%u, ts=%u, dts=%u", etcp->log_name, seq, ts, dts);
|
||||
|
||||
@@ -747,9 +762,10 @@ void etcp_ack_recv(struct ETCP_CONN* etcp, uint32_t seq, uint16_t ts, uint16_t d
|
||||
}
|
||||
|
||||
|
||||
// Process incoming decrypted packet
|
||||
void etcp_conn_input(struct ETCP_DGRAM* pkt) {
|
||||
if (!pkt || !pkt->data_len) return;
|
||||
// Process incoming decrypted packet
|
||||
void etcp_conn_input(struct ETCP_DGRAM* pkt) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
if (!pkt || !pkt->data_len) return;
|
||||
|
||||
struct ETCP_CONN* etcp = pkt->link->etcp;
|
||||
uint8_t* data = pkt->data;
|
||||
|
||||
@@ -24,6 +24,7 @@ static void etcp_link_remove_from_connections(struct ETCP_SOCKET* conn, struct E
|
||||
|
||||
// Unified packet dump function - uses configured format
|
||||
static void packet_dump(const char* prefix, const uint8_t* data, size_t len, struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!data || len == 0) return;
|
||||
|
||||
// Full multi-line format (legacy)
|
||||
@@ -39,6 +40,7 @@ static void etcp_link_init_timer_cbk(void* arg);
|
||||
#define INIT_TIMEOUT_MAX 50000
|
||||
|
||||
static void etcp_link_send_init(struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_init link=%p, is_server=%d", link, link ? link->is_server : -1);
|
||||
if (!link || !link->etcp || !link->etcp->instance) return;
|
||||
|
||||
@@ -104,6 +106,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link) {
|
||||
}
|
||||
|
||||
static void etcp_link_init_timer_cbk(void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
struct ETCP_LINK* link = (struct ETCP_LINK*)arg;
|
||||
if (!link || link->initialized || link->is_server != 0) return;
|
||||
|
||||
@@ -112,6 +115,7 @@ static void etcp_link_init_timer_cbk(void* arg) {
|
||||
}
|
||||
|
||||
static int etcp_link_send_reset(struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!link) return -1;
|
||||
|
||||
struct ETCP_DGRAM* dgram = malloc(sizeof(struct ETCP_DGRAM) + 1);
|
||||
@@ -132,12 +136,14 @@ static int etcp_link_send_reset(struct ETCP_LINK* link) {
|
||||
}
|
||||
|
||||
static uint32_t sockaddr_hash(struct sockaddr_storage* addr) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
socklen_t addr_len = (addr->ss_family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
|
||||
return crc32_calc((void*)addr, addr_len);
|
||||
}
|
||||
|
||||
// Бинарный поиск линка по ip_port_hash
|
||||
static int find_link_index(struct ETCP_SOCKET* e_sock, uint32_t hash) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!e_sock || e_sock->num_channels == 0) return -1;
|
||||
|
||||
int left = 0;
|
||||
@@ -159,6 +165,7 @@ static int find_link_index(struct ETCP_SOCKET* e_sock, uint32_t hash) {
|
||||
|
||||
// Реалокация массива линков с увеличением в 2 раза
|
||||
static int realloc_links(struct ETCP_SOCKET* e_sock) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
size_t new_max = e_sock->max_channels == 0 ? 8 : e_sock->max_channels * 2;
|
||||
struct ETCP_LINK** new_links = realloc(e_sock->links, new_max * sizeof(struct ETCP_LINK*));
|
||||
if (!new_links) {
|
||||
@@ -173,6 +180,7 @@ static int realloc_links(struct ETCP_SOCKET* e_sock) {
|
||||
|
||||
// Вставка линка в отсортированный массив
|
||||
static int insert_link(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!e_sock || !link) return -1;
|
||||
|
||||
if (e_sock->num_channels >= e_sock->max_channels) {
|
||||
@@ -196,6 +204,7 @@ static int insert_link(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link) {
|
||||
|
||||
// Удаление линка из массива
|
||||
static void remove_link(struct ETCP_SOCKET* e_sock, uint32_t hash) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!e_sock || e_sock->num_channels == 0) return;
|
||||
|
||||
int idx = find_link_index(e_sock, hash);
|
||||
@@ -211,6 +220,7 @@ static void remove_link(struct ETCP_SOCKET* e_sock, uint32_t hash) {
|
||||
|
||||
// надо править, используй sockaddr_hash
|
||||
struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sockaddr_storage* addr) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!e_sock || !addr) return NULL;
|
||||
|
||||
int idx = find_link_index(e_sock, sockaddr_hash(addr));
|
||||
@@ -220,6 +230,7 @@ struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sock
|
||||
}
|
||||
|
||||
int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!etcp) return -1;
|
||||
|
||||
// Битовый массив для 256 id (32 байта * 8 бит = 256)
|
||||
@@ -254,6 +265,7 @@ int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) {
|
||||
// ===============================
|
||||
|
||||
struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct sockaddr_storage* ip, uint32_t netif_index, int so_mark, uint8_t type) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!instance) return NULL;
|
||||
|
||||
struct ETCP_SOCKET* e_sock = calloc(1, sizeof(struct ETCP_SOCKET));
|
||||
@@ -368,6 +380,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct socka
|
||||
}
|
||||
|
||||
void etcp_socket_remove(struct ETCP_SOCKET* conn) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!conn) return;
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Removing socket %p, fd=%d, socket_id=%p", conn, conn->fd, conn->socket_id);
|
||||
@@ -395,6 +408,7 @@ void etcp_socket_remove(struct ETCP_SOCKET* conn) {
|
||||
|
||||
|
||||
struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn, struct sockaddr_storage* remote_addr, uint8_t is_server) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!remote_addr) return NULL;
|
||||
|
||||
struct ETCP_LINK* link = calloc(1, sizeof(struct ETCP_LINK));
|
||||
@@ -442,6 +456,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
|
||||
}
|
||||
|
||||
void etcp_link_close(struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!link || !link->etcp) return;
|
||||
|
||||
// Cancel init timer if active
|
||||
@@ -466,6 +481,7 @@ void etcp_link_close(struct ETCP_LINK* link) {
|
||||
}
|
||||
|
||||
int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_encrypt_send called, link=%p", dgram ? dgram->link : NULL);
|
||||
// printf("[ETCP DEBUG] etcp_encrypt_send: ENTERING FUNCTION\n");
|
||||
|
||||
@@ -479,7 +495,9 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
|
||||
// DUMP: Show packet before encryption
|
||||
// log_dump("ECTP_ENCRYPT_SEND", dgram->data, dgram->data_len);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Encrypt start");
|
||||
sc_encrypt(sc, (uint8_t*)&dgram->timestamp/*не править это, тут верно!*/, sizeof(uint16_t) + len, enc_buf, &enc_buf_len);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Encrypt end");
|
||||
if (enc_buf_len == 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_encrypt_send: encryption failed for node %llu", (unsigned long long)dgram->link->etcp->instance->node_id);
|
||||
dgram->link->send_errors++;
|
||||
@@ -518,6 +536,7 @@ es_err:
|
||||
}
|
||||
|
||||
static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_connections_read_callback fd=%d, socket=%p", fd, arg);
|
||||
// !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!!
|
||||
// НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!!
|
||||
@@ -652,6 +671,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Decrypt start");
|
||||
if (sc_decrypt(&link->etcp->crypto_ctx, data, recv_len, (uint8_t*)&pkt->timestamp, &pkt_len)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "etcp_connections_read_callback: failed to decrypt packet from node %llu len=%d", (unsigned long long)link->etcp->instance->node_id, recv_len);
|
||||
// log_dump("my_privkey",&link->etcp->crypto_ctx.pk->private_key, SC_PRIVKEY_SIZE);
|
||||
@@ -660,6 +680,7 @@ static void etcp_connections_read_callback(int fd, void* arg) {
|
||||
errorcode=6;
|
||||
goto ec_fr;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Decrypt end");
|
||||
if (pkt_len<3) { errorcode=46; DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "etcp_connections_read_callback: decrypted packet too small, size=%zu", pkt_len); goto ec_fr; }
|
||||
pkt->data_len=pkt_len-2;
|
||||
pkt->noencrypt_len=0;
|
||||
@@ -718,6 +739,7 @@ ec_fr:
|
||||
}
|
||||
|
||||
int init_connections(struct UTUN_INSTANCE* instance) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!instance || !instance->config) return -1;
|
||||
|
||||
struct utun_config* config = instance->config;
|
||||
|
||||
+7
-1
@@ -326,7 +326,13 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
utun_instance_unregister_sockets(instance);
|
||||
utun_instance_destroy(instance);
|
||||
|
||||
// Destroy uasync instance after instance is destroyed
|
||||
if (ua) {
|
||||
uasync_destroy(ua, 0);
|
||||
}
|
||||
|
||||
remove_pidfile(args.pid_file);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
+3
-6
@@ -227,12 +227,9 @@ void utun_instance_destroy(struct UTUN_INSTANCE *instance) {
|
||||
instance->data_pool = NULL;
|
||||
}
|
||||
|
||||
// FINALLY destroy uasync (after all resources are cleaned up)
|
||||
if (instance->ua) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "[INSTANCE_DESTROY] Destroying uasync instance");
|
||||
uasync_destroy(instance->ua, 0);
|
||||
instance->ua = NULL;
|
||||
}
|
||||
// Note: uasync is NOT destroyed here - caller must destroy it separately
|
||||
// This allows sharing uasync between multiple instances
|
||||
instance->ua = NULL;
|
||||
|
||||
// Clear global instance
|
||||
if (g_instance == instance) {
|
||||
|
||||
Reference in new issue
Block a user