Change FragReassembler to use a tuple as a key and use std::map for fragments in Sessions

This commit is contained in:
Tim Wojtulewicz 2019-08-01 14:20:10 -07:00
parent 57f29f3e7c
commit a4b8aa1f30
4 changed files with 26 additions and 46 deletions

View file

@ -27,7 +27,7 @@ void FragTimer::Dispatch(double t, int /* is_expire */)
FragReassembler::FragReassembler(NetSessions* arg_s, FragReassembler::FragReassembler(NetSessions* arg_s,
const IP_Hdr* ip, const u_char* pkt, const IP_Hdr* ip, const u_char* pkt,
HashKey* k, double t) const FragReassemblerKey& k, double t)
: Reassembler(0, REASSEM_FRAG) : Reassembler(0, REASSEM_FRAG)
{ {
s = arg_s; s = arg_s;
@ -68,7 +68,6 @@ FragReassembler::~FragReassembler()
DeleteTimer(); DeleteTimer();
delete [] proto_hdr; delete [] proto_hdr;
delete reassembled_pkt; delete reassembled_pkt;
delete key;
} }
void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt) void FragReassembler::AddFragment(double t, const IP_Hdr* ip, const u_char* pkt)

View file

@ -3,6 +3,8 @@
#ifndef frag_h #ifndef frag_h
#define frag_h #define frag_h
#include <tuple>
#include "util.h" #include "util.h"
#include "IP.h" #include "IP.h"
#include "Net.h" #include "Net.h"
@ -17,10 +19,12 @@ class FragTimer;
typedef void (FragReassembler::*frag_timer_func)(double t); typedef void (FragReassembler::*frag_timer_func)(double t);
using FragReassemblerKey = std::tuple<IPAddr, IPAddr, bro_uint_t>;
class FragReassembler : public Reassembler { class FragReassembler : public Reassembler {
public: public:
FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt, FragReassembler(NetSessions* s, const IP_Hdr* ip, const u_char* pkt,
HashKey* k, double t); const FragReassemblerKey& k, double t);
~FragReassembler() override; ~FragReassembler() override;
void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt); void AddFragment(double t, const IP_Hdr* ip, const u_char* pkt);
@ -30,7 +34,7 @@ public:
void ClearTimer() { expire_timer = 0; } void ClearTimer() { expire_timer = 0; }
const IP_Hdr* ReassembledPkt() { return reassembled_pkt; } const IP_Hdr* ReassembledPkt() { return reassembled_pkt; }
HashKey* Key() const { return key; } const FragReassemblerKey& Key() const { return key; }
protected: protected:
void BlockInserted(DataBlock* start_block) override; void BlockInserted(DataBlock* start_block) override;
@ -43,7 +47,7 @@ protected:
NetSessions* s; NetSessions* s;
uint64_t frag_size; // size of fully reassembled fragment uint64_t frag_size; // size of fully reassembled fragment
uint16_t next_proto; // first IPv6 fragment header's next proto field uint16_t next_proto; // first IPv6 fragment header's next proto field
HashKey* key; FragReassemblerKey key;
FragTimer* expire_timer; FragTimer* expire_timer;
}; };

View file

