session manager support tcp reassembly

This commit is contained in:
luwenpeng
2024-03-26 15:09:03 +08:00
parent 5b92d6d8de
commit eb281ab789
30 changed files with 1917 additions and 88 deletions

View File

@@ -161,6 +161,7 @@ void tcp_reassembly_init(struct tcp_reassembly *assy, uint32_t syn_seq)
}
assy->exp_seq = syn_seq + 1;
TCP_REASSEMBLE_DEBUG("reassembler %p init expect seq %lu", assy, assy->exp_seq);
}
void tcp_reassembly_expire(struct tcp_reassembly *assy, uint64_t now)
@@ -189,7 +190,7 @@ void tcp_reassembly_expire(struct tcp_reassembly *assy, uint64_t now)
};
assy->stat.timeout_discard_segments++;
assy->stat.timeout_discard_bytes += seg->len;
TCP_REASSEMBLE_DEBUG("expire %p [%lu, %lu] (time: %lu, now: %lu)", seg, seg->offset, high, seg->time, now);
TCP_REASSEMBLE_DEBUG("reassembler %p expire segment %p [%lu, %lu] (time: %lu, now: %lu)", assy, seg, seg->offset, high, seg->time, now);
itree_remove(assy->itree, &expire);
}
@@ -214,7 +215,7 @@ void tcp_reassembly_insert(struct tcp_reassembly *assy, uint32_t offset, const c
{
assy->stat.overload_bypass_segments++;
assy->stat.overload_bypass_bytes += len;
TCP_REASSEMBLE_DEBUG("insert [%lu, %lu] failed, reach max packets %u", low, high, assy->opts.max_segments);
TCP_REASSEMBLE_DEBUG("reassembler %p insert [%lu, %lu] failed, reach max packets %u", assy, low, high, assy->opts.max_segments);
return;
}
@@ -222,7 +223,7 @@ void tcp_reassembly_insert(struct tcp_reassembly *assy, uint32_t offset, const c
{
assy->stat.overload_bypass_segments++;
assy->stat.overload_bypass_bytes += len;
TCP_REASSEMBLE_DEBUG("insert [%lu, %lu] failed, reach max bytes %u", low, high, assy->opts.max_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p insert [%lu, %lu] failed, reach max bytes %u", assy, low, high, assy->opts.max_bytes);
return;
}
@@ -230,7 +231,7 @@ void tcp_reassembly_insert(struct tcp_reassembly *assy, uint32_t offset, const c
{
assy->stat.retrans_bypass_segments++;
assy->stat.retrans_bypass_bytes += len;
TCP_REASSEMBLE_DEBUG("insert [%lu, %lu] failed, less the expect seq %lu", low, high, assy->exp_seq);
TCP_REASSEMBLE_DEBUG("reassembler %p insert [%lu, %lu] failed, less the expect seq %lu", assy, low, high, assy->exp_seq);
return;
}
@@ -257,7 +258,7 @@ void tcp_reassembly_insert(struct tcp_reassembly *assy, uint32_t offset, const c
free(seg);
return;
}
TCP_REASSEMBLE_DEBUG("insert %p [%lu, %lu]", seg, insert.low, insert.high);
TCP_REASSEMBLE_DEBUG("reassembler %p insert segment %p [%lu, %lu]", assy, seg, insert.low, insert.high);
segment_list_add(&assy->list, seg);
@@ -327,10 +328,10 @@ const char *tcp_reassembly_peek(struct tcp_reassembly *assy, uint32_t *len)
{
overlap = assy->exp_seq - seg->offset;
*len = seg->len - overlap;
TCP_REASSEMBLE_DEBUG("peek [%lu, +∞], found %p [%lu, %lu] (left overlap: %lu)", assy->exp_seq, seg, oldest->low, oldest->high, overlap);
TCP_REASSEMBLE_DEBUG("reassembler %p peek [%lu, +∞], found segment %p [%lu, %lu] (left overlap: %lu)", assy, assy->exp_seq, seg, oldest->low, oldest->high, overlap);
return seg->payload + overlap;
}
TCP_REASSEMBLE_DEBUG("peek [%lu, +∞], found %p [%lu, %lu]", assy->exp_seq, seg, oldest->low, oldest->high);
TCP_REASSEMBLE_DEBUG("reassembler %p peek [%lu, +∞], found segment %p [%lu, %lu]", assy, assy->exp_seq, seg, oldest->low, oldest->high);
*len = seg->len;
return seg->payload;
@@ -357,15 +358,33 @@ void tcp_reassembly_consume(struct tcp_reassembly *assy, uint32_t len)
ilisttrav_t *trav = NULL;
struct segment *seg = NULL;
/*
* https://www.ietf.org/rfc/rfc0793.txt
*
* This space ranges from 0 to 2**32 - 1.
* Since the space is finite, all arithmetic dealing with sequence
* numbers must be performed modulo 2**32. This unsigned arithmetic
* preserves the relationship of sequence numbers as they cycle from
* 2**32 - 1 to 0 again. There are some subtleties to computer modulo
* arithmetic, so great care should be taken in programming the
* comparison of such values. The symbol "=<" means "less than or equal"
* (modulo 2**32).
*
* UINT32_MAX = 4294967295
* 2^32 = 4294967296
* 2^32 - 1 = 4294967295
* seq range: [0, 4294967295]
* seq range: [0, UINT32_MAX]
*/
old_exp_seq = assy->exp_seq;
assy->exp_seq += len;
if (assy->exp_seq > UINT32_MAX)
{
assy->exp_seq = assy->exp_seq % UINT32_MAX;
assy->exp_seq = assy->exp_seq % 4294967296;
}
new_exp_seq = assy->exp_seq;
TCP_REASSEMBLE_DEBUG("consume [%lu, %lu], update expect seq %lu -> %lu", old_exp_seq, old_exp_seq + len - 1, old_exp_seq, new_exp_seq);
TCP_REASSEMBLE_DEBUG("reassembler %p consume [%lu, %lu], update expect seq %lu -> %lu", assy, old_exp_seq, old_exp_seq + len - 1, old_exp_seq, new_exp_seq);
consume =
{
.low = old_exp_seq,
@@ -397,7 +416,7 @@ void tcp_reassembly_consume(struct tcp_reassembly *assy, uint32_t len)
seg = (struct segment *)del->data;
assy->stat.remove_segments++;
assy->stat.remove_bytes += seg->len;
TCP_REASSEMBLE_DEBUG("consume [%lu, %lu], delete %p [%lu, %lu]", old_exp_seq, old_exp_seq + len - 1, seg, del->low, del->high);
TCP_REASSEMBLE_DEBUG("reassembler %p consume [%lu, %lu], delete segment %p [%lu, %lu]", assy, old_exp_seq, old_exp_seq + len - 1, seg, del->low, del->high);
itree_remove(assy->itree, del);
}
}
@@ -422,11 +441,11 @@ void tcp_reassembly_print_stat(struct tcp_reassembly *assy)
return;
}
TCP_REASSEMBLE_DEBUG("current : segments %lu, bytes %lu", assy->stat.curr_segments, assy->stat.curr_bytes);
TCP_REASSEMBLE_DEBUG("insert : segments %lu, bytes %lu", assy->stat.insert_segments, assy->stat.insert_bytes);
TCP_REASSEMBLE_DEBUG("remove : segments %lu, bytes %lu", assy->stat.remove_segments, assy->stat.remove_bytes);
TCP_REASSEMBLE_DEBUG("consume : segments %lu, bytes %lu", assy->stat.consume_segments, assy->stat.consume_bytes);
TCP_REASSEMBLE_DEBUG("retrans bypass : segments %lu, bytes %lu", assy->stat.retrans_bypass_segments, assy->stat.retrans_bypass_bytes);
TCP_REASSEMBLE_DEBUG("overload bypass : segments %lu, bytes %lu", assy->stat.overload_bypass_segments, assy->stat.overload_bypass_bytes);
TCP_REASSEMBLE_DEBUG("timeout discard : segments %lu, bytes %lu", assy->stat.timeout_discard_segments, assy->stat.timeout_discard_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p current : segments %lu, bytes %lu", assy, assy->stat.curr_segments, assy->stat.curr_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p insert : segments %lu, bytes %lu", assy, assy->stat.insert_segments, assy->stat.insert_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p remove : segments %lu, bytes %lu", assy, assy->stat.remove_segments, assy->stat.remove_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p consume : segments %lu, bytes %lu", assy, assy->stat.consume_segments, assy->stat.consume_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p retrans bypass : segments %lu, bytes %lu", assy, assy->stat.retrans_bypass_segments, assy->stat.retrans_bypass_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p overload bypass : segments %lu, bytes %lu", assy, assy->stat.overload_bypass_segments, assy->stat.overload_bypass_bytes);
TCP_REASSEMBLE_DEBUG("reassembler %p timeout discard : segments %lu, bytes %lu", assy, assy->stat.timeout_discard_segments, assy->stat.timeout_discard_bytes);
}

View File

@@ -20,7 +20,7 @@ extern "C"
struct tcp_reassembly_options
{
bool enable;
uint8_t enable;
uint32_t max_timeout;
uint32_t max_segments;
uint32_t max_bytes;

View File

@@ -29,40 +29,6 @@ static void tcp_reassembly_check_stat(struct tcp_reassembly *assy,
EXPECT_TRUE(stat->timeout_discard_bytes == timeout_discard_bytes);
}
#if 0
const char *session_peek_tcp_payload(struct session *session, uint32_t *len)
{
struct tcp_reassembly *assy;
struct session_dir *dir = session_get_cur_dir(session);
if (dir == SESSION_DIR_C2S)
{
assy = session_get_tcp_c2s_reassembly(session);
}
else
{
assy = session_get_tcp_s2c_reassembly(session);
}
return tcp_reassembly_peek(assy, len);
}
void session_consume_tcp_payload(struct session *session, uint32_t len)
{
struct tcp_reassembly *assy;
struct session_dir *dir = session_get_cur_dir(session);
if (dir == SESSION_DIR_C2S)
{
assy = session_get_tcp_c2s_reassembly(session);
}
else
{
assy = session_get_tcp_s2c_reassembly(session);
}
tcp_reassembly_consume(assy, len);
}
#endif
#if 1
TEST(TCP_REASSEMBLY, TEST)
{
@@ -286,8 +252,6 @@ TEST(TCP_REASSEMBLY, REPEAT2)
* +---> 90 +---> 100 +---> 109
*/
// C2S
tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0);
tcp_reassembly_check_stat(assy,
1, 10, // curr_segments, curr_bytes
@@ -476,6 +440,7 @@ TEST(TCP_REASSEMBLY, SEQ_WRAPAROUND)
.max_segments = 16,
.max_bytes = 1500};
// UINT32_MAX = 4294967295
printf("UINT32_MAX = %u\n", UINT32_MAX);
assy = tcp_reassembly_new(&opts);
@@ -502,9 +467,9 @@ TEST(TCP_REASSEMBLY, SEQ_WRAPAROUND)
* | | | |A|B|C|D|E|F|G|H|I|J|
* | | | +-+-+-+-+-+-+-+-+-+-+
* | | | | | |
* | | | | | +---> UINT32_MAX + 11
* | | | | +---> UINT32_MAX + 5
* | | | +---> UINT32_MAX + 2
* | | | | | +---> 10
* | | | | +---> 4
* | | | +---> 1
* | | +---> UINT32_MAX - 1
* | +---> UINT32_MAX - 4
* +---> UINT32_MAX - 10
@@ -532,7 +497,7 @@ TEST(TCP_REASSEMBLY, SEQ_WRAPAROUND)
0, 0, // retrans_bypass_segments, retrans_bypass_bytes
0, 0, // overload_bypass_segments, overload_bypass_bytes
0, 0); // timeout_discard_segments, timeout_discard_bytes
tcp_reassembly_insert(assy, 2, (const char *)"ABCDEFGHIJ", 10, 0);
tcp_reassembly_insert(assy, 1, (const char *)"ABCDEFGHIJ", 10, 0);
tcp_reassembly_check_stat(assy,
3, 30, // curr_segments, curr_bytes
3, 30, // insert_segments, insert_bytes
@@ -627,7 +592,6 @@ TEST(TCP_REASSEMBLY, MAX_TIMEOUT1)
* +---> 90 +---> 100 +---> 109
*/
// C2S
tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0);
tcp_reassembly_check_stat(assy,
1, 10, // curr_segments, curr_bytes
@@ -828,7 +792,6 @@ TEST(TCP_REASSEMBLY, MAX_PACKETS)
* +---> 90 +---> 100 +---> 110
*/
// C2S
tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0);
tcp_reassembly_check_stat(assy,
1, 10, // curr_segments, curr_bytes
@@ -917,7 +880,6 @@ TEST(TCP_REASSEMBLY, MAX_BYTES)
* +---> 90 +---> 100 +---> 110
*/
// C2S
tcp_reassembly_insert(assy, 90, (const char *)"0123456789", 10, 0);
tcp_reassembly_check_stat(assy,
1, 10, // curr_segments, curr_bytes