Conn: In-place val flip and connection_flipped()

Avoids loosing state on a connection value when a connection is flipped.

Fixes up the NTP baseline as well where this was visible: analyzer_confirmation_info()
was raised for a connection value which was immediately forgotten due to
the subsequent connection flipping.

Closed #3028
This commit is contained in:
Arne Welzel 2023-07-04 19:19:03 +02:00
parent 640bd4e065
commit a2214ad611
6 changed files with 80 additions and 2 deletions

View file

@ -217,6 +217,29 @@ void Connection::HistoryThresholdEvent(EventHandlerPtr e, bool is_orig, uint32_t
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
// with GetVal() and connection's layout in init-bare.
void flip_conn_val(const RecordValPtr& conn_val)
{
// Flip the the conn_id (c$id).
const auto& id_val = conn_val->GetField<zeek::RecordVal>(0);
const auto& tmp_addr = id_val->GetField<zeek::AddrVal>(0);
const auto& tmp_port = id_val->GetField<zeek::PortVal>(1);
id_val->Assign(0, id_val->GetField<zeek::AddrVal>(2));
id_val->Assign(1, id_val->GetField<zeek::PortVal>(3));
id_val->Assign(2, tmp_addr);
id_val->Assign(3, tmp_port);
// Flip the endpoints within connection.
const auto& tmp_endp = conn_val->GetField<zeek::RecordVal>(1);
conn_val->Assign(1, conn_val->GetField(2));
conn_val->Assign(2, tmp_endp);
}
}
const RecordValPtr& Connection::GetVal()
{
if ( ! conn_val )
@ -358,7 +381,8 @@ void Connection::FlipRoles()
resp_flow_label = orig_flow_label;
orig_flow_label = tmp_flow;
conn_val = nullptr;
if ( conn_val )
flip_conn_val(conn_val);
if ( adapter )
adapter->FlipRoles();
@ -366,6 +390,9 @@ void Connection::FlipRoles()
analyzer_mgr->ApplyScheduledAnalyzers(this);
AddHistory('^');
if ( connection_flipped )
EnqueueEvent(connection_flipped, nullptr, GetVal());
}
void Connection::Describe(ODesc* d) const