@ -87,17 +87,6 @@ void IPTunnelTimer::Dispatch(double t, int is_expire)
NetSessions::NetSessions() NetSessions::NetSessions()
{ {
TypeList* t = new TypeList();
t->Append(base_type(TYPE_ADDR)); // source IP address
t->Append(base_type(TYPE_ADDR)); // dest IP address
t->Append(base_type(TYPE_COUNT)); // source and dest ports
ch = new CompositeHash(t);
Unref(t);
fragments.SetDeleteFunc(bro_obj_delete_func);
if ( stp_correlate_pair ) if ( stp_correlate_pair )
stp_manager = new analyzer::stepping_stone::SteppingStoneManager(); stp_manager = new analyzer::stepping_stone::SteppingStoneManager();
else else
@ -131,7 +120,6 @@ NetSessions::NetSessions()
NetSessions::~NetSessions() NetSessions::~NetSessions()
{ {
delete ch;
delete packet_filter; delete packet_filter;
delete pkt_profiler; delete pkt_profiler;
Unref(arp_analyzer); Unref(arp_analyzer);
@ -144,6 +132,8 @@ NetSessions::~NetSessions()
Unref(entry.second); Unref(entry.second);
for ( const auto& entry : icmp_conns ) for ( const auto& entry : icmp_conns )
Unref(entry.second); Unref(entry.second);
for ( const auto& entry : fragments )
Unref(entry.second);
} }
void NetSessions::Done() void NetSessions::Done()
@ -939,27 +929,22 @@ FragReassembler* NetSessions::NextFragment(double t, const IP_Hdr* ip,
{ {
uint32_t frag_id = ip->ID(); uint32_t frag_id = ip->ID();
ListVal* key = new ListVal(TYPE_ANY); FragReassemblerKey key = std::make_tuple(ip->SrcAddr(), ip->DstAddr(), frag_id);
key->Append(new AddrVal(ip->SrcAddr()));
key->Append(new AddrVal(ip->DstAddr()));
key->Append(val_mgr->GetCount(frag_id));
HashKey* h = ch->ComputeHash(key, 1); FragReassembler* f = nullptr;
if ( ! h ) auto it = fragments.find(key);
reporter->InternalError("hash computation failed"); if ( it != fragments.end() )
f = it->second;
FragReassembler* f = fragments.Lookup(h);
if ( ! f ) if ( ! f )
{ {
f = new FragReassembler(this, ip, pkt, h, t); f = new FragReassembler(this, ip, pkt, key, t);
fragments.Insert(h, f); fragments[key] = f;
Unref(key); if ( fragments.size() > stats.max_fragments )
stats.max_fragments = fragments.size();
return f; return f;
} }
delete h;
Unref(key);
f->AddFragment(t, ip, pkt); f->AddFragment(t, ip, pkt);
return f; return f;
} }
@ -1097,15 +1082,8 @@ void NetSessions::Remove(FragReassembler* f)
if ( ! f ) if ( ! f )
return; return;
HashKey* k = f->Key(); if ( fragments.erase(f->Key()) == 0 )
if ( k )
{
if ( ! fragments.RemoveEntry(k) )
reporter->InternalWarning("fragment reassembler not in dict"); reporter->InternalWarning("fragment reassembler not in dict");
}
else
reporter->InternalWarning("missing fragment reassembler hash key");
Unref(f); Unref(f);
} }
@ -1188,13 +1166,13 @@ void NetSessions::GetStats(SessionStats& s) const
s.cumulative_UDP_conns = stats.cumulative_UDP_conns; s.cumulative_UDP_conns = stats.cumulative_UDP_conns;
s.num_ICMP_conns = icmp_conns.size(); s.num_ICMP_conns = icmp_conns.size();
s.cumulative_ICMP_conns = stats.cumulative_ICMP_conns; s.cumulative_ICMP_conns = stats.cumulative_ICMP_conns;
s.num_fragments = fragments.Length(); s.num_fragments = fragments.size();
s.num_packets = num_packets_processed; s.num_packets = num_packets_processed;
s.max_TCP_conns = stats.max_TCP_conns; s.max_TCP_conns = stats.max_TCP_conns;
s.max_UDP_conns = stats.max_UDP_conns; s.max_UDP_conns = stats.max_UDP_conns;
s.max_ICMP_conns = stats.max_ICMP_conns; s.max_ICMP_conns = stats.max_ICMP_conns;
s.max_fragments = fragments.MaxLength(); s.max_fragments = stats.max_fragments;
} }
Connection* NetSessions::NewConn(const ConnIDKey& k, double t, const ConnID* id, Connection* NetSessions::NewConn(const ConnIDKey& k, double t, const ConnID* id,
@ -1481,11 +1459,10 @@ unsigned int NetSessions::MemoryAllocation()
return ConnectionMemoryUsage() return ConnectionMemoryUsage()
+ padded_sizeof(*this) + padded_sizeof(*this)
+ ch->MemoryAllocation()
+ padded_sizeof(tcp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type))) + padded_sizeof(tcp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type)))
+ padded_sizeof(udp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type))) + padded_sizeof(udp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type)))
+ padded_sizeof(icmp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type))) + padded_sizeof(icmp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type)))
+ fragments.MemoryAllocation() - padded_sizeof(fragments) + padded_sizeof(fragments.size() * (sizeof(FragmentMap::key_type) + sizeof(FragmentMap::value_type)))
// FIXME: MemoryAllocation() not implemented for rest. // FIXME: MemoryAllocation() not implemented for rest.
; ;
} }

View file

@ -173,6 +173,7 @@ protected:
friend class IPTunnelTimer; friend class IPTunnelTimer;
using ConnectionMap = std::map<ConnIDKey, Connection*>; using ConnectionMap = std::map<ConnIDKey, Connection*>;
using FragmentMap = std::map<FragReassemblerKey, FragReassembler*>;
Connection* NewConn(const ConnIDKey& k, double t, const ConnID* id, Connection* NewConn(const ConnIDKey& k, double t, const ConnID* id,
const u_char* data, int proto, uint32_t flow_label, const u_char* data, int proto, uint32_t flow_label,
@ -221,11 +222,10 @@ protected:
// the new one. // the new one.
void InsertConnection(ConnectionMap* m, const ConnIDKey& key, Connection* conn); void InsertConnection(ConnectionMap* m, const ConnIDKey& key, Connection* conn);
CompositeHash* ch;
ConnectionMap tcp_conns; ConnectionMap tcp_conns;
ConnectionMap udp_conns; ConnectionMap udp_conns;
ConnectionMap icmp_conns; ConnectionMap icmp_conns;
PDict<FragReassembler> fragments; FragmentMap fragments;
SessionStats stats; SessionStats stats;