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