Rework Session/Connection tracking to use a std::map instead of PDict

This commit is contained in:
Tim Wojtulewicz 2019-07-29 11:14:58 -07:00
parent 8ab0650c1e
commit 57f29f3e7c
7 changed files with 183 additions and 147 deletions

View file

@ -54,12 +54,13 @@ uint64_t Connection::total_connections = 0;
uint64_t Connection::current_connections = 0; uint64_t Connection::current_connections = 0;
uint64_t Connection::external_connections = 0; uint64_t Connection::external_connections = 0;
Connection::Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, Connection::Connection(NetSessions* s, const ConnIDKey& k, double t, const ConnID* id,
uint32_t flow, const Packet* pkt, uint32_t flow, const Packet* pkt,
const EncapsulationStack* arg_encap) const EncapsulationStack* arg_encap)
{ {
sessions = s; sessions = s;
key = k; key = k;
key_valid = true;
start_time = last_time = t; start_time = last_time = t;
orig_addr = id->src_addr; orig_addr = id->src_addr;
@ -144,7 +145,6 @@ Connection::~Connection()
Unref(conn_val); Unref(conn_val);
} }
delete key;
delete root_analyzer; delete root_analyzer;
delete conn_timer_mgr; delete conn_timer_mgr;
delete encapsulation; delete encapsulation;
@ -520,7 +520,7 @@ void Connection::AddTimer(timer_func timer, double t, int do_expire,
// If the key is cleared, the connection isn't stored in the connection // If the key is cleared, the connection isn't stored in the connection
// table anymore and will soon be deleted. We're not installing new // table anymore and will soon be deleted. We're not installing new
// timers anymore then. // timers anymore then.
if ( ! key ) if ( ! key_valid )
return; return;
Timer* conn_timer = new ConnectionTimer(this, timer, t, do_expire, type); Timer* conn_timer = new ConnectionTimer(this, timer, t, do_expire, type);
@ -600,7 +600,6 @@ void Connection::FlipRoles()
unsigned int Connection::MemoryAllocation() const unsigned int Connection::MemoryAllocation() const
{ {
return padded_sizeof(*this) return padded_sizeof(*this)
+ (key ? key->MemoryAllocation() : 0)
+ (timers.MemoryAllocation() - padded_sizeof(timers)) + (timers.MemoryAllocation() - padded_sizeof(timers))
+ (conn_val ? conn_val->MemoryAllocation() : 0) + (conn_val ? conn_val->MemoryAllocation() : 0)
+ (root_analyzer ? root_analyzer->MemoryAllocation(): 0) + (root_analyzer ? root_analyzer->MemoryAllocation(): 0)

View file

@ -5,7 +5,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <unordered_map>
#include <string> #include <string>
#include "Dict.h" #include "Dict.h"
@ -57,7 +56,7 @@ namespace analyzer { class Analyzer; }
class Connection : public BroObj { class Connection : public BroObj {
public: public:
Connection(NetSessions* s, HashKey* k, double t, const ConnID* id, Connection(NetSessions* s, const ConnIDKey& k, double t, const ConnID* id,
uint32_t flow, const Packet* pkt, const EncapsulationStack* arg_encap); uint32_t flow, const Packet* pkt, const EncapsulationStack* arg_encap);
~Connection() override; ~Connection() override;
@ -90,11 +89,15 @@ public:
// arguments for reproducing packets // arguments for reproducing packets
const Packet *pkt); const Packet *pkt);
HashKey* Key() const { return key; } // Keys are only considered valid for a connection when a
void ClearKey() { key = 0; } // connection is in the session map. If it is removed, the key
// should be marked invalid.
const ConnIDKey& Key() const { return key; }
void ClearKey() { key_valid = false; }
bool IsKeyValid() const { return key_valid; }
double StartTime() const { return start_time; } double StartTime() const { return start_time; }
void SetStartTime(double t) { start_time = t; } void SetStartTime(double t) { start_time = t; }
double LastTime() const { return last_time; } double LastTime() const { return last_time; }
void SetLastTime(double t) { last_time = t; } void SetLastTime(double t) { last_time = t; }
@ -306,7 +309,8 @@ protected:
void RemoveConnectionTimer(double t); void RemoveConnectionTimer(double t);
NetSessions* sessions; NetSessions* sessions;
HashKey* key; ConnIDKey key;
bool key_valid;
// Timer manager to use for this conn (or nil). // Timer manager to use for this conn (or nil).
TimerMgr::Tag* conn_timer_mgr; TimerMgr::Tag* conn_timer_mgr;

View file

@ -14,14 +14,9 @@ const uint8_t IPAddr::v4_mapped_prefix[12] = { 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0xff, 0xff }; 0, 0, 0xff, 0xff };
HashKey* BuildConnIDHashKey(const ConnID& id) ConnIDKey BuildConnIDKey(const ConnID& id)
{ {
struct { ConnIDKey key;
in6_addr ip1;
in6_addr ip2;
uint16_t port1;
uint16_t port2;
} key;
// Lookup up connection based on canonical ordering, which is // Lookup up connection based on canonical ordering, which is
// the smaller of <src addr, src port> and <dst addr, dst port> // the smaller of <src addr, src port> and <dst addr, dst port>
@ -43,7 +38,7 @@ HashKey* BuildConnIDHashKey(const ConnID& id)
key.port2 = id.src_port; key.port2 = id.src_port;
} }
return new HashKey(&key, sizeof(key)); return key;
} }
static inline uint32_t bit_mask32(int bottom_bits) static inline uint32_t bit_mask32(int bottom_bits)

