|
|
|
|
@ -52,6 +52,30 @@ static void drain_and_free_fragment_queue(struct ETCP_CONN* etcp, struct ll_queu
|
|
|
|
|
*q = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Helper function to clear INFLIGHT_PACKET queue (keep queue, free elements)
|
|
|
|
|
static void clear_inflight_queue(struct ll_queue* q, struct ETCP_CONN* etcp) { |
|
|
|
|
if (!q) return; |
|
|
|
|
struct INFLIGHT_PACKET* pkt; |
|
|
|
|
while ((pkt = (struct INFLIGHT_PACKET*)queue_data_get(q)) != NULL) { |
|
|
|
|
if (pkt->ll.dgram) { |
|
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
|
} |
|
|
|
|
memory_pool_free(etcp->inflight_pool, pkt); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Helper function to clear ETCP_FRAGMENT queue (keep queue, free elements)
|
|
|
|
|
static void clear_fragment_queue(struct ll_queue* q, struct ETCP_CONN* etcp) { |
|
|
|
|
if (!q) return; |
|
|
|
|
struct ETCP_FRAGMENT* pkt; |
|
|
|
|
while ((pkt = (struct ETCP_FRAGMENT*)queue_data_get(q)) != NULL) { |
|
|
|
|
if (pkt->ll.dgram) { |
|
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
|
} |
|
|
|
|
memory_pool_free(etcp->io_pool, pkt); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Helper function to drain and free INFLIGHT_PACKET queue
|
|
|
|
|
static void drain_and_free_inflight_queue(struct ETCP_CONN* etcp, struct ll_queue** q) { |
|
|
|
|
if (!*q) return; |
|
|
|
|
@ -219,14 +243,37 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
|
|
|
|
|
free(etcp); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Reset connection (stub)
|
|
|
|
|
// Reset connection
|
|
|
|
|
void etcp_conn_reset(struct ETCP_CONN* etcp) { |
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, ""); |
|
|
|
|
// Reset IDs, queues, etc. as per protocol.txt
|
|
|
|
|
// Reset IDs
|
|
|
|
|
etcp->next_tx_id = 1; |
|
|
|
|
etcp->last_rx_id = 0; |
|
|
|
|
etcp->last_delivered_id = 0; |
|
|
|
|
// Clear inflight, rx_list, etc.
|
|
|
|
|
etcp->rx_ack_till = 0; |
|
|
|
|
|
|
|
|
|
// Reset metrics
|
|
|
|
|
etcp->unacked_bytes = 0; |
|
|
|
|
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; |
|
|
|
|
|
|
|
|
|
// Reset RTT history
|
|
|
|
|
memset(etcp->rtt_history, 0, sizeof(etcp->rtt_history)); |
|
|
|
|
etcp->rtt_history_idx = 0; |
|
|
|
|
|
|
|
|
|
// Clear queues (keep queue structures)
|
|
|
|
|
clear_inflight_queue(etcp->input_send_q, etcp); |
|
|
|
|
clear_inflight_queue(etcp->input_wait_ack, etcp); |
|
|
|
|
clear_fragment_queue(etcp->recv_q, etcp); |
|
|
|
|
|
|
|
|
|
// Reset timers (just clear the pointers - timers will expire naturally)
|
|
|
|
|
etcp->retrans_timer = NULL; |
|
|
|
|
etcp->ack_resp_timer = NULL; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Update log_name when peer_node_id becomes known
|
|
|
|
|
@ -398,6 +445,7 @@ static void input_queue_cb(struct ll_queue* q, void* arg) {
|
|
|
|
|
p->ll.len = in_pkt->ll.len; |
|
|
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] input -> inflight (seq=%u, len=%u)", etcp->log_name, p->seq, p->ll.len); |
|
|
|
|
int len=p->ll.len;// сохраним len
|
|
|
|
|
|
|
|
|
|
// Add to send queue
|
|
|
|
|
if (queue_data_put(etcp->input_send_q, (struct ll_entry*)p, p->seq) != 0) { |
|
|
|
|
@ -407,6 +455,8 @@ static void input_queue_cb(struct ll_queue* q, void* arg) {
|
|
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "[%s] EXIT (queue put failed)", etcp->log_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
etcp->unacked_bytes += len; |
|
|
|
|
|
|
|
|
|
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "input_queue_cb: successfully moved from input_queue to input_send_q");
|
|
|
|
|
|
|
|
|
|
etcp_conn_process_send_queue(etcp);// сразу обработаем этот пакет
|
|
|
|
|
|