zeek/src/analyzer/protocol/tcp/TCP_Reassembler.h
Max Kellermann 0db61f3094 include cleanup
The Zeek code base has very inconsistent #includes.  Many sources
included a few headers, and those headers included other headers, and
in the end, nearly everything is included everywhere, so missing
#includes were never noticed.  Another side effect was a lot of header
bloat which slows down the build.

First step to fix it: in each source file, its own header should be
included first to verify that each header's includes are correct, and
none is missing.

After adding the missing #includes, I replaced lots of #includes
inside headers with class forward declarations.  In most headers,
object pointers are never referenced, so declaring the function
prototypes with forward-declared classes is just fine.

This patch speeds up the build by 19%, because each compilation unit
gets smaller.  Here are the "time" numbers for a fresh build (with a
warm page cache but without ccache):

Before this patch:

 3144.94user 161.63system 3:02.87elapsed 1808%CPU (0avgtext+0avgdata 2168608maxresident)k
 760inputs+12008400outputs (1511major+57747204minor)pagefaults 0swaps

After this patch:

 2565.17user 141.83system 2:25.46elapsed 1860%CPU (0avgtext+0avgdata 1489076maxresident)k
 72576inputs+9130920outputs (1667major+49400430minor)pagefaults 0swaps
2020-02-04 20:51:02 +01:00

121 lines
3.4 KiB
C++

#pragma once
#include "Reassem.h"
#include "TCP_Endpoint.h"
#include "TCP_Flags.h"
class BroFile;
class Connection;
namespace analyzer {
class Analyzer;
namespace tcp {
class TCP_Analyzer;
class TCP_Reassembler : public Reassembler {
public:
enum Type {
Direct, // deliver to destination analyzer itself
Forward, // forward to destination analyzer's children
};
TCP_Reassembler(Analyzer* arg_dst_analyzer, TCP_Analyzer* arg_tcp_analyzer,
Type arg_type, TCP_Endpoint* arg_endp);
~TCP_Reassembler() override;
void Done();
void SetDstAnalyzer(Analyzer* analyzer) { dst_analyzer = analyzer; }
void SetType(Type arg_type) { type = arg_type; }
TCP_Analyzer* GetTCPAnalyzer() { return tcp_analyzer; }
// Returns the volume of data buffered in the reassembler.
// First parameter returns data that is above a hole, and thus is
// waiting on the hole being filled. Second parameter returns
// data that has been processed but is awaiting an ACK to free
// it up.
//
// If we're not processing contents, then naturally each of
// these is empty.
//
// WARNING: this is an O(n) operation and potentially very slow.
void SizeBufferedData(uint64_t& waiting_on_hole, uint64_t& waiting_on_ack) const;
// How much data is pending delivery since it's not yet reassembled.
// Includes the data due to holes (so this value is a bit different
// from waiting_on_hole above; and is computed in a different fashion).
uint64_t NumUndeliveredBytes() const;
void SetContentsFile(BroFile* f);
BroFile* GetContentsFile() const { return record_contents_file; }
void MatchUndelivered(uint64_t up_to_seq, bool use_last_upper);
// Skip up to seq, as if there's a content gap.
// Can be used to skip HTTP data for performance considerations.
void SkipToSeq(uint64_t seq);
int DataSent(double t, uint64_t seq, int len, const u_char* data,
analyzer::tcp::TCP_Flags flags, bool replaying=true);
void AckReceived(uint64_t seq);
// Checks if we have delivered all contents that we can possibly
// deliver for this endpoint. Calls TCP_Analyzer::EndpointEOF()
// when so.
void CheckEOF();
int HasUndeliveredData() const { return HasBlocks(); }
int HadGap() const { return had_gap; }
int DataPending() const;
uint64_t DataSeq() const { return LastReassemSeq(); }
void DeliverBlock(uint64_t seq, int len, const u_char* data);
virtual void Deliver(uint64_t seq, int len, const u_char* data);
TCP_Endpoint* Endpoint() { return endp; }
const TCP_Endpoint* Endpoint() const { return endp; }
int IsOrig() const { return endp->IsOrig(); }
bool IsSkippedContents(uint64_t seq, int length) const
{ return seq + length <= seq_to_skip; }
private:
TCP_Reassembler() { }
void Undelivered(uint64_t up_to_seq) override;
void Gap(uint64_t seq, uint64_t len);
void RecordToSeq(uint64_t start_seq, uint64_t stop_seq, BroFile* f);
void RecordBlock(const DataBlock& b, BroFile* f);
void RecordGap(uint64_t start_seq, uint64_t upper_seq, BroFile* f);
void BlockInserted(DataBlockMap::const_iterator it) override;
void Overlap(const u_char* b1, const u_char* b2, uint64_t n) override;
TCP_Endpoint* endp;
bool deliver_tcp_contents;
bool had_gap;
bool did_EOF;
bool skip_deliveries;
uint64_t seq_to_skip;
bool in_delivery;
analyzer::tcp::TCP_Flags flags;
BroFile* record_contents_file; // file on which to reassemble contents
Analyzer* dst_analyzer;
TCP_Analyzer* tcp_analyzer;
Type type;
};
} } // namespace analyzer::*