Bound ETCP receive window and fix timestamp and allocator UB
This commit is contained in:
1 parent
59f4802904
commit
03f71fd94e
10 files changed
+211
-47
No files matched your search
+22
-12
@@ -927,6 +927,12 @@ void etcp_stats(struct ETCP_CONN* etcp) {
|
||||
static void input_queue_cb(struct ll_queue* q, void* arg) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
|
||||
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);
|
||||
|
||||
if (!in_pkt) {
|
||||
@@ -1595,8 +1601,9 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
|
||||
case ETCP_SECTION_ACK: {
|
||||
if (len < ETCP_ACK_BASE_SIZE) { len = 0; break; }
|
||||
int elm_cnt=data[1];
|
||||
uint32_t till=data[2] | (data[3]<<8) | (data[4]<<16) | (data[5]<<24);
|
||||
if ((int32_t)(till - etcp->next_tx_id) > 0) till = etcp->next_tx_id; // wrap-aware: пир не мог подтвердить больше, чем мы отправили
|
||||
uint32_t till=data[2] | (data[3]<<8) | (data[4]<<16) | ((uint32_t)data[5]<<24);
|
||||
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 old_tx_dup_16 = etcp->tx_dup_count & 0xFFFF;
|
||||
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;
|
||||
len-=ack_section_len;
|
||||
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 dts=data[-ack_section_len+14+i*8] | (data[-ack_section_len+15+i*8]<<8);
|
||||
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) {
|
||||
etcp->rx_ack_till++; etcp_ack_recv(etcp, etcp->rx_ack_till, -1, -1); ack_gap++;
|
||||
}// подтверждаем всё по till
|
||||
/* Все записи могли уже уйти по selective ACK; тогда ack_recv не вызовет resume. */
|
||||
if (ack_gap) input_queue_try_resume(etcp);
|
||||
break;
|
||||
}
|
||||
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 ret_ts=data[1] | (data[2]<<8);// cur_ts=ret_ts = RTT
|
||||
uint16_t new_rtt=cur_ts-ret_ts;
|
||||
int prev_rtt = pkt->link->rtt_last;
|
||||
pkt->link->rtt_last=new_rtt;
|
||||
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);
|
||||
@@ -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_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;
|
||||
if (pkt->link->recv_dt_avg_tx==0) pkt->link->recv_dt_avg_tx=recv_dt_tx*65536;
|
||||
pkt->link->recv_dt_avg_rx +=((int32_t)(recv_dt_rx*65536 - pkt->link->recv_dt_avg_rx))/32;
|
||||
pkt->link->recv_dt_avg_tx +=((int32_t)(recv_dt_tx*65536 - pkt->link->recv_dt_avg_tx))/32;
|
||||
/* Timestamp циклический uint16: Q16 также вычисляем по модулю 2^32, без signed overflow. */
|
||||
uint32_t sample_rx = (uint32_t)recv_dt_rx * 65536u;
|
||||
uint32_t sample_tx = (uint32_t)recv_dt_tx * 65536u;
|
||||
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->tt_last = recv_dt_tx1 - pkt->link->recv_dt_avg_tx/65536;
|
||||
//tts_correction += ((NOW - RTT/2 - TTS) - tts_correction)/16 (инициализируем сразу по 1 пакету)
|
||||
data+=5; len-=5;
|
||||
|
||||
int prev_rtt = pkt->link->rtt_last;
|
||||
int d_rtt = new_rtt - prev_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;
|
||||
int rtt_sum=0;
|
||||
@@ -1679,7 +1691,7 @@ void etcp_conn_input(struct ETCP_DGRAM* pkt) {
|
||||
|
||||
if (len>=5) {
|
||||
// формируем 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 (seq==1) { etcp->got_initial_pkt = 1; DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] Initial packet seq=1 received", etcp->log_name); }
|
||||
else {
|
||||
@@ -1889,5 +1901,3 @@ void etcp_update_mtu(struct ETCP_CONN* etcp) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user