Switch to virtualized use of new zeek::ConnKey class tree

This touches quite a few places, but each just swaps out existing
APIs and/or zeek::detail::ConnKey instances.
This commit is contained in:
Christian Kreibich 2025-06-12 12:59:45 -07:00 committed by Arne Welzel
parent b8f82ff659
commit 52d6228b06
14 changed files with 158 additions and 65 deletions

View file

@ -19,11 +19,15 @@ bool GTPv1_Analyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pack
}
auto conn = static_cast<Connection*>(packet->session);
zeek::detail::ConnKey conn_key = conn->Key();
const auto& key = conn->Key();
auto sk = key.SessionKey();
auto cm_it = conn_map.find(conn_key);
auto cm_it = conn_map.find(sk);
if ( cm_it == conn_map.end() ) {
cm_it = conn_map.insert(cm_it, {conn_key, std::make_unique<binpac::GTPv1::GTPv1_Conn>(this)});
sk.CopyData(); // Copy key data to store in map.
auto [it, inserted] = conn_map.emplace(std::move(sk), std::make_unique<binpac::GTPv1::GTPv1_Conn>(this));
assert(inserted);
cm_it = it;
// Let script land know about the state we created, so it will
// register a conn removal hook for cleanup.

View file

@ -3,6 +3,7 @@
#pragma once
#include "zeek/packet_analysis/Analyzer.h"
#include "zeek/session/Key.h"
#include "packet_analysis/protocol/gtpv1/gtpv1_pac.h"
@ -27,11 +28,10 @@ public:
gtp_hdr_val = std::move(val);
}
void RemoveConnection(const zeek::detail::ConnKey& conn_key) { conn_map.erase(conn_key); }
void RemoveConnection(const zeek::session::detail::Key& conn_key) { conn_map.erase(conn_key); }
protected:
using ConnMap = std::map<zeek::detail::ConnKey, std::unique_ptr<binpac::GTPv1::GTPv1_Conn>>;
ConnMap conn_map;
std::map<zeek::session::detail::Key, std::unique_ptr<binpac::GTPv1::GTPv1_Conn>> conn_map;
int inner_packet_offset = -1;
uint8_t next_header = 0;

View file

@ -2,6 +2,7 @@ module PacketAnalyzer::GTPV1;
%%{
#include "zeek/Conn.h"
#include "zeek/conn_key/Manager.h"
#include "zeek/session/Manager.h"
#include "zeek/packet_analysis/Manager.h"
#include "zeek/packet_analysis/protocol/gtpv1/GTPv1.h"
@ -12,8 +13,12 @@ function remove_gtpv1_connection%(cid: conn_id%) : bool
zeek::packet_analysis::AnalyzerPtr gtpv1 = zeek::packet_mgr->GetAnalyzer("GTPv1");
if ( gtpv1 )
{
zeek::detail::ConnKey conn_key(cid);
static_cast<zeek::packet_analysis::gtpv1::GTPv1_Analyzer*>(gtpv1.get())->RemoveConnection(conn_key);
auto r = zeek::conn_key_mgr->GetFactory().ConnKeyFromVal(*cid);
if ( ! r.has_value() )
return zeek::val_mgr->False();
auto sk = r.value()->SessionKey();
static_cast<zeek::packet_analysis::gtpv1::GTPv1_Analyzer*>(gtpv1.get())->RemoveConnection(sk);
}
return zeek::val_mgr->True();

View file

@ -7,6 +7,8 @@
#include "zeek/Val.h"
#include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/protocol/pia/PIA.h"
#include "zeek/conn_key/Manager.h"
#include "zeek/packet_analysis/protocol/ip/conn_key/IPBasedConnKey.h"
#include "zeek/plugin/Manager.h"
#include "zeek/session/Manager.h"
@ -26,13 +28,30 @@ bool IPBasedAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pkt
if ( ! BuildConnTuple(len, data, pkt, tuple) )
return false;
const std::shared_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
zeek::detail::ConnKey key(tuple);
static IPBasedConnKeyPtr key; // Note, this is static for reuse:
if ( ! key ) {
ConnKeyPtr ck = conn_key_mgr->GetFactory().NewConnKey();
Connection* conn = session_mgr->FindConnection(key);
// The IPBasedAnalyzer requires a factory that produces IPBasedConnKey instances.
// We could check with dynamic_cast, but that's probably slow, so assume plugin
// providers know what they're doing here and anyhow, we don't really have analyzers
// that instantiate non-IP connections today and definitely not here!
key = IPBasedConnKeyPtr(static_cast<IPBasedConnKey*>(ck.release()));
}
// Initialize the key with the IP conn tuple and the packet as additional context.
//
// Custom IPConnKey implementations can fiddle with the Key through
// the DoInit(const Packet& pkt) hook called at this point.
key->InitTuple(tuple);
key->Init(*pkt);
const std::shared_ptr<IP_Hdr>& ip_hdr = pkt->ip_hdr;
Connection* conn = session_mgr->FindConnection(*key);
if ( ! conn ) {
conn = NewConn(&tuple, key, pkt);
conn = NewConn(tuple, std::move(key), pkt);
if ( conn )
session_mgr->Insert(conn, false);
}
@ -41,7 +60,7 @@ bool IPBasedAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pkt
conn->Event(connection_reused, nullptr);
session_mgr->Remove(conn);
conn = NewConn(&tuple, key, pkt);
conn = NewConn(tuple, std::move(key), pkt);
if ( conn )
session_mgr->Insert(conn, false);
}
@ -140,18 +159,19 @@ bool IPBasedAnalyzer::IsLikelyServerPort(uint32_t port) const {
return port_cache.find(port) != port_cache.end();
}
zeek::Connection* IPBasedAnalyzer::NewConn(const ConnTuple* id, const zeek::detail::ConnKey& key, const Packet* pkt) {
int src_h = ntohs(id->src_port);
int dst_h = ntohs(id->dst_port);
zeek::Connection* IPBasedAnalyzer::NewConn(const ConnTuple& id, IPBasedConnKeyPtr key, const Packet* pkt) {
int src_h = ntohs(id.src_port);
int dst_h = ntohs(id.dst_port);
bool flip = false;
if ( ! WantConnection(src_h, dst_h, pkt->ip_hdr->Payload(), flip) )
return nullptr;
Connection* conn = new Connection(key, run_state::processing_start_time, id, pkt->ip_hdr->FlowLabel(), pkt);
Connection* conn =
new Connection(std::move(key), id, run_state::processing_start_time, pkt->ip_hdr->FlowLabel(), pkt);
conn->SetTransport(transport);
if ( flip && ! id->dst_addr.IsBroadcast() )
if ( flip && ! id.dst_addr.IsBroadcast() )
conn->FlipRoles();
BuildSessionAnalyzerTree(conn);

View file

@ -7,6 +7,7 @@
#include "zeek/Tag.h"
#include "zeek/packet_analysis/Analyzer.h"
#include "zeek/packet_analysis/protocol/ip/conn_key/IPBasedConnKey.h"
namespace zeek::analyzer::pia {
class PIA;
@ -184,7 +185,7 @@ private:
* @param key A connection ID key generated from the ID.
* @param pkt The packet associated with the new connection.
*/
zeek::Connection* NewConn(const ConnTuple* id, const zeek::detail::ConnKey& key, const Packet* pkt);
zeek::Connection* NewConn(const ConnTuple& id, IPBasedConnKeyPtr key, const Packet* pkt);
void BuildSessionAnalyzerTree(Connection* conn);

View file

@ -185,15 +185,19 @@ bool TeredoAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* pack
return false;
}
zeek::detail::ConnKey conn_key = conn->Key();
OrigRespMap::iterator or_it = orig_resp_map.find(conn_key);
const auto& k = conn->Key();
auto sk = k.SessionKey();
OrigRespMap::iterator or_it = orig_resp_map.find(sk);
// The first time a teredo packet is parsed successfully, insert
// state into orig_resp_map so we can confirm when both sides
// see valid Teredo packets. Further, raise an event so that script
// layer can install a connection removal hooks to cleanup later.
if ( or_it == orig_resp_map.end() ) {
or_it = orig_resp_map.insert(or_it, {conn_key, {}});
sk.CopyData(); // Copy key data to store in map.
auto [it, inserted] = orig_resp_map.emplace(std::move(sk), OrigResp{});
assert(inserted);
or_it = it;
packet->session->EnqueueEvent(new_teredo_state, nullptr, packet->session->GetVal());
}

View file

@ -8,6 +8,7 @@
#include "zeek/RE.h"
#include "zeek/Reporter.h"
#include "zeek/packet_analysis/Analyzer.h"
#include "zeek/session/Key.h"
namespace zeek::packet_analysis::teredo {
@ -44,7 +45,7 @@ public:
bool DetectProtocol(size_t len, const uint8_t* data, Packet* packet) override;
void RemoveConnection(const zeek::detail::ConnKey& conn_key) { orig_resp_map.erase(conn_key); }
void RemoveConnection(const zeek::session::detail::Key& conn_key) { orig_resp_map.erase(conn_key); }
protected:
struct OrigResp {
@ -52,7 +53,7 @@ protected:
bool valid_resp = false;
bool confirmed = false;
};
using OrigRespMap = std::map<zeek::detail::ConnKey, OrigResp>;
using OrigRespMap = std::map<zeek::session::detail::Key, OrigResp>;
OrigRespMap orig_resp_map;
std::unique_ptr<zeek::detail::Specific_RE_Matcher> pattern_re;

View file

@ -2,6 +2,7 @@ module PacketAnalyzer::TEREDO;
%%{
#include "zeek/Conn.h"
#include "zeek/conn_key/Manager.h"
#include "zeek/session/Manager.h"
#include "zeek/packet_analysis/Manager.h"
#include "zeek/packet_analysis/protocol/teredo/Teredo.h"
@ -12,8 +13,12 @@ function remove_teredo_connection%(cid: conn_id%) : bool
zeek::packet_analysis::AnalyzerPtr teredo = zeek::packet_mgr->GetAnalyzer("Teredo");
if ( teredo )
{
zeek::detail::ConnKey conn_key(cid);
static_cast<zeek::packet_analysis::teredo::TeredoAnalyzer*>(teredo.get())->RemoveConnection(conn_key);
auto r = zeek::conn_key_mgr->GetFactory().ConnKeyFromVal(*cid);
if ( ! r.has_value() )
return zeek::val_mgr->False();
auto sk = r.value()->SessionKey();
static_cast<zeek::packet_analysis::teredo::TeredoAnalyzer*>(teredo.get())->RemoveConnection(sk);
}
return zeek::val_mgr->True();