in src/filtration/filtration_processor.h [265:356]
bool check_fragments(const uint32_t acknowledged)
{
Packet* current{fragments};
if(current)
{
Packet* prev{nullptr};
uint32_t lowest_seq{current->tcp->seq()};
while(current)
{
const uint32_t current_seq{current->tcp->seq()};
const uint32_t current_len{current->dlen};
if(GT_SEQ(lowest_seq, current_seq)) // lowest_seq > current_seq
{
lowest_seq = current_seq;
}
if(LT_SEQ(current_seq, sequence)) // current_seq < sequence
{
// this sequence number seems dated, but
// check the end to make sure it has no more
// info than we have already seen
uint32_t newseq{current_seq + current_len};
if(GT_SEQ(newseq, sequence))
{
// this one has more than we have seen. let's get the
// payload that we have not seen. This happens when
// part of this frame has been retransmitted
uint32_t new_pos{sequence - current_seq};
sequence += (current_len - new_pos);
if(current->dlen > new_pos)
{
current->data += new_pos;
current->dlen -= new_pos;
reader.push(*current);
}
}
// Remove the fragment from the list as the "new" part of it
// has been processed or its data has been seen already in
// another packet.
if(prev)
{
prev->next = current->next;
}
else
{
fragments = current->next;
}
Packet::destroy(current);
return true;
}
if(EQ_SEQ(current_seq, sequence))
{
// this fragment fits the stream
sequence += current_len;
if(prev)
{
prev->next = current->next;
}
else
{
fragments = current->next;
}
reader.push(*current);
Packet::destroy(current);
return true;
}
prev = current;
current = current->next;
} // end while
if(GT_SEQ(acknowledged, lowest_seq)) // acknowledged > lowest_seq
{
//TRACE("acknowledged(%u) > lowest_seq(%u) seq:%u", acknowledged, lowest_seq, sequence);
// There are frames missing in the capture stream that were seen
// by the receiving host. Inform stream about it.
reader.lost(lowest_seq - sequence);
sequence = lowest_seq;
return true;
}
}
return false;
}