mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
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.
This commit is contained in:
parent
fddbdf6232
commit
b4e86f28b8
4 changed files with 97 additions and 60 deletions
33
src/Conn.cc
33
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
|
||||
|
|
27
src/Conn.h
27
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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<zeek::Tag, AnalyzerConfirmationState> analyzer_confirmations;
|
||||
|
||||
uint32_t hist_seen;
|
||||
std::string history;
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue