session manager support tcp reassembly
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user