View file

@ -5,6 +5,7 @@
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <string.h>
#include <string> #include <string>
#include "BroString.h" #include "BroString.h"
@ -18,6 +19,31 @@ namespace analyzer { class ExpectedConn; }
typedef in_addr in4_addr; typedef in_addr in4_addr;
struct ConnIDKey
{
in6_addr ip1;
in6_addr ip2;
uint16_t port1;
uint16_t port2;
ConnIDKey() : port1(0), port2(0)
{
memset(&ip1, 0, sizeof(in6_addr));
memset(&ip2, 0, sizeof(in6_addr));
}
bool operator<(const ConnIDKey& rhs) const { return memcmp(this, &rhs, sizeof(ConnIDKey)) < 0; }
bool operator==(const ConnIDKey& rhs) const { return memcmp(this, &rhs, sizeof(ConnIDKey)) == 0; }
ConnIDKey& operator=(const ConnIDKey& rhs)
{
if ( this != &rhs )
memcpy(this, &rhs, sizeof(ConnIDKey));
return *this;
}
};
/** /**
* Class storing both IPv4 and IPv6 addresses. * Class storing both IPv4 and IPv6 addresses.
*/ */
@ -362,7 +388,7 @@ public:
*/ */
void ConvertToThreadingValue(threading::Value::addr_t* v) const; void ConvertToThreadingValue(threading::Value::addr_t* v) const;
friend HashKey* BuildConnIDHashKey(const ConnID& id); friend ConnIDKey BuildConnIDKey(const ConnID& id);
unsigned int MemoryAllocation() const { return padded_sizeof(*this); } unsigned int MemoryAllocation() const { return padded_sizeof(*this); }
@ -485,9 +511,9 @@ inline void IPAddr::ConvertToThreadingValue(threading::Value::addr_t* v) const
} }
/** /**
* Returns a hash key for a given ConnID. Passes ownership to caller. * Returns a map key for a given ConnID.
*/ */
HashKey* BuildConnIDHashKey(const ConnID& id); ConnIDKey BuildConnIDKey(const ConnID& id);
/** /**
* Class storing both IPv4 and IPv6 prefixes * Class storing both IPv4 and IPv6 prefixes

View file

@ -96,9 +96,6 @@ NetSessions::NetSessions()
Unref(t); Unref(t);
tcp_conns.SetDeleteFunc(bro_obj_delete_func);
udp_conns.SetDeleteFunc(bro_obj_delete_func);
icmp_conns.SetDeleteFunc(bro_obj_delete_func);
fragments.SetDeleteFunc(bro_obj_delete_func); fragments.SetDeleteFunc(bro_obj_delete_func);
if ( stp_correlate_pair ) if ( stp_correlate_pair )
@ -128,6 +125,8 @@ NetSessions::NetSessions()
arp_analyzer = new analyzer::arp::ARP_Analyzer(); arp_analyzer = new analyzer::arp::ARP_Analyzer();
else else
arp_analyzer = 0; arp_analyzer = 0;
memset(&stats, 0, sizeof(SessionStats));
} }
NetSessions::~NetSessions() NetSessions::~NetSessions()
@ -138,6 +137,13 @@ NetSessions::~NetSessions()
Unref(arp_analyzer); Unref(arp_analyzer);
delete discarder; delete discarder;
delete stp_manager; delete stp_manager;
for ( const auto& entry : tcp_conns )
Unref(entry.second);
for ( const auto& entry : udp_conns )
Unref(entry.second);
for ( const auto& entry : icmp_conns )
Unref(entry.second);
} }
void NetSessions::Done() void NetSessions::Done()
@ -427,7 +433,7 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
ConnID id; ConnID id;
id.src_addr = ip_hdr->SrcAddr(); id.src_addr = ip_hdr->SrcAddr();
id.dst_addr = ip_hdr->DstAddr(); id.dst_addr = ip_hdr->DstAddr();
Dictionary* d = 0; ConnectionMap* d = nullptr;
BifEnum::Tunnel::Type tunnel_type = BifEnum::Tunnel::IP; BifEnum::Tunnel::Type tunnel_type = BifEnum::Tunnel::IP;
switch ( proto ) { switch ( proto ) {
@ -715,30 +721,27 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
return; return;
} }
HashKey* h = BuildConnIDHashKey(id); ConnIDKey key = BuildConnIDKey(id);
if ( ! h ) Connection* conn = nullptr;
reporter->InternalError("hash computation failed");
Connection* conn = 0;
// FIXME: The following is getting pretty complex. Need to split up // FIXME: The following is getting pretty complex. Need to split up
// into separate functions. // into separate functions.
conn = (Connection*) d->Lookup(h); auto it = d->find(key);
if ( it != d->end() )
conn = it->second;
if ( ! conn ) if ( ! conn )
{ {
conn = NewConn(h, t, &id, data, proto, ip_hdr->FlowLabel(), pkt, encapsulation); conn = NewConn(key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt, encapsulation);
if ( conn ) if ( conn )
d->Insert(h, conn); InsertConnection(d, key, conn);
} }
else else
{ {
// We already know that connection. // We already know that connection.
int consistent = CheckConnectionTag(conn); int consistent = CheckConnectionTag(conn);
if ( consistent < 0 ) if ( consistent < 0 )
{
delete h;
return; return;
}
if ( ! consistent || conn->IsReuse(t, data) ) if ( ! consistent || conn->IsReuse(t, data) )
{ {
@ -746,22 +749,18 @@ void NetSessions::DoNextPacket(double t, const Packet* pkt, const IP_Hdr* ip_hdr
conn->Event(connection_reused, 0); conn->Event(connection_reused, 0);
Remove(conn); Remove(conn);
conn = NewConn(h, t, &id, data, proto, ip_hdr->FlowLabel(), pkt, encapsulation); conn = NewConn(key, t, &id, data, proto, ip_hdr->FlowLabel(), pkt, encapsulation);
if ( conn ) if ( conn )
d->Insert(h, conn); InsertConnection(d, key, conn);
} }
else else
{ {
delete h;
conn->CheckEncapsulation(encapsulation); conn->CheckEncapsulation(encapsulation);
} }
} }
if ( ! conn ) if ( ! conn )
{
delete h;
return; return;
}
int record_packet = 1; // whether to record the packet at all int record_packet = 1; // whether to record the packet at all
int record_content = 1; // whether to record its data int record_content = 1; // whether to record its data
@ -1016,11 +1015,8 @@ Connection* NetSessions::FindConnection(Val* v)
id.is_one_way = 0; // ### incorrect for ICMP connections id.is_one_way = 0; // ### incorrect for ICMP connections
HashKey* h = BuildConnIDHashKey(id); ConnIDKey key = BuildConnIDKey(id);
if ( ! h ) ConnectionMap* d;
reporter->InternalError("hash computation failed");
Dictionary* d;
if ( orig_portv->IsTCP() ) if ( orig_portv->IsTCP() )
d = &tcp_conns; d = &tcp_conns;
@ -1033,22 +1029,22 @@ Connection* NetSessions::FindConnection(Val* v)
// This can happen due to pseudo-connections we // This can happen due to pseudo-connections we
// construct, for example for packet headers embedded // construct, for example for packet headers embedded
// in ICMPs. // in ICMPs.
delete h;
return 0; return 0;
} }
Connection* conn = (Connection*) d->Lookup(h); Connection* conn = nullptr;
auto it = d->find(key);
delete h; if ( it != d->end() )
conn = it->second;
return conn; return conn;
} }
void NetSessions::Remove(Connection* c) void NetSessions::Remove(Connection* c)
{ {
HashKey* k = c->Key(); if ( c->IsKeyValid() )
if ( k )
{ {
const ConnIDKey& key = c->Key();
c->CancelTimers(); c->CancelTimers();
if ( c->ConnTransport() == TRANSPORT_TCP ) if ( c->ConnTransport() == TRANSPORT_TCP )
@ -1073,17 +1069,17 @@ void NetSessions::Remove(Connection* c)
switch ( c->ConnTransport() ) { switch ( c->ConnTransport() ) {
case TRANSPORT_TCP: case TRANSPORT_TCP:
if ( ! tcp_conns.RemoveEntry(k) ) if ( tcp_conns.erase(key) == 0 )
reporter->InternalWarning("connection missing"); reporter->InternalWarning("connection missing");
break; break;
case TRANSPORT_UDP: case TRANSPORT_UDP:
if ( ! udp_conns.RemoveEntry(k) ) if ( udp_conns.erase(key) == 0 )
reporter->InternalWarning("connection missing"); reporter->InternalWarning("connection missing");
break; break;
case TRANSPORT_ICMP: case TRANSPORT_ICMP:
if ( ! icmp_conns.RemoveEntry(k) ) if ( icmp_conns.erase(key) == 0 )
reporter->InternalWarning("connection missing"); reporter->InternalWarning("connection missing");
break; break;
@ -1093,7 +1089,6 @@ void NetSessions::Remove(Connection* c)
} }
Unref(c); Unref(c);
delete k;
} }
} }
@ -1117,27 +1112,30 @@ void NetSessions::Remove(FragReassembler* f)
void NetSessions::Insert(Connection* c) void NetSessions::Insert(Connection* c)
{ {
assert(c->Key()); assert(c->IsKeyValid());
Connection* old = 0; Connection* old = nullptr;
switch ( c->ConnTransport() ) { switch ( c->ConnTransport() ) {
// Remove first. Otherwise the dictioanry would still // Remove first. Otherwise the map would still reference the old key for
// reference the old key for already existing connections. // already existing connections.
case TRANSPORT_TCP: case TRANSPORT_TCP:
old = (Connection*) tcp_conns.Remove(c->Key()); old = LookupConn(tcp_conns, c->Key());
tcp_conns.Insert(c->Key(), c); tcp_conns.erase(c->Key());
InsertConnection(&tcp_conns, c->Key(), c);
break; break;
case TRANSPORT_UDP: case TRANSPORT_UDP:
old = (Connection*) udp_conns.Remove(c->Key()); old = LookupConn(udp_conns, c->Key());
udp_conns.Insert(c->Key(), c); udp_conns.erase(c->Key());
InsertConnection(&udp_conns, c->Key(), c);
break; break;
case TRANSPORT_ICMP: case TRANSPORT_ICMP:
old = (Connection*) icmp_conns.Remove(c->Key()); old = LookupConn(icmp_conns, c->Key());
icmp_conns.Insert(c->Key(), c); icmp_conns.erase(c->Key());
InsertConnection(&icmp_conns, c->Key(), c);
break; break;
default: default:
@ -1151,7 +1149,6 @@ void NetSessions::Insert(Connection* c)
// Some clean-ups similar to those in Remove() (but invisible // Some clean-ups similar to those in Remove() (but invisible
// to the script layer). // to the script layer).
old->CancelTimers(); old->CancelTimers();
delete old->Key();
old->ClearKey(); old->ClearKey();
Unref(old); Unref(old);
} }
@ -1159,29 +1156,23 @@ void NetSessions::Insert(Connection* c)
void NetSessions::Drain() void NetSessions::Drain()
{ {
IterCookie* cookie = tcp_conns.InitForIteration(); for ( const auto& entry : tcp_conns )
Connection* tc;
while ( (tc = tcp_conns.NextEntry(cookie)) )
{ {
Connection* tc = entry.second;
tc->Done(); tc->Done();
tc->Event(connection_state_remove, 0); tc->Event(connection_state_remove, 0);
} }
cookie = udp_conns.InitForIteration(); for ( const auto& entry : udp_conns )
Connection* uc;
while ( (uc = udp_conns.NextEntry(cookie)) )
{ {
Connection* uc = entry.second;
uc->Done(); uc->Done();
uc->Event(connection_state_remove, 0); uc->Event(connection_state_remove, 0);
} }
cookie = icmp_conns.InitForIteration(); for ( const auto& entry : icmp_conns )
Connection* ic;
while ( (ic = icmp_conns.NextEntry(cookie)) )
{ {
Connection* ic = entry.second;
ic->Done(); ic->Done();
ic->Event(connection_state_remove, 0); ic->Event(connection_state_remove, 0);
} }
@ -1191,22 +1182,22 @@ void NetSessions::Drain()
void NetSessions::GetStats(SessionStats& s) const void NetSessions::GetStats(SessionStats& s) const
{ {
s.num_TCP_conns = tcp_conns.Length(); s.num_TCP_conns = tcp_conns.size();
s.cumulative_TCP_conns = tcp_conns.NumCumulativeInserts(); s.cumulative_TCP_conns = stats.cumulative_TCP_conns;
s.num_UDP_conns = udp_conns.Length(); s.num_UDP_conns = udp_conns.size();
s.cumulative_UDP_conns = udp_conns.NumCumulativeInserts(); s.cumulative_UDP_conns = stats.cumulative_UDP_conns;
s.num_ICMP_conns = icmp_conns.Length(); s.num_ICMP_conns = icmp_conns.size();
s.cumulative_ICMP_conns = icmp_conns.NumCumulativeInserts(); s.cumulative_ICMP_conns = stats.cumulative_ICMP_conns;
s.num_fragments = fragments.Length(); s.num_fragments = fragments.Length();
s.num_packets = num_packets_processed; s.num_packets = num_packets_processed;
s.max_TCP_conns = tcp_conns.MaxLength(); s.max_TCP_conns = stats.max_TCP_conns;
s.max_UDP_conns = udp_conns.MaxLength(); s.max_UDP_conns = stats.max_UDP_conns;
s.max_ICMP_conns = icmp_conns.MaxLength(); s.max_ICMP_conns = stats.max_ICMP_conns;
s.max_fragments = fragments.MaxLength(); s.max_fragments = fragments.MaxLength();
} }
Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id, Connection* NetSessions::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,
const Packet* pkt, const EncapsulationStack* encapsulation) const Packet* pkt, const EncapsulationStack* encapsulation)
{ {
@ -1282,6 +1273,15 @@ Connection* NetSessions::NewConn(HashKey* k, double t, const ConnID* id,
return conn; return conn;
} }
Connection* NetSessions::LookupConn(const ConnectionMap& conns, const ConnIDKey& key)
{
auto it = conns.find(key);
if ( it != conns.end() )
return it->second;
return nullptr;
}
bool NetSessions::IsLikelyServerPort(uint32_t port, TransportProto proto) const bool NetSessions::IsLikelyServerPort(uint32_t port, TransportProto proto) const
{ {
// We keep a cached in-core version of the table to speed up the lookup. // We keep a cached in-core version of the table to speed up the lookup.
@ -1441,23 +1441,14 @@ unsigned int NetSessions::ConnectionMemoryUsage()
// Connections have been flushed already. // Connections have been flushed already.
return 0; return 0;
IterCookie* cookie = tcp_conns.InitForIteration(); for ( const auto& entry : tcp_conns )
Connection* tc; mem += entry.second->MemoryAllocation();
while ( (tc = tcp_conns.NextEntry(cookie)) ) for ( const auto& entry : udp_conns )
mem += tc->MemoryAllocation(); mem += entry.second->MemoryAllocation();
cookie = udp_conns.InitForIteration(); for ( const auto& entry : icmp_conns )
Connection* uc; mem += entry.second->MemoryAllocation();
while ( (uc = udp_conns.NextEntry(cookie)) )
mem += uc->MemoryAllocation();
cookie = icmp_conns.InitForIteration();
Connection* ic;
while ( (ic = icmp_conns.NextEntry(cookie)) )
mem += ic->MemoryAllocation();
return mem; return mem;
} }
@ -1470,23 +1461,14 @@ unsigned int NetSessions::ConnectionMemoryUsageConnVals()
// Connections have been flushed already. // Connections have been flushed already.
return 0; return 0;
IterCookie* cookie = tcp_conns.InitForIteration(); for ( const auto& entry : tcp_conns )
Connection* tc; mem += entry.second->MemoryAllocationConnVal();
while ( (tc = tcp_conns.NextEntry(cookie)) ) for ( const auto& entry : udp_conns )
mem += tc->MemoryAllocationConnVal(); mem += entry.second->MemoryAllocationConnVal();
cookie = udp_conns.InitForIteration(); for ( const auto& entry : icmp_conns )
Connection* uc; mem += entry.second->MemoryAllocationConnVal();
while ( (uc = udp_conns.NextEntry(cookie)) )
mem += uc->MemoryAllocationConnVal();
cookie = icmp_conns.InitForIteration();
Connection* ic;
while ( (ic = icmp_conns.NextEntry(cookie)) )
mem += ic->MemoryAllocationConnVal();
return mem; return mem;
} }
@ -1500,16 +1482,35 @@ unsigned int NetSessions::MemoryAllocation()
return ConnectionMemoryUsage() return ConnectionMemoryUsage()
+ padded_sizeof(*this) + padded_sizeof(*this)
+ ch->MemoryAllocation() + ch->MemoryAllocation()
// must take care we don't count the HaskKeys twice. + padded_sizeof(tcp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type)))
+ tcp_conns.MemoryAllocation() - padded_sizeof(tcp_conns) - + padded_sizeof(udp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type)))
// 12 is sizeof(Key) from ConnID::BuildConnKey(); + padded_sizeof(icmp_conns.size() * (sizeof(ConnectionMap::key_type) + sizeof(ConnectionMap::value_type)))
// it can't be (easily) accessed here. :-(
(tcp_conns.Length() * pad_size(12))
+ udp_conns.MemoryAllocation() - padded_sizeof(udp_conns) -
(udp_conns.Length() * pad_size(12))
+ icmp_conns.MemoryAllocation() - padded_sizeof(icmp_conns) -
(icmp_conns.Length() * pad_size(12))
+ fragments.MemoryAllocation() - padded_sizeof(fragments) + fragments.MemoryAllocation() - padded_sizeof(fragments)
// FIXME: MemoryAllocation() not implemented for rest. // FIXME: MemoryAllocation() not implemented for rest.
; ;
} }
void NetSessions::InsertConnection(ConnectionMap* m, const ConnIDKey& key, Connection* conn)
{
(*m)[key] = conn;
switch ( conn->ConnTransport() )
{
case TRANSPORT_TCP:
stats.cumulative_TCP_conns++;
if ( m->size() > stats.max_TCP_conns )
stats.max_TCP_conns = m->size();
break;
case TRANSPORT_UDP:
stats.cumulative_UDP_conns++;
if ( m->size() > stats.max_UDP_conns )
stats.max_UDP_conns = m->size();
break;
case TRANSPORT_ICMP:
stats.cumulative_ICMP_conns++;
if ( m->size() > stats.max_ICMP_conns )
stats.max_ICMP_conns = m->size();
break;
default: break;
}
}

View file

@ -3,6 +3,9 @@
#ifndef sessions_h #ifndef sessions_h
#define sessions_h #define sessions_h
#include <map>
#include <utility>
#include "Dict.h" #include "Dict.h"
#include "CompHash.h" #include "CompHash.h"
#include "IP.h" #include "IP.h"
@ -13,8 +16,6 @@
#include "TunnelEncapsulation.h" #include "TunnelEncapsulation.h"
#include "analyzer/protocol/tcp/Stats.h" #include "analyzer/protocol/tcp/Stats.h"
#include <utility>
class EncapsulationStack; class EncapsulationStack;
class Connection; class Connection;
class ConnCompressor; class ConnCompressor;
@ -27,20 +28,20 @@ namespace analyzer { namespace stepping_stone { class SteppingStoneManager; } }
namespace analyzer { namespace arp { class ARP_Analyzer; } } namespace analyzer { namespace arp { class ARP_Analyzer; } }
struct SessionStats { struct SessionStats {
int num_TCP_conns; size_t num_TCP_conns;
int max_TCP_conns; size_t max_TCP_conns;
uint64_t cumulative_TCP_conns; uint64_t cumulative_TCP_conns;
int num_UDP_conns; size_t num_UDP_conns;
int max_UDP_conns; size_t max_UDP_conns;
uint64_t cumulative_UDP_conns; uint64_t cumulative_UDP_conns;
int num_ICMP_conns; size_t num_ICMP_conns;
int max_ICMP_conns; size_t max_ICMP_conns;
uint64_t cumulative_ICMP_conns; uint64_t cumulative_ICMP_conns;
int num_fragments; size_t num_fragments;
int max_fragments; size_t max_fragments;
uint64_t num_packets; uint64_t num_packets;
}; };
@ -112,8 +113,7 @@ public:
unsigned int CurrentConnections() unsigned int CurrentConnections()
{ {
return tcp_conns.Length() + udp_conns.Length() + return tcp_conns.size() + udp_conns.size() + icmp_conns.size();
icmp_conns.Length();
} }
void DoNextPacket(double t, const Packet *pkt, const IP_Hdr* ip_hdr, void DoNextPacket(double t, const Packet *pkt, const IP_Hdr* ip_hdr,
@ -172,10 +172,14 @@ protected:
friend class TimerMgrExpireTimer; friend class TimerMgrExpireTimer;
friend class IPTunnelTimer; friend class IPTunnelTimer;
Connection* NewConn(HashKey* k, double t, const ConnID* id, using ConnectionMap = std::map<ConnIDKey, Connection*>;
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,
const Packet* pkt, const EncapsulationStack* encapsulation); const Packet* pkt, const EncapsulationStack* encapsulation);
Connection* LookupConn(const ConnectionMap& conns, const ConnIDKey& key);
// Check whether the tag of the current packet is consistent with // Check whether the tag of the current packet is consistent with
// the given connection. Returns: // the given connection. Returns:
// -1 if current packet is to be completely ignored. // -1 if current packet is to be completely ignored.
@ -212,12 +216,19 @@ protected:
bool CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen, bool CheckHeaderTrunc(int proto, uint32_t len, uint32_t caplen,
const Packet *pkt, const EncapsulationStack* encap); const Packet *pkt, const EncapsulationStack* encap);
// Inserts a new connection into the sessions map. If a connection with
// the same key already exists in the map, it will be overwritten by
// the new one.
void InsertConnection(ConnectionMap* m, const ConnIDKey& key, Connection* conn);
CompositeHash* ch; CompositeHash* ch;
PDict<Connection> tcp_conns; ConnectionMap tcp_conns;
PDict<Connection> udp_conns; ConnectionMap udp_conns;
PDict<Connection> icmp_conns; ConnectionMap icmp_conns;
PDict<FragReassembler> fragments; PDict<FragReassembler> fragments;
SessionStats stats;
typedef pair<IPAddr, IPAddr> IPPair; typedef pair<IPAddr, IPAddr> IPPair;
typedef pair<EncapsulatingConn, double> TunnelActivity; typedef pair<EncapsulatingConn, double> TunnelActivity;
typedef std::map<IPPair, TunnelActivity> IPTunnelMap; typedef std::map<IPPair, TunnelActivity> IPTunnelMap;

View file

@ -132,7 +132,7 @@ void ProfileLogger::Log()
SessionStats s; SessionStats s;
sessions->GetStats(s); sessions->GetStats(s);
file->Write(fmt("%.06f Conns: tcp=%d/%d udp=%d/%d icmp=%d/%d\n", file->Write(fmt("%.06f Conns: tcp=%lu/%lu udp=%lu/%lu icmp=%lu/%lu\n",
network_time, network_time,
s.num_TCP_conns, s.max_TCP_conns, s.num_TCP_conns, s.max_TCP_conns,
s.num_UDP_conns, s.max_UDP_conns, s.num_UDP_conns, s.max_UDP_conns,