From b4e86f28b8adcbd45b9008dfa1818c6eb2fbb4d0 Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Thu, 30 Nov 2023 17:18:53 +0100 Subject: [PATCH] Conn/Session: Lift history logic into Session This should allow to mangle a Session's history also from packet analyzers without necessarily knowing the concrete connection type. Given Connection is a subclass of Session, I don't think this changes much. --- src/Conn.cc | 33 ---------------------- src/Conn.h | 27 ------------------ src/session/Session.cc | 33 ++++++++++++++++++++++ src/session/Session.h | 64 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+), 60 deletions(-) diff --git a/src/Conn.cc b/src/Conn.cc index 1f21df7775..dc46e06f89 100644 --- a/src/Conn.cc +++ b/src/Conn.cc @@ -158,39 +158,6 @@ void Connection::NextPacket(double t, bool is_orig, const IP_Hdr* ip, int len, i bool Connection::IsReuse(double t, const u_char* pkt) { return adapter && adapter->IsReuse(t, pkt); } -bool Connection::ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold, uint32_t scaling_base) { - if ( ++counter == scaling_threshold ) { - AddHistory(code); - - auto new_threshold = scaling_threshold * scaling_base; - - if ( new_threshold <= scaling_threshold ) - // This can happen due to wrap-around. In that - // case, reset the counter but leave the threshold - // unchanged. - counter = 0; - - else - scaling_threshold = new_threshold; - - return true; - } - - return false; -} - -void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold) { - if ( ! e ) - return; - - if ( threshold == 1 ) - // This will be far and away the most common case, - // and at this stage it's not a *multiple* instance. - return; - - EnqueueEvent(e, nullptr, GetVal(), val_mgr->Bool(is_orig), val_mgr->Count(threshold)); -} - namespace { // Flip everything that needs to be flipped in the connection // record that is known on this level. This needs to align diff --git a/src/Conn.h b/src/Conn.h index 6ad9d56a55..9f42341d08 100644 --- a/src/Conn.h +++ b/src/Conn.h @@ -179,30 +179,6 @@ public: static uint64_t TotalConnections() { return total_connections; } static uint64_t CurrentConnections() { return current_connections; } - // Returns true if the history was already seen, false otherwise. - bool CheckHistory(uint32_t mask, char code) { - if ( (hist_seen & mask) == 0 ) { - hist_seen |= mask; - AddHistory(code); - return false; - } - else - return true; - } - - // Increments the passed counter and adds it as a history - // code if it has crossed the next scaling threshold. Scaling - // is done in terms of powers of the third argument. - // Returns true if the threshold was crossed, false otherwise. - bool ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold, uint32_t scaling_base = 10); - - void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold); - - void AddHistory(char code) { history += code; } - - const std::string& GetHistory() const { return history; } - void ReplaceHistory(std::string new_h) { history = std::move(new_h); } - // Sets the root of the analyzer tree as well as the primary PIA. void SetSessionAdapter(packet_analysis::IP::SessionAdapter* aa, analyzer::pia::PIA* pia); packet_analysis::IP::SessionAdapter* GetSessionAdapter() { return adapter; } @@ -246,9 +222,6 @@ private: unsigned int finished : 1; unsigned int saw_first_orig_packet : 1, saw_first_resp_packet : 1; - uint32_t hist_seen; - std::string history; - packet_analysis::IP::SessionAdapter* adapter; analyzer::pia::PIA* primary_PIA; diff --git a/src/session/Session.cc b/src/session/Session.cc index 28f9f85839..3d244e35f6 100644 --- a/src/session/Session.cc +++ b/src/session/Session.cc @@ -186,4 +186,37 @@ void Session::SetAnalyzerState(const zeek::Tag& tag, AnalyzerConfirmationState v analyzer_confirmations.insert_or_assign(tag, value); } +bool Session::ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold, uint32_t scaling_base) { + if ( ++counter == scaling_threshold ) { + AddHistory(code); + + auto new_threshold = scaling_threshold * scaling_base; + + if ( new_threshold <= scaling_threshold ) + // This can happen due to wrap-around. In that + // case, reset the counter but leave the threshold + // unchanged. + counter = 0; + + else + scaling_threshold = new_threshold; + + return true; + } + + return false; +} + +void Session::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold) { + if ( ! e ) + return; + + if ( threshold == 1 ) + // This will be far and away the most common case, + // and at this stage it's not a *multiple* instance. + return; + + EnqueueEvent(e, nullptr, GetVal(), val_mgr->Bool(is_orig), val_mgr->Count(threshold)); +} + } // namespace zeek::session diff --git a/src/session/Session.h b/src/session/Session.h index ea500924fc..589c39af71 100644 --- a/src/session/Session.h +++ b/src/session/Session.h @@ -185,6 +185,67 @@ public: AnalyzerConfirmationState AnalyzerState(const zeek::Tag& tag) const; void SetAnalyzerState(const zeek::Tag& tag, AnalyzerConfirmationState); + /** + * Add \a code to history unless already seen. + * + * @param mask Bitmask used for the given code character. + * @param code The character to add to the history. + * + * @return True if the given \a code was already seen (mask set), + * otherwise false after adding it. + */ + bool CheckHistory(uint32_t mask, char code) { + if ( (hist_seen & mask) == 0 ) { + hist_seen |= mask; + AddHistory(code); + return false; + } + + return true; + } + + /** + * Increments the passed counter and adds it as a history + * code if it has crossed the next scaling threshold. Scaling + * is done in terms of powers of the third argument. + * + * @param code The history code. + * @param counter Reference to counter for this code. + * @param scaling_threshold The next threshold, updated to next threshold if crossed. + * @param scaling_base Base to compute the next scaling_threshold. + * + * @return True if the threshold was crossed, false otherwise. + */ + bool ScaledHistoryEntry(char code, uint32_t& counter, uint32_t& scaling_threshold, uint32_t scaling_base = 10); + + /** + * Helper to enqueue a history threshold event \a e with the Connection object of this session. + * + * @param e The event to enqueue + * @param is_orig True if this is the originator of the session. + * @param threshold Crossed threshold to use as event argument. + */ + void HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t threshold); + + /** + * Add \a code to the history. + * + * @param code Code to add + */ + void AddHistory(char code) { history += code; } + + /** + * @return The current history value. + */ + const std::string& GetHistory() const { return history; } + + /** + * Replace the history of this session with a new one. + * + * @param new_h The new history. + */ + void ReplaceHistory(std::string new_h) { history = std::move(new_h); } + protected: friend class detail::Timer; @@ -234,6 +295,9 @@ protected: bool in_session_table; std::map analyzer_confirmations; + + uint32_t hist_seen; + std::string history; }; namespace detail {