|
|
|
@ -38,6 +38,34 @@ 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 wait_ack_cb(struct ll_queue* q, void* arg); |
|
|
|
static void etcp_conn_process_send_queue(struct ETCP_CONN* etcp); |
|
|
|
static void etcp_conn_process_send_queue(struct ETCP_CONN* etcp); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Helper function to drain and free ETCP_FRAGMENT queue
|
|
|
|
|
|
|
|
static void drain_and_free_fragment_queue(struct ETCP_CONN* etcp, struct ll_queue** q) { |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(*q); |
|
|
|
|
|
|
|
*q = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 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; |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(*q); |
|
|
|
|
|
|
|
*q = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Get current time in 0.1ms units
|
|
|
|
// Get current time in 0.1ms units
|
|
|
|
uint64_t get_current_time_units() { |
|
|
|
uint64_t get_current_time_units() { |
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, ""); |
|
|
|
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, ""); |
|
|
|
@ -149,59 +177,14 @@ void etcp_connection_close(struct ETCP_CONN* etcp) { |
|
|
|
etcp->normalizer = NULL; |
|
|
|
etcp->normalizer = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Drain and free input_queue (contains ETCP_FRAGMENT with pkt_data from data_pool)
|
|
|
|
// Drain and free all queues using helper functions
|
|
|
|
if (etcp->input_queue) { |
|
|
|
drain_and_free_fragment_queue(etcp, &etcp->input_queue); |
|
|
|
struct ETCP_FRAGMENT* pkt; |
|
|
|
drain_and_free_fragment_queue(etcp, &etcp->output_queue); |
|
|
|
while ((pkt = (struct ETCP_FRAGMENT*)queue_data_get(etcp->input_queue)) != NULL) { |
|
|
|
drain_and_free_inflight_queue(etcp, &etcp->input_send_q); |
|
|
|
if (pkt->ll.dgram) { |
|
|
|
drain_and_free_inflight_queue(etcp, &etcp->input_wait_ack); |
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
drain_and_free_fragment_queue(etcp, &etcp->recv_q); |
|
|
|
} |
|
|
|
|
|
|
|
memory_pool_free(etcp->io_pool, pkt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(etcp->input_queue); |
|
|
|
|
|
|
|
etcp->input_queue = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Drain and free output_queue (contains ETCP_FRAGMENT with pkt_data from data_pool)
|
|
|
|
// Drain and free ack_q (contains ACK_PACKET from ack_pool - special handling)
|
|
|
|
if (etcp->output_queue) { |
|
|
|
|
|
|
|
struct ETCP_FRAGMENT* pkt; |
|
|
|
|
|
|
|
while ((pkt = (struct ETCP_FRAGMENT*)queue_data_get(etcp->output_queue)) != NULL) { |
|
|
|
|
|
|
|
if (pkt->ll.dgram) { |
|
|
|
|
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
memory_pool_free(etcp->io_pool, pkt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(etcp->output_queue); |
|
|
|
|
|
|
|
etcp->output_queue = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Drain and free input_send_q (contains INFLIGHT_PACKET with pkt_data from data_pool)
|
|
|
|
|
|
|
|
if (etcp->input_send_q) { |
|
|
|
|
|
|
|
struct INFLIGHT_PACKET* pkt; |
|
|
|
|
|
|
|
while ((pkt = (struct INFLIGHT_PACKET*)queue_data_get(etcp->input_send_q)) != NULL) { |
|
|
|
|
|
|
|
if (pkt->ll.dgram) { |
|
|
|
|
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
memory_pool_free(etcp->inflight_pool, pkt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(etcp->input_send_q); |
|
|
|
|
|
|
|
etcp->input_send_q = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Drain and free input_wait_ack (contains INFLIGHT_PACKET with pkt_data from data_pool)
|
|
|
|
|
|
|
|
if (etcp->input_wait_ack) { |
|
|
|
|
|
|
|
struct INFLIGHT_PACKET* pkt; |
|
|
|
|
|
|
|
while ((pkt = (struct INFLIGHT_PACKET*)queue_data_get(etcp->input_wait_ack)) != NULL) { |
|
|
|
|
|
|
|
if (pkt->ll.dgram) { |
|
|
|
|
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
memory_pool_free(etcp->inflight_pool, pkt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(etcp->input_wait_ack); |
|
|
|
|
|
|
|
etcp->input_wait_ack = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Drain and free ack_q (contains ACK_PACKET from ack_pool)
|
|
|
|
|
|
|
|
if (etcp->ack_q) { |
|
|
|
if (etcp->ack_q) { |
|
|
|
struct ACK_PACKET* pkt; |
|
|
|
struct ACK_PACKET* pkt; |
|
|
|
while ((pkt = (struct ACK_PACKET*)queue_data_get(etcp->ack_q)) != NULL) { |
|
|
|
while ((pkt = (struct ACK_PACKET*)queue_data_get(etcp->ack_q)) != NULL) { |
|
|
|
@ -211,19 +194,6 @@ void etcp_connection_close(struct ETCP_CONN* etcp) { |
|
|
|
etcp->ack_q = NULL; |
|
|
|
etcp->ack_q = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Drain and free recv_q (contains ETCP_FRAGMENT with pkt_data from data_pool)
|
|
|
|
|
|
|
|
if (etcp->recv_q) { |
|
|
|
|
|
|
|
struct ETCP_FRAGMENT* pkt; |
|
|
|
|
|
|
|
while ((pkt = (struct ETCP_FRAGMENT*)queue_data_get(etcp->recv_q)) != NULL) { |
|
|
|
|
|
|
|
if (pkt->ll.dgram) { |
|
|
|
|
|
|
|
memory_pool_free(etcp->instance->data_pool, pkt->ll.dgram); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
memory_pool_free(etcp->io_pool, pkt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
queue_free(etcp->recv_q); |
|
|
|
|
|
|
|
etcp->recv_q = NULL; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Free memory pools after all elements are returned
|
|
|
|
// Free memory pools after all elements are returned
|
|
|
|
if (etcp->inflight_pool) { |
|
|
|
if (etcp->inflight_pool) { |
|
|
|
memory_pool_destroy(etcp->inflight_pool); |
|
|
|
memory_pool_destroy(etcp->inflight_pool); |
|
|
|
|