Switch ConnKey storage in Connecton class to a smart pointer.

The class previously kept a full copy, preventing virtualization.

There are 3 remaining uses of the existing Connection object constructor, all in
C++ unit tests. Since Connection isn't in the detail namespace we can't
immediately change its API, but we could deprecate the existing constructor at
this time.
This commit is contained in:
Christian Kreibich 2025-04-10 15:16:42 -07:00
parent 2c860c6785
commit 2ac9e136ba
3 changed files with 12 additions and 7 deletions

View file

@ -27,7 +27,7 @@ namespace zeek {
uint64_t Connection::total_connections = 0; uint64_t Connection::total_connections = 0;
uint64_t Connection::current_connections = 0; uint64_t Connection::current_connections = 0;
Connection::Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt) Connection::Connection(const detail::ConnKeyPtr k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt)
: Session(t, connection_timeout, connection_status_update, detail::connection_status_update_interval), key(k) { : Session(t, connection_timeout, connection_status_update, detail::connection_status_update_interval), key(k) {
orig_addr = id->src_addr; orig_addr = id->src_addr;
resp_addr = id->dst_addr; resp_addr = id->dst_addr;
@ -75,6 +75,9 @@ Connection::Connection(const detail::ConnKey& k, double t, const ConnTuple* id,
encapsulation = pkt->encap; encapsulation = pkt->encap;
} }
Connection::Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt)
: Connection(std::make_shared<zeek::detail::ConnKey>(k), t, id, flow, pkt) {}
Connection::~Connection() { Connection::~Connection() {
if ( ! finished ) if ( ! finished )
reporter->InternalError("Done() not called before destruction of Connection"); reporter->InternalError("Done() not called before destruction of Connection");
@ -89,6 +92,8 @@ Connection::~Connection() {
--current_connections; --current_connections;
} }
session::detail::Key Connection::SessionKey(bool copy) const { return key->SessionKey(); }
void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& arg_encap) { void Connection::CheckEncapsulation(const std::shared_ptr<EncapsulationStack>& arg_encap) {
if ( encapsulation && arg_encap ) { if ( encapsulation && arg_encap ) {
if ( *encapsulation != *arg_encap ) { if ( *encapsulation != *arg_encap ) {

View file

@ -73,6 +73,7 @@ static inline int addr_port_canon_lt(const IPAddr& addr1, uint32_t p1, const IPA
class Connection final : public session::Session { class Connection final : public session::Session {
public: public:
Connection(const detail::ConnKeyPtr k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt);
Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt); Connection(const detail::ConnKey& k, double t, const ConnTuple* id, uint32_t flow, const Packet* pkt);
~Connection() override; ~Connection() override;
@ -110,10 +111,8 @@ public:
// Keys are only considered valid for a connection when a // Keys are only considered valid for a connection when a
// connection is in the session map. If it is removed, the key // connection is in the session map. If it is removed, the key
// should be marked invalid. // should be marked invalid.
const detail::ConnKey& Key() const { return key; } const detail::ConnKey& Key() const { return *key; }
session::detail::Key SessionKey(bool copy) const override { session::detail::Key SessionKey(bool copy) const override;
return session::detail::Key{&key, sizeof(key), session::detail::Key::CONNECTION_KEY_TYPE, copy};
}
const IPAddr& OrigAddr() const { return orig_addr; } const IPAddr& OrigAddr() const { return orig_addr; }
const IPAddr& RespAddr() const { return resp_addr; } const IPAddr& RespAddr() const { return resp_addr; }
@ -139,7 +138,7 @@ public:
return "unknown"; return "unknown";
} }
uint8_t KeyProto() const { return key.transport; } uint8_t KeyProto() const { return key->transport; }
// Returns true if the packet reflects a reuse of this // Returns true if the packet reflects a reuse of this
// connection (i.e., not a continuation but the beginning of // connection (i.e., not a continuation but the beginning of
@ -220,7 +219,7 @@ private:
std::shared_ptr<EncapsulationStack> encapsulation; // tunnels std::shared_ptr<EncapsulationStack> encapsulation; // tunnels
uint8_t tunnel_changes = 0; uint8_t tunnel_changes = 0;
detail::ConnKey key; detail::ConnKeyPtr key;
unsigned int weird : 1; unsigned int weird : 1;
unsigned int finished : 1; unsigned int finished : 1;

View file

@ -37,6 +37,7 @@ public:
ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, uint16_t dst_port, uint16_t proto, bool one_way); ConnKey(const IPAddr& src, const IPAddr& dst, uint16_t src_port, uint16_t dst_port, uint16_t proto, bool one_way);
ConnKey(const ConnTuple& conn); ConnKey(const ConnTuple& conn);
ConnKey(Val* v); ConnKey(Val* v);
virtual ~ConnKey() {};
session::detail::Key SessionKey() const; session::detail::Key SessionKey() const;
virtual size_t PackedSize() const; virtual size_t PackedSize() const;