Add duplicate packet counter to ACK frames
- Add rx_dup_count (local) and tx_dup_count (remote via ACK) to ETCP_CONN - Extend ACK section format: add 16-bit rx_dup_count after last_delivered_id - Reconstruct 32-bit tx_dup_count from received 16-bit diff - Update etcpmon protocol and control_server to expose counters - Update packet dumper for new ACK format
This commit is contained in:
1 parent
ac56b1da3e
commit
e440e8cde0
5 files changed
+29
-10
No files matched your search
@@ -969,6 +969,8 @@ static void send_metrics(struct control_server* server, struct control_client* c
|
||||
rsp->etcp.cnt_ack_hit_sndq = conn->cnt_ack_hit_sndq;
|
||||
rsp->etcp.cnt_ack_miss = conn->cnt_ack_miss;
|
||||
rsp->etcp.cnt_link_wait = conn->cnt_link_wait;
|
||||
rsp->etcp.rx_dup_count = conn->rx_dup_count;
|
||||
rsp->etcp.tx_dup_count = conn->tx_dup_count;
|
||||
rsp->etcp.tx_state = conn->tx_state;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
rsp->etcp.debug[i] = conn->debug[i];
|
||||
|
||||
+19
-7
@@ -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);
|
||||
|
||||
@@ -165,6 +165,8 @@ struct ETCP_CONN {
|
||||
uint32_t cnt_ack_hit_sndq; // счетчик удалений inflight пакетов из sndq
|
||||
uint32_t cnt_ack_miss; // счетчик не найденных ack
|
||||
uint32_t cnt_link_wait; // счетчик переходов в ожидание когда link busy
|
||||
uint32_t rx_dup_count; // счетчик принятых дубликатов (локальные)
|
||||
uint32_t tx_dup_count; // счетчик дубликатов удаленной стороны (из ACK)
|
||||
uint32_t debug[8]; // 8 значений для дебага (live watch)
|
||||
|
||||
// Logging identifier (format: "XXXX→XXXX [name]" - last 4 digits of local and peer node_id + optional name)
|
||||
|
||||
+4
-3
@@ -42,11 +42,12 @@ void etcp_dump_pkt_sections(struct ETCP_DGRAM* pkt, struct ETCP_LINK* link, int
|
||||
case ETCP_SECTION_ACK: {
|
||||
if (offset + 2 > len) { offset = len; break; }
|
||||
ack_count = data[offset + 1];
|
||||
if (offset + 6 > len) { offset = len; break; }
|
||||
if (offset + 8 > len) { offset = len; break; }
|
||||
ack_last_delivered = data[offset + 2] | (data[offset + 3] << 8) |
|
||||
(data[offset + 4] << 16) | (data[offset + 5] << 24);
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " ack=%u/%d", ack_last_delivered, ack_count);
|
||||
offset += 6 + ack_count * 8;
|
||||
uint16_t ack_rx_dup = data[offset + 6] | (data[offset + 7] << 8);
|
||||
pos += snprintf(buf + pos, sizeof(buf) - pos, " ack=%u/%d dup=%u", ack_last_delivered, ack_count, ack_rx_dup);
|
||||
offset += 8 + ack_count * 8;
|
||||
break;
|
||||
}
|
||||
case ETCP_SECTION_TIMESTAMP: {
|
||||
|
||||
@@ -190,6 +190,8 @@ struct etcpmon_etcp_metrics {
|
||||
uint32_t cnt_ack_hit_sndq;
|
||||
uint32_t cnt_ack_miss;
|
||||
uint32_t cnt_link_wait;
|
||||
uint32_t rx_dup_count;
|
||||
uint32_t tx_dup_count;
|
||||
uint32_t tx_state;
|
||||
uint32_t debug[8];
|
||||
|
||||
|
||||
Reference in new issue
Block a user