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

@@ -90,9 +90,12 @@ void tcp_reassembly_free(struct tcp_reassembly *assembler)
}
}
// return: 1: success (seg overlap)
// return: 0: success
// return: -1: failed (no space)
/*
* return: 1: push tcp segment success (segment overlap)
* return: 0: push tcp segment success
* return: -1: push tcp segment failed (no space)
* return: -2: push tcp segment failed (segment repeat)
*/
int tcp_reassembly_push(struct tcp_reassembly *assembler, struct tcp_segment *seg, uint64_t now)
{
if (assembler == NULL)
@@ -102,17 +105,32 @@ int tcp_reassembly_push(struct tcp_reassembly *assembler, struct tcp_segment *se
if (assembler->cur_seg_num >= assembler->max_seg_num)
{
TCP_REASSEMBLY_LOG_ERROR("assembler is full");
TCP_REASSEMBLY_LOG_ERROR("assembler %p is full", assembler);
return -1;
}
int ret = 0;
struct tcp_segment_private *p = container_of(seg, struct tcp_segment_private, seg);
if (interval_tree_iter_first(&assembler->root, p->node.start, p->node.last))
struct interval_tree_node *node = interval_tree_iter_first(&assembler->root, p->node.start, p->node.last);
if (node)
{
TCP_REASSEMBLY_LOG_DEBUG("seg overlap");
do
{
struct tcp_segment_private *t = container_of(node, struct tcp_segment_private, node);
if (t->node.start == p->node.start && t->node.last == p->node.last)
{
TCP_REASSEMBLY_LOG_DEBUG("assembler %p push segment %p [%lu, %lu] failed, segment repeat", assembler, seg, p->node.start, p->node.last);
return -2;
}
} while ((node = interval_tree_iter_next(node, p->node.start, p->node.last)));
TCP_REASSEMBLY_LOG_DEBUG("assembler %p push segment %p [%lu, %lu], but segment overlap", assembler, seg, p->node.start, p->node.last);
ret = 1;
}
else
{
TCP_REASSEMBLY_LOG_DEBUG("assembler %p push segment %p [%lu, %lu]", assembler, seg, p->node.start, p->node.last);
}
p->ts = now;
p->id = assembler->sum_seg_num++;
@@ -137,6 +155,7 @@ struct tcp_segment *tcp_reassembly_pop(struct tcp_reassembly *assembler)
return NULL;
}
uint64_t overlap = 0;
uint64_t min_id = UINT64_MAX;
struct tcp_segment_private *oldest = NULL;
while (node)
@@ -158,17 +177,15 @@ struct tcp_segment *tcp_reassembly_pop(struct tcp_reassembly *assembler)
if (oldest->node.start < assembler->recv_next)
{
// trim overlap
uint64_t overlap = assembler->recv_next - oldest->node.start;
overlap = assembler->recv_next - oldest->node.start;
oldest->seg.len -= overlap;
oldest->seg.data = (char *)oldest->data + overlap;
}
TCP_REASSEMBLY_LOG_DEBUG("assembler %p pop segment %p [%lu, %lu], trim overlap %lu", assembler, &oldest->seg, oldest->node.start, oldest->node.last, overlap);
// update recv_next
assembler->recv_next = oldest->node.last + 1;
if (assembler->recv_next > UINT32_MAX)
{
assembler->recv_next = assembler->recv_next % 4294967296;
}
assembler->recv_next = uint32_add(assembler->recv_next, oldest->seg.len);
return &oldest->seg;
}
@@ -191,6 +208,7 @@ struct tcp_segment *tcp_reassembly_expire(struct tcp_reassembly *assembler, uint
assembler->cur_seg_num--;
list_del(&p->lru);
interval_tree_remove(&p->node, &assembler->root);
TCP_REASSEMBLY_LOG_DEBUG("assembler %p expire segment %p [%lu, %lu]", assembler, &p->seg, p->node.start, p->node.last);
return &p->seg;
}
else
@@ -206,11 +224,8 @@ void tcp_reassembly_inc_recv_next(struct tcp_reassembly *assembler, uint32_t off
return;
}
assembler->recv_next += offset;
if (assembler->recv_next > UINT32_MAX)
{
assembler->recv_next = assembler->recv_next % 4294967296;
}
assembler->recv_next = uint32_add(assembler->recv_next, offset);
TCP_REASSEMBLY_LOG_DEBUG("assembler %p inc recv_next %u to %lu", assembler, offset, assembler->recv_next);
}
void tcp_reassembly_set_recv_next(struct tcp_reassembly *assembler, uint32_t seq)
@@ -221,6 +236,7 @@ void tcp_reassembly_set_recv_next(struct tcp_reassembly *assembler, uint32_t seq
}
assembler->recv_next = seq;
TCP_REASSEMBLY_LOG_DEBUG("assembler %p set recv_next %u", assembler, seq);
}
uint32_t tcp_reassembly_get_recv_next(struct tcp_reassembly *assembler)