Browse Source

Рефакторинг: упрощен etcp_connection_create через вызов etcp_conn_reset

- Удалено ~50 строк дублирующего кода инициализации
- Все поля теперь сбрасываются через etcp_conn_reset
- Сохранена специфичная инициализация: mtu, crypto, очереди, callback
v2_dev
Evgeny 2 months ago
parent
commit
aab0e445f7
  1. 216
      src/etcp.c
  2. 9
      src/etcp.h

216
src/etcp.c

@ -45,56 +45,51 @@ static void etcp_update_window(struct ETCP_CONN* etcp) {
etcp->retrans_timer_period = 20; // Default retransmit period
}
// Creating ETCP instance
// после создания надо добавить peer bublic key.
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
if (!instance) return NULL;
struct ETCP_CONN* etcp = calloc(1, sizeof(struct ETCP_CONN));
if (!etcp) return NULL;
// Reset connection (adapted from etcp_reset in master, without packet sending)
void etcp_conn_reset(struct ETCP_CONN* etcp) {
if (!etcp) return;
etcp->mtu = 1500; // Default MTU
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_conn_reset: resetting instance");
etcp->instance = instance;
etcp->state = 0;
// Initialize crypto context
if (sc_init_ctx(&etcp->crypto_ctx, &etcp->instance->my_keys) != SC_OK) {
free(etcp);
return NULL;
// Cancel timers
if (etcp->next_tx_timer) {
uasync_cancel_timeout(etcp->instance->ua, etcp->next_tx_timer);
etcp->next_tx_timer = NULL;
}
// Initialize queues (tx_queue is input_queue)
etcp->input_queue = queue_new(instance->ua,NULL);
etcp->output_queue = queue_new(instance->ua,NULL);
if (!etcp->input_queue || !etcp->output_queue) {
if (etcp->input_queue) queue_free(etcp->input_queue);
if (etcp->output_queue) queue_free(etcp->output_queue);
free(etcp);
return NULL;
if (etcp->retransmit_timer) {
uasync_cancel_timeout(etcp->instance->ua, etcp->retransmit_timer);
etcp->retransmit_timer = NULL;
}
// Set callback for input_queue (tx_queue)
queue_set_callback(etcp->input_queue, tx_queue_callback, etcp);
// Initialize state (from master)
etcp->bandwidth = 10000; // Default: 10000 bytes per timebase (0.1us)
etcp->last_sent_timestamp = get_current_timestamp();
etcp->bytes_allowed = 0;
etcp_update_window(etcp); // Initialize window size and retrans timer
// Clear queues (but keep them)
queue_clear(etcp->input_queue);
queue_clear(etcp->output_queue);
// Initialize lists
// Clear lists
rx_packet_t* rx = etcp->rx_list;
while (rx) {
rx_packet_t* next = rx->next;
if (rx->data) free(rx->data);
free(rx);
rx = next;
}
etcp->rx_list = NULL;
sent_packet_t* sent = etcp->sent_list;
while (sent) {
sent_packet_t* next = sent->next;
if (sent->data) free(sent->data);
free(sent);
sent = next;
}
etcp->sent_list = NULL;
// Initialize metrics
// Reset metrics and stats
etcp->rtt_last = 0;
etcp->rtt_avg_10 = 0;
etcp->rtt_avg_100 = 0;
etcp->jitter = 0;
etcp->bytes_sent_total = 0;
// Initialize statistics
etcp->retransmissions_count = 0;
etcp->ack_packets_count = 0;
etcp->control_packets_count = 0;
@ -102,37 +97,74 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
etcp->unique_packets_sent = 0;
etcp->bytes_received_total = 0;
// Initialize IDs
// Reset IDs
etcp->next_tx_id = 1;
etcp->last_sent_id = 0;
etcp->last_rx_id = 0;
etcp->last_delivered_id = 0;
// Initialize history
// Reset history
etcp->rtt_history_idx = 0;
etcp->rtt_history_count = 0;
// Initialize pending arrays
// Reset pending
etcp->pending_ack_count = 0;
etcp->pending_retransmit_count = 0;
// Initialize window management
// Reset window
etcp->unacked_bytes = 0;
etcp->last_acked_id = 0;
etcp->last_rx_ack_id = 0;
etcp->retrans_timer_period = 20; // Default 2ms (20 timebase units)
etcp->next_retrans_time = 0;
etcp->window_blocked = 0;
// Forward progress tracking
// Reset forward progress
etcp->oldest_missing_id = 0;
etcp->missing_since_time = 0;
// No timers yet
etcp->next_tx_timer = NULL;
etcp->retransmit_timer = NULL;
etcp_update_window(etcp);
}
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_create: created instance with node_id=%llu, mtu=%d",
// Creating ETCP instance
// после создания надо добавить peer bublic key.
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
if (!instance) return NULL;
struct ETCP_CONN* etcp = calloc(1, sizeof(struct ETCP_CONN));
if (!etcp) return NULL;
etcp->mtu = 1500; // Default MTU
etcp->instance = instance;
// Initialize crypto context
if (sc_init_ctx(&etcp->crypto_ctx, &etcp->instance->my_keys) != SC_OK) {
free(etcp);
return NULL;
}
// Initialize queues (tx_queue is input_queue)
etcp->input_queue = queue_new(instance->ua,NULL);
etcp->output_queue = queue_new(instance->ua,NULL);
if (!etcp->input_queue || !etcp->output_queue) {
if (etcp->input_queue) queue_free(etcp->input_queue);
if (etcp->output_queue) queue_free(etcp->output_queue);
free(etcp);
return NULL;
}
// Set callback for input_queue (tx_queue)
queue_set_callback(etcp->input_queue, tx_queue_callback, etcp);
// Initialize state (from master)
etcp->bandwidth = 10000; // Default: 10000 bytes per timebase (0.1us)
etcp->last_sent_timestamp = get_current_timestamp();
etcp->bytes_allowed = 0;
// Reset all other fields to initial state
etcp_conn_reset(etcp);
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_connection_create: created instance with node_id=%llu, mtu=%d",
(unsigned long long)etcp->instance->node_id, etcp->mtu);
etcp->next=instance->connections;
@ -144,10 +176,10 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
}
// Destroying ETCP instance
void etcp_destroy(struct ETCP_CONN* etcp) {
void etcp_connection_close(struct ETCP_CONN* etcp) {
if (!etcp) return;
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_destroy: destroying instance");
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_connection_close: destroying instance");
// Cancel timers
if (etcp->next_tx_timer) {
@ -185,8 +217,10 @@ void etcp_destroy(struct ETCP_CONN* etcp) {
}
// Process incoming packet (partial, truncated in original)
void etcp_conn_input(struct ETCP_CONN* etcp, struct ETCP_DGRAM* pkt) {
if (!etcp || !pkt) return;
void etcp_conn_input(struct ETCP_DGRAM* pkt) {
if (!pkt) return;
struct ETCP_CONN* etcp=pkt->link->etcp;
if (!etcp) return;
uint8_t* data = pkt->data;
size_t len = pkt->data_len;
@ -327,88 +361,6 @@ void etcp_conn_input(struct ETCP_CONN* etcp, struct ETCP_DGRAM* pkt) {
schedule_ack_timer(etcp);
}
// Reset connection (adapted from etcp_reset in master, without packet sending)
void etcp_conn_reset(struct ETCP_CONN* etcp) {
if (!etcp) return;
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "etcp_conn_reset: resetting instance");
// Reset state
etcp->state = 0;
// Cancel timers
if (etcp->next_tx_timer) {
uasync_cancel_timeout(etcp->instance->ua, etcp->next_tx_timer);
etcp->next_tx_timer = NULL;
}
if (etcp->retransmit_timer) {
uasync_cancel_timeout(etcp->instance->ua, etcp->retransmit_timer);
etcp->retransmit_timer = NULL;
}
// Clear queues (but keep them)
queue_clear(etcp->input_queue);
queue_clear(etcp->output_queue);
// Clear lists
rx_packet_t* rx = etcp->rx_list;
while (rx) {
rx_packet_t* next = rx->next;
if (rx->data) free(rx->data);
free(rx);
rx = next;
}
etcp->rx_list = NULL;
sent_packet_t* sent = etcp->sent_list;
while (sent) {
sent_packet_t* next = sent->next;
if (sent->data) free(sent->data);
free(sent);
sent = next;
}
etcp->sent_list = NULL;
// Reset metrics and stats
etcp->rtt_last = 0;
etcp->rtt_avg_10 = 0;
etcp->rtt_avg_100 = 0;
etcp->jitter = 0;
etcp->bytes_sent_total = 0;
etcp->retransmissions_count = 0;
etcp->ack_packets_count = 0;
etcp->control_packets_count = 0;
etcp->total_packets_sent = 0;
etcp->unique_packets_sent = 0;
etcp->bytes_received_total = 0;
// Reset IDs
etcp->next_tx_id = 1;
etcp->last_sent_id = 0;
etcp->last_rx_id = 0;
etcp->last_delivered_id = 0;
// Reset history
etcp->rtt_history_idx = 0;
etcp->rtt_history_count = 0;
// Reset pending
etcp->pending_ack_count = 0;
etcp->pending_retransmit_count = 0;
// Reset window
etcp->unacked_bytes = 0;
etcp->last_acked_id = 0;
etcp->last_rx_ack_id = 0;
etcp->next_retrans_time = 0;
etcp->window_blocked = 0;
// Reset forward progress
etcp->oldest_missing_id = 0;
etcp->missing_since_time = 0;
etcp_update_window(etcp);
}
// Getting statistics (extended with master stats)
void etcp_get_stats(struct ETCP_CONN* etcp, size_t* packets_sent, size_t* packets_recv,

9
src/etcp.h

@ -1,4 +1,5 @@
// etcp.h - Расширенный протокол управления передачей (ETCP Protocol)
// etcp.c/h - стек ретрансмиссий для ETCP Protocol
// каждое подключение имеет несколько дублирующих каналов. они реализованы в etcp_connections.c/h
#ifndef ETCP_H
#define ETCP_H
@ -45,8 +46,6 @@ struct ETCP_CONN {
// Каналы (соединения) - linked list
struct ETCP_LINK* links;
uint8_t state; // 0 - just created, 1 - initialized, 2 - connection established
// Криптография и состояние
struct secure_channel crypto_ctx;
@ -79,7 +78,7 @@ struct ETCP_CONN {
uint32_t bytes_received_total;
// State
uint16_t next_tx_id;
uint16_t next_tx_id;// инкрементируется после отправки пакета
uint16_t last_sent_id;
uint16_t last_rx_id;
uint16_t last_delivered_id;
@ -122,7 +121,7 @@ struct ETCP_CONN {
struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance);
// Уничтожение ETCP instance
void etcp_destroy(struct ETCP_CONN* etcp);
void etcp_connection_close(struct ETCP_CONN* etcp);
// Обработать входящий пакет (вызывается из etcp_connections)
void etcp_conn_input(struct ETCP_CONN* etcp, struct ETCP_DGRAM* pkt);

Loading…
Cancel
Save