From: Ron Dempster (rdempste) Date: Wed, 23 Nov 2022 12:37:35 +0000 (+0000) Subject: Pull request #3661: flow: add an event for retry packets X-Git-Tag: 3.1.48.0~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5f88ddbf080b27a4012cb63b27ba6cebbc56a99;p=thirdparty%2Fsnort3.git Pull request #3661: flow: add an event for retry packets Merge in SNORT/snort3 from ~RDEMPSTE/snort3:retry_event to master Squashed commit of the following: commit db8fdde4cdffb84cae3af426ed19c6b371eff14f Author: Ron Dempster (rdempste) Date: Tue Oct 25 17:09:44 2022 -0400 flow: add an event for retry packets --- diff --git a/src/flow/flow.h b/src/flow/flow.h index 578aead7c..82e4edd35 100644 --- a/src/flow/flow.h +++ b/src/flow/flow.h @@ -494,6 +494,7 @@ public: // FIXIT-M privatize if possible bool snort_proto_id_set_by_ha : 1; bool efd_flow : 1; // Indicate that current flow is an elephant flow bool svc_event_generated : 1; // Set if FLOW_NO_SERVICE_EVENT was generated for this flow + bool retry_queued : 1; // Set if a packet was queued for retry for this flow } flags; FlowState flow_state; diff --git a/src/flow/flow_control.cc b/src/flow/flow_control.cc index 35699d3f2..38bc6c577 100644 --- a/src/flow/flow_control.cc +++ b/src/flow/flow_control.cc @@ -33,6 +33,7 @@ #include "protocols/tcp.h" #include "protocols/udp.h" #include "protocols/vlan.h" +#include "pub_sub/packet_events.h" #include "stream/stream.h" #include "utils/util.h" @@ -453,6 +454,19 @@ unsigned FlowControl::process(Flow* flow, Packet* p) } p->filtering_state = flow->filtering_state; update_stats(flow, p); + if (p->is_retry()) + { + RetryPacketEvent retry_event(p); + DataBus::publish(PKT_RETRY_EVENT, retry_event); + flow->flags.retry_queued = false; + } + else if ( flow->flags.retry_queued and ( !p->is_cooked() or p->is_defrag() ) ) + { + RetryPacketEvent retry_event(p); + DataBus::publish(PKT_RETRY_EVENT, retry_event); + if ( !retry_event.is_still_pending() ) + flow->flags.retry_queued = false; + } } else { diff --git a/src/flow/test/flow_cache_test.cc b/src/flow/test/flow_cache_test.cc index 99db6eacf..27ac992fa 100644 --- a/src/flow/test/flow_cache_test.cc +++ b/src/flow/test/flow_cache_test.cc @@ -83,6 +83,7 @@ void Flow::term() { } void Flow::flush(bool) { } void Flow::reset(bool) { } void Flow::free_flow_data() { } +void DataBus::publish(const char*, DataEvent&, Flow*) { } void DataBus::publish(const char*, const uint8_t*, unsigned, Flow*) { } void DataBus::publish(const char*, Packet*, Flow*) { } const SnortConfig* SnortConfig::get_conf() { return nullptr; } diff --git a/src/flow/test/flow_control_test.cc b/src/flow/test/flow_control_test.cc index c941b78bd..d021bab34 100644 --- a/src/flow/test/flow_control_test.cc +++ b/src/flow/test/flow_control_test.cc @@ -85,6 +85,7 @@ size_t FlowCache::uni_flows_size() const { return 0; } size_t FlowCache::uni_ip_flows_size() const { return 0; } size_t FlowCache::flows_size() const { return 0; } void Flow::init(PktType) { } +void DataBus::publish(const char*, DataEvent&, Flow*) { } void DataBus::publish(const char*, const uint8_t*, unsigned, Flow*) { } void DataBus::publish(const char*, Packet*, Flow*) { } const SnortConfig* SnortConfig::get_conf() { return nullptr; } diff --git a/src/main/analyzer.cc b/src/main/analyzer.cc index ea18f3f4b..639a47cea 100644 --- a/src/main/analyzer.cc +++ b/src/main/analyzer.cc @@ -313,9 +313,11 @@ static void packet_trace_dump(Packet* p, DAQ_Verdict verdict, bool msg_was_held) PacketTracer::dump(p); } -void Analyzer::add_to_retry_queue(DAQ_Msg_h daq_msg) +void Analyzer::add_to_retry_queue(DAQ_Msg_h daq_msg, Flow* flow) { retry_queue->put(daq_msg); + if (flow) + flow->flags.retry_queued = true; } /* @@ -331,7 +333,7 @@ void Analyzer::post_process_daq_pkt_msg(Packet* p) if (p->active->packet_retry_requested()) { - add_to_retry_queue(p->daq_msg); + add_to_retry_queue(p->daq_msg, p->flow); daq_stats.retries_queued++; } else diff --git a/src/main/analyzer.h b/src/main/analyzer.h index 2c2e354da..fda12345a 100644 --- a/src/main/analyzer.h +++ b/src/main/analyzer.h @@ -43,6 +43,7 @@ class Swapper; namespace snort { class AnalyzerCommand; +class Flow; class SFDAQInstance; struct Packet; struct SnortConfig; @@ -96,7 +97,7 @@ public: bool process_rebuilt_packet(snort::Packet*, const DAQ_PktHdr_t*, const uint8_t* pkt, uint32_t pktlen); SO_PUBLIC bool inspect_rebuilt(snort::Packet*); void finalize_daq_message(DAQ_Msg_h, DAQ_Verdict); - void add_to_retry_queue(DAQ_Msg_h); + void add_to_retry_queue(DAQ_Msg_h, snort::Flow*); // Functions called by analyzer commands void start(); diff --git a/src/pub_sub/CMakeLists.txt b/src/pub_sub/CMakeLists.txt index 0d83a7123..351bad756 100644 --- a/src/pub_sub/CMakeLists.txt +++ b/src/pub_sub/CMakeLists.txt @@ -14,6 +14,7 @@ set (PUB_SUB_INCLUDES http_request_body_event.h netflow_event.h opportunistic_tls_event.h + packet_events.h reputation_events.h rna_events.h sip_events.h diff --git a/src/pub_sub/packet_events.h b/src/pub_sub/packet_events.h new file mode 100644 index 000000000..98ffce11f --- /dev/null +++ b/src/pub_sub/packet_events.h @@ -0,0 +1,53 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2022-2022 Cisco and/or its affiliates. All rights reserved. +// +// This program is free software; you can redistribute it and/or modify it +// under the terms of the GNU General Public License Version 2 as published +// by the Free Software Foundation. You may not use, modify or distribute +// this program under any other version of the GNU General Public License. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +//-------------------------------------------------------------------------- +// packet_events.h author Ron Dempster + +#ifndef PACKET_EVENTS_H +#define PACKET_EVENTS_H + +#include "framework/data_bus.h" + +// A retry packet is being processed +#define PKT_RETRY_EVENT "retry_packet" + +namespace snort +{ + +class RetryPacketEvent : public DataEvent +{ +public: + explicit RetryPacketEvent(const Packet* p) : pkt(p) + { } + + const Packet* get_packet() const override + { return pkt; } + + void set_still_pending() + { still_pending = true; } + + bool is_still_pending() const + { return still_pending; } + +private: + const Packet* pkt; + bool still_pending = false; +}; + +} + +#endif diff --git a/src/stream/tcp/tcp_stream_tracker.cc b/src/stream/tcp/tcp_stream_tracker.cc index 152af86ec..cfef5f3e1 100644 --- a/src/stream/tcp/tcp_stream_tracker.cc +++ b/src/stream/tcp/tcp_stream_tracker.cc @@ -729,7 +729,7 @@ void TcpStreamTracker::finalize_held_packet(Packet* cp) if ( cp->active->packet_retry_requested() ) { tcpStats.held_packet_retries++; - Analyzer::get_local_analyzer()->add_to_retry_queue(msg); + Analyzer::get_local_analyzer()->add_to_retry_queue(msg, cp->flow); } else {