@ -256,6 +256,8 @@ void etcp_conn_reset(struct ETCP_CONN* etcp) {
etcp - > bytes_sent_total = 0 ;
etcp - > retransmissions_count = 0 ;
etcp - > ack_packets_count = 0 ;
etcp - > rx_dup_count = 0 ;
etcp - > tx_dup_count = 0 ;
// Reset RTT history
memset ( etcp - > rtt_history , 0 , sizeof ( etcp - > rtt_history ) ) ;
@ -504,6 +506,8 @@ void etcp_stats(struct ETCP_CONN* etcp) {
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] retransmissions_count: %u " , etcp - > log_name , etcp - > retransmissions_count ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] ack_packets_count: %u " , etcp - > log_name , etcp - > ack_packets_count ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] unacked_bytes: %u " , etcp - > log_name , etcp - > unacked_bytes ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] rx_dup_count: %u " , etcp - > log_name , etcp - > rx_dup_count ) ;
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] tx_dup_count: %u " , etcp - > log_name , etcp - > tx_dup_count ) ;
// IDs
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] IDs: " , etcp - > log_name ) ;
@ -810,7 +814,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
dgram - > noencrypt_len = 0 ;
dgram - > timestamp = get_current_timestamp ( ) ;
// формат ack: [01] [elements count] [4 байта last_delivered_id] и <[4 байта seq][2 байта recv_ts][2 байта txrx delay ts]> x count
// формат ack: [01] [elements count] [4 байта last_delivered_id] [2 байта rx_dup_count] и <[4 байта seq][2 байта recv_ts][2 байта txrx delay ts]> x count
dgram - > data [ 0 ] = 1 ; // ack
int ptr = 2 ;
@ -819,9 +823,12 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
dgram - > data [ ptr + + ] = etcp - > last_delivered_id > > 16 ;
dgram - > data [ ptr + + ] = etcp - > last_delivered_id > > 24 ;
dgram - > data [ ptr + + ] = etcp - > rx_dup_count ;
dgram - > data [ ptr + + ] = etcp - > rx_dup_count > > 8 ;
int data_len = 0 ;
if ( inf_pkt ) data_len = inf_pkt - > ll . len ;
int remain_len = link - > mtu - 28 /*udp headers*/ - 13 - 8 - 4 /*sc_nonce+tag size+crc*/ - 9 /*hdr[3] + min ack[6]*/ - 5 /*payload hdr*/ - data_len ;
int remain_len = link - > mtu - 28 /*udp headers*/ - 13 - 8 - 4 /*sc_nonce+tag size+crc*/ - 11 /*hdr[3] + min ack[8 ]*/ - 5 /*payload hdr*/ - data_len ;
// DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "remain_len= %d pl=%d", remain_len, data_len);
// добавим опциональные заголовки
@ -851,7 +858,7 @@ struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp) {
if ( ptr > 500 ) break ;
}
dgram - > data [ 1 ] = ptr / 8 ;
dgram - > data [ 1 ] = ( ptr - 8 ) / 8 ;
if ( link - > last_recv_updated & & remain_len > = 5 ) { // если есть данные - добавим channel_timestamp
@ -1035,13 +1042,17 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
case ETCP_SECTION_ACK : {
int elm_cnt = data [ 1 ] ;
uint32_t till = data [ 2 ] | ( data [ 3 ] < < 8 ) | ( data [ 4 ] < < 16 ) | ( data [ 5 ] < < 24 ) ;
int ack_section_len = 6 + elm_cnt * 8 ;
uint16_t rx_dup_count_16 = data [ 6 ] | ( data [ 7 ] < < 8 ) ;
uint16_t old_tx_dup_16 = etcp - > tx_dup_count & 0xFFFF ;
int16_t diff = ( int16_t ) ( rx_dup_count_16 - old_tx_dup_16 ) ;
etcp - > tx_dup_count + = diff ;
int ack_section_len = 8 + elm_cnt * 8 ;
data + = ack_section_len ;
len - = ack_section_len ;
for ( int i = 0 ; i < elm_cnt ; i + + ) {
uint32_t seq = data [ - ack_section_len + 6 + i * 8 ] | ( data [ - ack_section_len + 7 + i * 8 ] < < 8 ) | ( data [ - ack_section_len + 8 + i * 8 ] < < 16 ) | ( data [ - ack_section_len + 9 + i * 8 ] < < 24 ) ;
uint16_t ts = data [ - ack_section_len + 10 + i * 8 ] | ( data [ - ack_section_len + 11 + i * 8 ] < < 8 ) ;
uint16_t dts = data [ - ack_section_len + 12 + i * 8 ] | ( data [ - ack_section_len + 13 + i * 8 ] < < 8 ) ;
uint32_t seq = data [ - ack_section_len + 8 + i * 8 ] | ( data [ - ack_section_len + 9 + i * 8 ] < < 8 ) | ( data [ - ack_section_len + 10 + i * 8 ] < < 16 ) | ( data [ - ack_section_len + 11 + i * 8 ] < < 24 ) ;
uint16_t ts = data [ - ack_section_len + 12 + i * 8 ] | ( data [ - ack_section_len + 13 + i * 8 ] < < 8 ) ;
uint16_t dts = data [ - ack_section_len + 14 + i * 8 ] | ( data [ - ack_section_len + 15 + i * 8 ] < < 8 ) ;
etcp_ack_recv ( etcp , seq , ts , dts ) ;
}
while ( ( int32_t ) ( etcp - > rx_ack_till - till ) < 0 ) { etcp - > rx_ack_till + + ; etcp_ack_recv ( etcp , etcp - > rx_ack_till , - 1 , - 1 ) ; } // подтверждаем всё по till
@ -1190,6 +1201,7 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] RX seq=%u need=%u asm_len=%d " , etcp - > log_name , seq , etcp - > last_delivered_id + 1 , etcp - > recv_q - > count ) ;
if ( ( int32_t ) ( seq - etcp - > last_delivered_id ) = = 1 ) etcp_output_try_assembly ( etcp ) ; // пробуем собрать выходную очередь из фрагментов
} else {
etcp - > rx_dup_count + + ;
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] RX dup: seq=%u need=%u asm_len=%d " , etcp - > log_name , seq , etcp - > last_delivered_id + 1 , etcp - > recv_q - > count ) ;
}
} else DEBUG_ERROR ( DEBUG_CATEGORY_ETCP , " payload len %d < 5 " , len ) ;