TCP reassembly add stat of TCP retransmit and TCP overlap

This commit is contained in:
luwenpeng
2024-05-06 15:54:16 +08:00
parent 309736f9f1
commit 61ee619689
8 changed files with 167 additions and 70 deletions

View File

@@ -225,16 +225,6 @@ static int check_options(const struct session_manager_options *opts)
* TCP
******************************************************************************/
/*
* The next routines deal with comparing 32 bit unsigned ints
* and worry about wraparound (automatic with unsigned arithmetic).
*/
static inline bool before(uint32_t seq1, uint32_t seq2)
{
return (int32_t)(seq1 - seq2) < 0;
}
static void tcp_clean(struct session_manager *mgr, struct session *sess)
{
struct tcp_reassembly *c2s_ssembler = sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler;
@@ -279,6 +269,11 @@ static int tcp_init(struct session_manager *mgr, struct session *sess)
return -1;
}
SESSION_LOG_DEBUG("session %lu %s new c2s tcp assembler %p, s2c tcp assembler %p",
session_get_id(sess), session_get_tuple_str(sess),
sess->tcp_halfs[SESSION_DIRECTION_C2S].assembler,
sess->tcp_halfs[SESSION_DIRECTION_S2C].assembler);
return 0;
}
@@ -340,6 +335,7 @@ static void tcp_update(struct session_manager *mgr, struct session *sess, enum s
mgr->stat.nr_tcp_seg_received++;
uint32_t rcv_nxt = tcp_reassembly_get_recv_next(half->assembler);
// in order
if (half->seq == rcv_nxt)
{
session_inc_stat(sess, dir, STAT_TCP_SEGS_INORDER, 1);
@@ -350,16 +346,22 @@ static void tcp_update(struct session_manager *mgr, struct session *sess, enum s
half->in_order.len = len;
tcp_reassembly_inc_recv_next(half->assembler, len);
}
else if (before(half->seq, rcv_nxt))
// retransmission
else if (uint32_before(uint32_add(half->seq, len), rcv_nxt))
{
session_inc_stat(sess, dir, STAT_TCP_SEGS_OVERLAP, 1);
session_inc_stat(sess, dir, STAT_TCP_PLDS_OVERLAP, len);
mgr->stat.nr_tcp_seg_overlap++;
session_inc_stat(sess, dir, STAT_TCP_SEGS_RETRANSMIT, 1);
session_inc_stat(sess, dir, STAT_TCP_PLDS_RETRANSMIT, len);
mgr->stat.nr_tcp_seg_retransmit++;
}
else if ((seg = tcp_segment_new(half->seq, tcp_layer->pld_ptr, len)))
{
switch (tcp_reassembly_push(half->assembler, seg, now))
{
case -2:
session_inc_stat(sess, dir, STAT_TCP_SEGS_RETRANSMIT, 1);
session_inc_stat(sess, dir, STAT_TCP_PLDS_RETRANSMIT, len);
mgr->stat.nr_tcp_seg_retransmit++;
tcp_segment_free(seg);
case -1:
session_inc_stat(sess, dir, STAT_TCP_SEGS_NOSPACE, 1);
session_inc_stat(sess, dir, STAT_TCP_PLDS_NOSPACE, len);

View File

@@ -85,14 +85,15 @@ struct session_manager_stat
uint64_t nr_udp_pkts_evctd_bypass; // sum
// TCP segments
uint64_t nr_tcp_seg_received; // sum
uint64_t nr_tcp_seg_expired; // sum
uint64_t nr_tcp_seg_overlap; // sum
uint64_t nr_tcp_seg_no_space; // sum
uint64_t nr_tcp_seg_inorder; // sum
uint64_t nr_tcp_seg_reorded; // sum
uint64_t nr_tcp_seg_buffered; // sum
uint64_t nr_tcp_seg_released; // sum
uint64_t nr_tcp_seg_received; // sum
uint64_t nr_tcp_seg_expired; // sum
uint64_t nr_tcp_seg_retransmit; // sum
uint64_t nr_tcp_seg_overlap; // sum
uint64_t nr_tcp_seg_no_space; // sum
uint64_t nr_tcp_seg_inorder; // sum
uint64_t nr_tcp_seg_reorded; // sum
uint64_t nr_tcp_seg_buffered; // sum
uint64_t nr_tcp_seg_released; // sum
};
struct session_manager;

View File

@@ -334,6 +334,46 @@ TEST(CASE, TCP_FAST_OPEN)
EXPECT_TRUE(session_get_current_direction(sess) == SESSION_DIRECTION_C2S);
EXPECT_TRUE(session_get_1st_packet(sess, SESSION_DIRECTION_C2S) != NULL);
EXPECT_TRUE(session_get_1st_packet(sess, SESSION_DIRECTION_S2C) == NULL);
// TCP Segment
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_RX) == 1);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_RX) == 166);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_EXPIRED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_EXPIRED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_RETRANSMIT) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_RETRANSMIT) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_OVERLAP) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_OVERLAP) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_NOSPACE) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_NOSPACE) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_INORDER) == 1);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_INORDER) == 166);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_REORDERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_REORDERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_BUFFERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_BUFFERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_SEGS_RELEASED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_C2S, STAT_TCP_PLDS_RELEASED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_RX) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_RX) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_EXPIRED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_EXPIRED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_RETRANSMIT) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_RETRANSMIT) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_OVERLAP) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_OVERLAP) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_NOSPACE) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_NOSPACE) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_INORDER) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_INORDER) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_REORDERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_REORDERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_BUFFERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_BUFFERED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_SEGS_RELEASED) == 0);
EXPECT_TRUE(session_get_stat(sess, SESSION_DIRECTION_S2C, STAT_TCP_PLDS_RELEASED) == 0);
session_print(sess);
struct tcp_segment *seg = session_get_tcp_segment(sess);