Пример #1
0
bool TCPStream::generic_process(uint32_t& my_seq,
                                uint32_t& /*other_seq*/,
                                payload_type& pload,
                                fragments_type& frags,
                                TCP* tcp) {
    bool added_some(false);
    if (tcp->get_flag(TCP::FIN) || tcp->get_flag(TCP::RST)) {
        fin_sent_ = true;
    }
    RawPDU* raw = static_cast<RawPDU*>(tcp->release_inner_pdu()); 
    if (raw) {
        const uint32_t chunk_end = add_sequence_numbers(tcp->seq(), raw->payload_size());
        // If the end of the chunk ends after our current sequence number, process it.
        if (compare_seq_numbers(chunk_end, my_seq) >= 0) {
            uint32_t seq = tcp->seq();
            // If it starts before our sequence number, slice it
            if (compare_seq_numbers(seq, my_seq) < 0) {
                const uint32_t diff = subtract_sequence_numbers(my_seq, seq);
                raw->payload().erase(
                    raw->payload().begin(),
                    raw->payload().begin() + diff
                );
                seq = my_seq;
            }
            safe_insert(frags, seq, raw);
            fragments_type::iterator it = frags.find(my_seq);
            // Keep looping while the fragments seq is lower or equal to our seq
            while (it != frags.end() && compare_seq_numbers(it->first, my_seq) <= 0) {
                // Does this fragment start before our sequence number?
                if (compare_seq_numbers(it->first, my_seq) < 0) {
                    uint32_t fragment_end = add_sequence_numbers(it->first, it->second->payload_size());
                    int comparison = compare_seq_numbers(fragment_end, my_seq);
                    // Does it end after our sequence number? 
                    if (comparison > 0) {
                        // Then slice it
                        RawPDU::payload_type& payload = it->second->payload();
                        payload.erase(
                            payload.begin(),
                            payload.begin() + subtract_sequence_numbers(my_seq, it->first)
                        );
                        safe_insert(frags, my_seq, it->second);
                        it = erase_iterator(it, frags);
                    }
                    else {
                        // Otherwise, we've seen this part of the payload. Erase it.
                        delete it->second;
                        it = erase_iterator(it, frags);
                    }
                }
                else {
                    // They're equal. Add this payload.
                    pload.insert(
                        pload.end(),
                        it->second->payload().begin(), 
                        it->second->payload().end()
                    );
                    my_seq += it->second->payload_size();
                    delete it->second;
                    it = erase_iterator(it, frags);
                    added_some = true;
                    if (frags.empty()) {
                        break;
                    }
                }
            }
        }
        else {
            delete raw;
        }
    }
    return added_some;
}