@ -64,6 +64,14 @@ static int router_send_one_flags(struct ETCP_ROUTER_CONN* rconn, const uint8_t*
hdr - > src_node_id = inst - > node_id ;
hdr - > seq = seq ;
hdr - > svc_id = rconn - > svc_id ;
{
uint8_t f = ( rconn - > sess_id < < ROUTER_SESS_ID_SHIFT ) ;
if ( ! rconn - > start_sent & & pl_len > 0 & & ! ( seq_flags & ( ROUTER_SEQ_CLOSE_FLAG | ROUTER_SEQ_RST_FLAG ) ) ) {
f | = ROUTER_FLAG_START ;
rconn - > start_sent = 1 ;
}
hdr - > flags = f ;
}
if ( pl_len > 0 ) memcpy ( dgram + SVC_ROUTE_HDR_SIZE , payload , pl_len ) ;
struct ll_entry * entry = queue_entry_new ( 0 ) ;
@ -222,6 +230,7 @@ static void router_send_ack(struct ETCP_ROUTER_CONN* rconn) {
hdr - > src_node_id = inst - > node_id ;
hdr - > seq = rconn - > rx_seq ;
hdr - > svc_id = rconn - > svc_id ;
hdr - > flags = ( rconn - > sess_id < < ROUTER_SESS_ID_SHIFT ) ;
struct ll_entry * entry = queue_entry_new ( 0 ) ;
if ( ! entry ) { u_free ( hdr ) ; return ; }
@ -368,13 +377,27 @@ static void etcp_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
if ( ! rconn ) { queue_dgram_free ( entry ) ; queue_entry_free ( entry ) ; return ; }
}
// Обнаружение перезапуска peer'a: seq=0 при rx_seq >= MAX_INFLIGHT
if ( rconn - > rx_seq > = ( uint32_t ) ROUTER_MAX_INFLIGHT & & hdr - > seq = = 0 & & pl_len > 0 ) {
DEBUG_INFO ( DEBUG_CATEGORY_ETCPROUTE , " router: peer restart detected svc_id=%u from %016llx — resetting " ,
hdr - > svc_id , ( unsigned long long ) hdr - > src_node_id ) ;
etcp_router_conn_restart ( inst , hdr - > src_node_id , hdr - > svc_id ) ;
rconn = etcp_router_conn_get ( inst , hdr - > src_node_id , hdr - > svc_id ) ;
if ( ! rconn ) { queue_dgram_free ( entry ) ; queue_entry_free ( entry ) ; return ; }
// Обнаружение перезапуска peer'а: новый sess_id или START-флаг
{
uint8_t incoming_sess = ( hdr - > flags > > ROUTER_SESS_ID_SHIFT ) & 0x3 ;
if ( pl_len > 0 & & ( incoming_sess ! = rconn - > peer_sess_id | | ( hdr - > flags & ROUTER_FLAG_START ) ) ) {
DEBUG_INFO ( DEBUG_CATEGORY_ETCPROUTE ,
" router: peer restart sess_id=%u→%u svc_id=%u from %016llx " ,
rconn - > peer_sess_id , incoming_sess , hdr - > svc_id ,
( unsigned long long ) hdr - > src_node_id ) ;
etcp_router_conn_restart ( inst , hdr - > src_node_id , hdr - > svc_id ) ;
rconn = etcp_router_conn_get ( inst , hdr - > src_node_id , hdr - > svc_id ) ;
if ( ! rconn ) { queue_dgram_free ( entry ) ; queue_entry_free ( entry ) ; return ; }
rconn - > peer_sess_id = incoming_sess ;
}
// RST-флаг — peer сигналит нарушение последовательности
if ( hdr - > flags & ROUTER_FLAG_RST ) {
DEBUG_INFO ( DEBUG_CATEGORY_ETCPROUTE ,
" router: RST from %016llx svc_id=%u " ,
( unsigned long long ) hdr - > src_node_id , hdr - > svc_id ) ;
router_close_and_notify ( rconn ) ;
rconn = NULL ;
}
}
// Seq-состояние есть — reorder
@ -589,6 +612,9 @@ void etcp_router_conn_restart(struct UTUN_INSTANCE* inst, uint64_t remote_node_i
DEBUG_INFO ( DEBUG_CATEGORY_ETCPROUTE , " router_restart: svc_id=%u remote=%016llx — notifying service " ,
svc_id , ( unsigned long long ) remote_node_id ) ;
rconn - > sess_id = ( rconn - > sess_id + 1 ) & 0x3 ;
rconn - > start_sent = 0 ;
etcp_recv_fn cb = inst - > router_bindings . callbacks [ svc_id ] ;
if ( cb ) {
struct ll_entry * e = queue_entry_new ( 0 ) ;
@ -633,6 +659,9 @@ struct ETCP_ROUTER_CONN* etcp_router_conn_get(struct UTUN_INSTANCE* inst,
rconn - > idle_ack_timer = NULL ;
rconn - > send_blocked = 0 ;
rconn - > send_resume_timer = NULL ;
rconn - > sess_id = 0 ;
rconn - > peer_sess_id = 0 ;
rconn - > start_sent = 0 ;
rconn - > recv_q = queue_new ( inst - > ua , ROUTER_RECVQ_HASH_SIZE , 0 , 4 , " router_recv_q " ) ;
if ( ! rconn - > recv_q ) { DEBUG_ERROR ( DEBUG_CATEGORY_ETCPROUTE , " router_conn_get: queue_new(recv_q) failed " ) ; queue_entry_free ( & rconn - > ll ) ; return NULL ; }
rconn - > send_q = queue_new ( inst - > ua , 0 , 0 , 0 , " router_send_q " ) ;