@ -96,6 +96,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
etcp - > io_pool = memory_pool_init ( sizeof ( struct ETCP_FRAGMENT ) ) ;
etcp - > optimal_inflight = 10000 ;
etcp - > initialized = 0 ;
etcp - > links_up = 0 ;
etcp - > name = u_strdup ( name ) ;
// Initialize log_name with local node_id (peer will be updated later when known)
snprintf ( etcp - > log_name , sizeof ( etcp - > log_name ) , " %04X->???? [%s] " , ( uint16_t ) instance - > node_id , etcp - > name ) ;
@ -144,11 +145,25 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
}
static void etcp_on_up ( struct ETCP_CONN * etcp ) {
if ( etcp - > up_cbk ) etcp - > up_cbk ( etcp , etcp - > up_arg ) ;
}
static void etcp_on_down ( struct ETCP_CONN * etcp ) {
if ( etcp - > down_cbk ) etcp - > down_cbk ( etcp , etcp - > down_arg ) ;
}
// 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 ;
if ( etcp - > links_up ! = 0 ) {
etcp - > links_up = 0 ;
etcp_on_down ( etcp ) ;
}
// Cancel active timers to prevent memory leaks
if ( etcp - > retrans_timer ) {
uasync_cancel_timeout ( etcp - > instance - > ua , etcp - > retrans_timer ) ;
@ -273,6 +288,24 @@ void etcp_conn_reset(struct ETCP_CONN* etcp) {
etcp - > tx_state = ETCP_TX_STATE_DATA_WAIT ;
int up = 0 ;
struct ETCP_LINK * link = etcp - > links ;
while ( link ) {
if ( link - > link_status ) up = 1 ;
link = link - > next ;
}
if ( up ) {
if ( etcp - > links_up = = 0 ) {
etcp - > links_up = 1 ;
etcp_on_up ( etcp ) ;
} else {
etcp_on_down ( etcp ) ;
etcp_on_up ( etcp ) ;
}
}
DEBUG_TRACE ( DEBUG_CATEGORY_ETCP , " end " ) ;
}
@ -296,7 +329,7 @@ void etcp_conn_reinit(struct ETCP_CONN* etcp) {// Если сбой в обме
DEBUG_TRACE ( DEBUG_CATEGORY_ETCP , " end " ) ;
}
// внутренняя функция. Вызывается стеком etcp когда соединение установлено (можно передавать данные)
// внутренняя функция. Вызывается один раз когда первый линк готов.
void etcp_conn_ready ( struct ETCP_CONN * conn ) {
if ( ! conn ) return ;
@ -583,13 +616,34 @@ static void send_ack_req_cb(struct ll_queue* q, void* arg) {// etcp->ack_q data
if ( etcp - > tx_state = = ETCP_TX_STATE_DATA_WAIT ) queue_resume_callback ( etcp - > ack_q ) ;
}
void etcp_on_link_down ( struct ETCP_CONN * etcp ) {
// scan all links ->
int up = 0 ;
struct ETCP_LINK * link = etcp - > links ;
while ( link ) {
if ( link - > link_status ) up = 1 ;
link = link - > next ;
}
etcp - > links_up = up ;
if ( up = = 0 & & etcp - > links_up ! = 0 ) {
etcp - > links_up = 0 ;
etcp_on_down ( etcp ) ;
}
}
static void etcp_link_ready_callback ( struct ETCP_CONN * etcp ) {
DEBUG_TRACE ( DEBUG_CATEGORY_ETCP , " " ) ;
if ( ! etcp ) return ;
if ( etcp - > tx_state ! = ETCP_TX_STATE_LINK_WAIT ) return ;
etcp - > tx_state = ETCP_TX_STATE_DATA_WAIT ;
queue_resume_callback ( etcp - > input_send_q ) ;
queue_resume_callback ( etcp - > ack_q ) ;
if ( etcp - > links_up = = 0 ) {
etcp - > links_up = 1 ;
etcp_on_up ( etcp ) ;
}
}
static void ack_response_timer_cb ( void * arg ) { // проверяем неотправленные ack response и отправляем если надо.