mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 08:08:19 +00:00
Rework Session/Connection tracking to use a std::map instead of PDict
This commit is contained in:
parent
8ab0650c1e
commit
57f29f3e7c
7 changed files with 183 additions and 147 deletions
|
@ -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)
|
||||||
|
|
16
src/Conn.h
16
src/Conn.h
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
32
src/IPAddr.h
32
src/IPAddr.h
|
@ -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
|
||||||
|
|
217
src/Sessions.cc
217
src/Sessions.cc
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue