@ -115,33 +115,82 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance) {
void etcp_connection_close ( struct ETCP_CONN * etcp ) {
void etcp_connection_close ( struct ETCP_CONN * etcp ) {
if ( ! etcp ) return ;
if ( ! etcp ) return ;
// Free queues only if they exist, then nullify to prevent double free
// Drain and free input_queue (contains ETCP_FRAGMENT with pkt_data from data_pool)
if ( etcp - > input_queue ) {
if ( etcp - > input_queue ) {
struct ETCP_FRAGMENT * pkt ;
while ( ( pkt = queue_data_get ( etcp - > input_queue ) ) ! = NULL ) {
if ( pkt - > pkt_data ) {
memory_pool_free ( etcp - > instance - > data_pool , pkt - > pkt_data ) ;
}
memory_pool_free ( etcp - > rx_pool , pkt ) ;
}
queue_free ( etcp - > input_queue ) ;
queue_free ( etcp - > input_queue ) ;
etcp - > input_queue = NULL ;
etcp - > input_queue = NULL ;
}
}
// Drain and free output_queue (contains ETCP_FRAGMENT with pkt_data from data_pool)
if ( etcp - > output_queue ) {
if ( etcp - > output_queue ) {
struct ETCP_FRAGMENT * pkt ;
while ( ( pkt = queue_data_get ( etcp - > output_queue ) ) ! = NULL ) {
if ( pkt - > pkt_data ) {
memory_pool_free ( etcp - > instance - > data_pool , pkt - > pkt_data ) ;
}
memory_pool_free ( etcp - > rx_pool , pkt ) ;
}
queue_free ( etcp - > output_queue ) ;
queue_free ( etcp - > output_queue ) ;
etcp - > output_queue = NULL ;
etcp - > output_queue = NULL ;
}
}
// Drain and free input_send_q (contains INFLIGHT_PACKET with pkt_data from data_pool)
if ( etcp - > input_send_q ) {
if ( etcp - > input_send_q ) {
struct INFLIGHT_PACKET * pkt ;
while ( ( pkt = queue_data_get ( etcp - > input_send_q ) ) ! = NULL ) {
if ( pkt - > pkt_data ) {
memory_pool_free ( etcp - > instance - > data_pool , pkt - > pkt_data ) ;
}
memory_pool_free ( etcp - > inflight_pool , pkt ) ;
}
queue_free ( etcp - > input_send_q ) ;
queue_free ( etcp - > input_send_q ) ;
etcp - > input_send_q = NULL ;
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 ) {
if ( etcp - > input_wait_ack ) {
struct INFLIGHT_PACKET * pkt ;
while ( ( pkt = queue_data_get ( etcp - > input_wait_ack ) ) ! = NULL ) {
if ( pkt - > pkt_data ) {
memory_pool_free ( etcp - > instance - > data_pool , pkt - > pkt_data ) ;
}
memory_pool_free ( etcp - > inflight_pool , pkt ) ;
}
queue_free ( etcp - > input_wait_ack ) ;
queue_free ( etcp - > input_wait_ack ) ;
etcp - > input_wait_ack = NULL ;
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 ;
while ( ( pkt = queue_data_get ( etcp - > ack_q ) ) ! = NULL ) {
queue_data_free ( pkt ) ;
}
queue_free ( etcp - > ack_q ) ;
queue_free ( etcp - > ack_q ) ;
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 ) {
if ( etcp - > recv_q ) {
struct ETCP_FRAGMENT * pkt ;
while ( ( pkt = queue_data_get ( etcp - > recv_q ) ) ! = NULL ) {
if ( pkt - > pkt_data ) {
memory_pool_free ( etcp - > instance - > data_pool , pkt - > pkt_data ) ;
}
memory_pool_free ( etcp - > rx_pool , pkt ) ;
}
queue_free ( etcp - > recv_q ) ;
queue_free ( etcp - > recv_q ) ;
etcp - > recv_q = NULL ;
etcp - > recv_q = NULL ;
}
}
// Free memory pool only if it exists
// 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 ) ;
etcp - > inflight_pool = NULL ;
etcp - > inflight_pool = NULL ;