TCP reassembly add stat of TCP retransmit and TCP overlap
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user