@ -191,14 +191,10 @@ static void router_enqueue_send(struct ETCP_ROUTER_CONN* rconn, const uint8_t* p
// ACK timers
// ====================================================================
static void router_schedule_ack ( struct ETCP_ROUTER_CONN * rconn ) {
if ( rconn - > idle_ack_timer ) {
uasync_cancel_timeout ( rconn - > inst - > ua , rconn - > idle_ack_timer ) ;
rconn - > idle_ack_timer = NULL ;
}
if ( ! rconn - > ack_timer )
rconn - > ack_timer = uasync_set_timeout ( rconn - > inst - > ua ,
ROUTER_ACK_INTERVAL_TB , rconn , router_ack_timer_cb , " router_ack " ) ;
static void router_ack_do_send ( struct ETCP_ROUTER_CONN * rconn ) {
router_send_ack ( rconn ) ;
rconn - > last_sent_ack_seq = rconn - > rx_seq ;
rconn - > last_ack_sent_tb = get_time_tb ( ) ;
}
static void router_send_ack ( struct ETCP_ROUTER_CONN * rconn ) {
@ -227,28 +223,43 @@ static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) {
etcp_send ( conn , entry ) ;
}
static void router_schedule_ack ( struct ETCP_ROUTER_CONN * rconn ) {
if ( rconn - > idle_ack_timer ) {
uasync_cancel_timeout ( rconn - > inst - > ua , rconn - > idle_ack_timer ) ;
rconn - > idle_ack_timer = NULL ;
}
if ( rconn - > rx_seq = = rconn - > last_sent_ack_seq ) return ;
uint64_t now = get_time_tb ( ) ;
uint64_t elapsed = now - rconn - > last_ack_sent_tb ;
if ( elapsed > = ROUTER_ACK_INTERVAL_TB ) {
router_ack_do_send ( rconn ) ;
return ;
}
if ( ! rconn - > ack_timer )
rconn - > ack_timer = uasync_set_timeout ( rconn - > inst - > ua ,
ROUTER_ACK_INTERVAL_TB - ( uint32_t ) elapsed , rconn , router_ack_timer_cb , " router_ack " ) ;
}
static void router_ack_timer_cb ( void * arg ) {
struct ETCP_ROUTER_CONN * rconn = ( struct ETCP_ROUTER_CONN * ) arg ;
rconn - > ack_timer = NULL ;
if ( rconn - > rx_seq ! = rconn - > last_sent_ack_seq ) {
router_send_ack ( rconn ) ;
rconn - > last_sent_ack_seq = rconn - > rx_seq ;
}
if ( rconn - > rx_seq ! = rconn - > last_sent_ack_seq )
router_ack_do_send ( rconn ) ;
if ( rconn - > rx_seq ! = rconn - > last_sent_ack_seq ) {
if ( ! rconn - > ack_timer )
rconn - > ack_timer = uasync_set_timeout ( rconn - > inst - > ua ,
ROUTER_ACK_INTERVAL_TB , rconn , router_ack_timer_cb , " router_ack " ) ;
else
} else if ( ! rconn - > idle_ack_timer ) {
rconn - > idle_ack_timer = uasync_set_timeout ( rconn - > inst - > ua ,
ROUTER_ACK_IDLE_TB , rconn , router_idle_ack_timer_cb , " router_idle_ack " ) ;
}
}
static void router_idle_ack_timer_cb ( void * arg ) {
struct ETCP_ROUTER_CONN * rconn = ( struct ETCP_ROUTER_CONN * ) arg ;
rconn - > idle_ack_timer = NULL ;
if ( rconn - > rx_seq ! = rconn - > last_sent_ack_seq ) {
router_send_ack ( rconn ) ;
rconn - > last_sent_ack_seq = rconn - > rx_seq ;
}
if ( rconn - > rx_seq ! = rconn - > last_sent_ack_seq )
router_ack_do_send ( rconn ) ;
}
// ====================================================================
@ -380,7 +391,7 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
if ( seq = = rconn - > rx_seq )
router_try_assembly ( rconn , conn ) ;
router_schedule_ack ( rconn ) ;
if ( ! rconn - > consumer_ack ) router_schedule_ack ( rconn ) ;
queue_dgram_free ( entry ) ; queue_entry_free ( entry ) ;
} else {
// ========== Транзит ==========
@ -428,9 +439,9 @@ void etcp_router_destroy(struct UTUN_INSTANCE* inst) {
while ( ( entry = queue_data_get ( inst - > router_conns ) ) ! = NULL ) {
struct ETCP_ROUTER_CONN * rconn = ( struct ETCP_ROUTER_CONN * ) entry ;
router_send_close_to_service ( rconn ) ;
if ( rconn - > ack_timer ) uasync_cancel_timeout ( inst - > ua , rconn - > ack_timer ) ;
if ( rconn - > idle_ack_timer ) uasync_cancel_timeout ( inst - > ua , rconn - > idle_ack_timer ) ;
if ( rconn - > send_resume_timer ) uasync_cancel_timeout ( inst - > ua , rconn - > send_resume_timer ) ;
if ( rconn - > ack_timer ) { uasync_cancel_timeout ( inst - > ua , rconn - > ack_timer ) ; rconn - > ack_timer = NULL ; }
if ( rconn - > idle_ack_timer ) { uasync_cancel_timeout ( inst - > ua , rconn - > idle_ack_timer ) ; rconn - > idle_ack_timer = NULL ; }
if ( rconn - > send_resume_timer ) { uasync_cancel_timeout ( inst - > ua , rconn - > send_resume_timer ) ; rconn - > send_resume_timer = NULL ; }
if ( rconn - > recv_q ) {
struct ll_entry * f ;
while ( ( f = queue_data_get ( rconn - > recv_q ) ) ! = NULL ) { queue_dgram_free ( f ) ; queue_entry_free ( f ) ; }
@ -536,6 +547,13 @@ void etcp_router_waiter_cancel(struct UTUN_INSTANCE* inst, uint64_t peer_node_id
queue_waiter_cancel ( conn - > normalizer - > input , h ) ;
}
void etcp_router_consumer_ack ( struct UTUN_INSTANCE * inst , uint64_t remote_node_id , uint8_t svc_id ) {
struct ETCP_ROUTER_CONN * rconn = etcp_router_conn_get ( inst , remote_node_id , svc_id ) ;
if ( ! rconn ) return ;
rconn - > consumer_ack = 1 ;
router_schedule_ack ( rconn ) ;
}
// ====================================================================
// Seq-connection API
// ====================================================================
@ -556,6 +574,8 @@ struct ETCP_ROUTER_CONN* etcp_router_conn_get(struct UTUN_INSTANCE* inst,
rconn - > rx_seq = 0 ;
rconn - > tx_acked = 0 ;
rconn - > last_sent_ack_seq = 0 ;
rconn - > consumer_ack = 0 ;
rconn - > last_ack_sent_tb = 0 ;
rconn - > inst = inst ;
rconn - > ack_timer = NULL ;
rconn - > idle_ack_timer = NULL ;