@ -927,6 +927,12 @@ void etcp_stats(struct ETCP_CONN* etcp) {
static void input_queue_cb ( struct ll_queue * q , void * arg ) {
static void input_queue_cb ( struct ll_queue * q , void * arg ) {
DEBUG_TRACE ( DEBUG_CATEGORY_ETCP , " " ) ;
DEBUG_TRACE ( DEBUG_CATEGORY_ETCP , " " ) ;
struct ETCP_CONN * etcp = ( struct ETCP_CONN * ) arg ;
struct ETCP_CONN * etcp = ( struct ETCP_CONN * ) arg ;
/* Selective ACK освобождает inflight, но не место за дыркой в приёмном окне пира. */
if ( ( uint32_t ) ( etcp - > next_tx_id - etcp - > rx_ack_till ) > MAX_INFLIGHT_SIZE ) {
DEBUG_DEBUG ( DEBUG_CATEGORY_ETCP , " [%s] peer receive window full: next=%u cumulative_ack=%u queued=%d " ,
etcp - > log_name , etcp - > next_tx_id , etcp - > rx_ack_till , q - > count ) ;
return ;
}
struct ETCP_FRAGMENT * in_pkt = ( struct ETCP_FRAGMENT * ) queue_data_get ( q ) ;
struct ETCP_FRAGMENT * in_pkt = ( struct ETCP_FRAGMENT * ) queue_data_get ( q ) ;
if ( ! in_pkt ) {
if ( ! in_pkt ) {
@ -1595,8 +1601,9 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
case ETCP_SECTION_ACK : {
case ETCP_SECTION_ACK : {
if ( len < ETCP_ACK_BASE_SIZE ) { len = 0 ; break ; }
if ( len < ETCP_ACK_BASE_SIZE ) { len = 0 ; break ; }
int elm_cnt = data [ 1 ] ;
int elm_cnt = data [ 1 ] ;
uint32_t till = data [ 2 ] | ( data [ 3 ] < < 8 ) | ( data [ 4 ] < < 16 ) | ( data [ 5 ] < < 24 ) ;
uint32_t till = data [ 2 ] | ( data [ 3 ] < < 8 ) | ( data [ 4 ] < < 16 ) | ( ( uint32_t ) data [ 5 ] < < 24 ) ;
if ( ( int32_t ) ( till - etcp - > next_tx_id ) > 0 ) till = etcp - > next_tx_id ; // wrap-aware: пир не мог подтвердить больше, чем мы отправили
uint32_t last_tx = etcp - > next_tx_id - 1 ;
if ( ( int32_t ) ( till - last_tx ) > 0 ) till = last_tx ; // нельзя подтвердить ещё не назначенный seq
uint16_t rx_dup_count_16 = data [ 6 ] | ( data [ 7 ] < < 8 ) ;
uint16_t rx_dup_count_16 = data [ 6 ] | ( data [ 7 ] < < 8 ) ;
uint16_t old_tx_dup_16 = etcp - > tx_dup_count & 0xFFFF ;
uint16_t old_tx_dup_16 = etcp - > tx_dup_count & 0xFFFF ;
int16_t diff = ( int16_t ) ( rx_dup_count_16 - old_tx_dup_16 ) ;
int16_t diff = ( int16_t ) ( rx_dup_count_16 - old_tx_dup_16 ) ;
@ -1610,7 +1617,7 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
data + = ack_section_len ;
data + = ack_section_len ;
len - = ack_section_len ;
len - = ack_section_len ;
for ( int i = 0 ; i < elm_cnt ; i + + ) {
for ( int i = 0 ; i < elm_cnt ; i + + ) {
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 ) ;
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 ) | ( ( uint32_t ) 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 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 ) ;
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 ) ;
etcp_ack_recv ( etcp , seq , ts , dts ) ;
@ -1619,6 +1626,8 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
while ( ( int32_t ) ( etcp - > rx_ack_till - till ) < 0 & & ack_gap < ETCP_ACK_GAP_MAX_PACKETS ) {
while ( ( int32_t ) ( etcp - > rx_ack_till - till ) < 0 & & ack_gap < ETCP_ACK_GAP_MAX_PACKETS ) {
etcp - > rx_ack_till + + ; etcp_ack_recv ( etcp , etcp - > rx_ack_till , - 1 , - 1 ) ; ack_gap + + ;
etcp - > rx_ack_till + + ; etcp_ack_recv ( etcp , etcp - > rx_ack_till , - 1 , - 1 ) ; ack_gap + + ;
} // подтверждаем всё по till
} // подтверждаем всё по till
/* Все записи могли уже уйти по selective ACK; тогда ack_recv не вызовет resume. */
if ( ack_gap ) input_queue_try_resume ( etcp ) ;
break ;
break ;
}
}
case ETCP_SECTION_TIMESTAMP : {
case ETCP_SECTION_TIMESTAMP : {
@ -1626,6 +1635,7 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
uint16_t cur_ts = get_current_timestamp ( ) ;
uint16_t cur_ts = get_current_timestamp ( ) ;
uint16_t ret_ts = data [ 1 ] | ( data [ 2 ] < < 8 ) ; // cur_ts=ret_ts = RTT
uint16_t ret_ts = data [ 1 ] | ( data [ 2 ] < < 8 ) ; // cur_ts=ret_ts = RTT
uint16_t new_rtt = cur_ts - ret_ts ;
uint16_t new_rtt = cur_ts - ret_ts ;
int prev_rtt = pkt - > link - > rtt_last ;
pkt - > link - > rtt_last = new_rtt ;
pkt - > link - > rtt_last = new_rtt ;
DEBUG_DEBUG ( DEBUG_CATEGORY_KEEPALIVE , " [%s] KA-RTT: rtt=%u cur=%u ret=%u dlen=%u " ,
DEBUG_DEBUG ( DEBUG_CATEGORY_KEEPALIVE , " [%s] KA-RTT: rtt=%u cur=%u ret=%u dlen=%u " ,
etcp - > log_name , new_rtt , cur_ts , ret_ts , pkt - > data_len ) ;
etcp - > log_name , new_rtt , cur_ts , ret_ts , pkt - > data_len ) ;
@ -1634,19 +1644,21 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
int recv_dt_rx = cur_ts - pkt - > link - > rtt_last / 2 - 1000 - ts ;
int recv_dt_rx = cur_ts - pkt - > link - > rtt_last / 2 - 1000 - ts ;
int recv_dt_tx = recv_dt_tx1 - pkt - > link - > rtt_last / 2 - 1000 ;
int recv_dt_tx = recv_dt_tx1 - pkt - > link - > rtt_last / 2 - 1000 ;
if ( pkt - > link - > recv_dt_avg_rx = = 0 ) pkt - > link - > recv_dt_avg_rx = recv_dt_rx * 65536 ;
/* Timestamp циклический uint16: Q16 также вычисляем по модулю 2^32, без signed overflow. */
if ( pkt - > link - > recv_dt_avg_tx = = 0 ) pkt - > link - > recv_dt_avg_tx = recv_dt_tx * 65536 ;
uint32_t sample_rx = ( uint32_t ) recv_dt_rx * 65536u ;
pkt - > link - > recv_dt_avg_rx + = ( ( int32_t ) ( recv_dt_rx * 65536 - pkt - > link - > recv_dt_avg_rx ) ) / 32 ;
uint32_t sample_tx = ( uint32_t ) recv_dt_tx * 65536u ;
pkt - > link - > recv_dt_avg_tx + = ( ( int32_t ) ( recv_dt_tx * 65536 - pkt - > link - > recv_dt_avg_tx ) ) / 32 ;
if ( pkt - > link - > recv_dt_avg_rx = = 0 ) pkt - > link - > recv_dt_avg_rx = sample_rx ;
if ( pkt - > link - > recv_dt_avg_tx = = 0 ) pkt - > link - > recv_dt_avg_tx = sample_tx ;
pkt - > link - > recv_dt_avg_rx + = ( ( int32_t ) ( sample_rx - pkt - > link - > recv_dt_avg_rx ) ) / 32 ;
pkt - > link - > recv_dt_avg_tx + = ( ( int32_t ) ( sample_tx - pkt - > link - > recv_dt_avg_tx ) ) / 32 ;
pkt - > link - > rt_last = cur_ts - ts - pkt - > link - > recv_dt_avg_rx / 65536 ;
pkt - > link - > rt_last = cur_ts - ts - pkt - > link - > recv_dt_avg_rx / 65536 ;
pkt - > link - > tt_last = recv_dt_tx1 - pkt - > link - > recv_dt_avg_tx / 65536 ;
pkt - > link - > tt_last = recv_dt_tx1 - pkt - > link - > recv_dt_avg_tx / 65536 ;
//tts_correction += ((NOW - RTT/2 - TTS) - tts_correction)/16 (инициализируем сразу по 1 пакету)
//tts_correction += ((NOW - RTT/2 - TTS) - tts_correction)/16 (инициализируем сразу по 1 пакету)
data + = 5 ; len - = 5 ;
data + = 5 ; len - = 5 ;
int prev_rtt = pkt - > link - > rtt_last ;
int d_rtt = new_rtt - prev_rtt ;
int d_rtt = new_rtt - prev_rtt ;
if ( d_rtt < 0 ) d_rtt = - d_rtt ;
if ( d_rtt < 0 ) d_rtt = - d_rtt ;
pkt - > link - > jitter + = ( ( int32_t ) ( d_rtt * 65536 - pkt - > link - > jitter ) ) / 32 ;
pkt - > link - > jitter + = ( ( int64_t ) d_rtt * 65536 - pkt - > link - > jitter ) / 32 ;
struct ETCP_LINK * c = etcp - > links ;
struct ETCP_LINK * c = etcp - > links ;
int rtt_sum = 0 ;
int rtt_sum = 0 ;
@ -1679,7 +1691,7 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
if ( len > = 5 ) {
if ( len > = 5 ) {
// формируем ACK
// формируем ACK
uint32_t seq = data [ 1 ] | ( data [ 2 ] < < 8 ) | ( data [ 3 ] < < 16 ) | ( data [ 4 ] < < 24 ) ;
uint32_t seq = data [ 1 ] | ( data [ 2 ] < < 8 ) | ( data [ 3 ] < < 16 ) | ( ( uint32_t ) data [ 4 ] < < 24 ) ;
if ( etcp - > got_initial_pkt = = 0 ) {
if ( etcp - > got_initial_pkt = = 0 ) {
if ( seq = = 1 ) { etcp - > got_initial_pkt = 1 ; DEBUG_INFO ( DEBUG_CATEGORY_ETCP , " [%s] Initial packet seq=1 received " , etcp - > log_name ) ; }
if ( seq = = 1 ) { etcp - > got_initial_pkt = 1 ; DEBUG_INFO ( DEBUG_CATEGORY_ETCP , " [%s] Initial packet seq=1 received " , etcp - > log_name ) ; }
else {
else {
@ -1889,5 +1901,3 @@ void etcp_update_mtu(struct ETCP_CONN* etcp) {
}
}
}
}
}
}