bool check_fragments()

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;
        }