From: Mike Stepanek (mstepane) Date: Tue, 18 Jun 2019 19:14:30 +0000 (-0400) Subject: Merge pull request #1646 in SNORT/snort3 from ~MASHASAN/snort3:rna_pub_sub to master X-Git-Tag: 3.0.0-257~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a5a85361854c781afaae16b42b486335d50b5ccc;p=thirdparty%2Fsnort3.git Merge pull request #1646 in SNORT/snort3 from ~MASHASAN/snort3:rna_pub_sub to master Squashed commit of the following: commit 02d777186b7b42185154fa7d5d149ee17a2ce59a Author: Masud Hasan Date: Mon Jun 17 14:41:32 2019 -0400 rna: Renaming peg counts and adding a warning when config changes commit d0a8a2c0fd70edf12a1e59bbd0b39bb71dffb7d3 Author: Masud Hasan Date: Mon Jun 17 04:09:05 2019 -0400 rna: Implementing event-driven RNA inspections --- diff --git a/src/flow/flow_control.cc b/src/flow/flow_control.cc index 42ecce481..29d320985 100644 --- a/src/flow/flow_control.cc +++ b/src/flow/flow_control.cc @@ -353,7 +353,7 @@ static bool want_flow(PktType type, Packet* p) return false; } -bool FlowControl::process(PktType type, Packet* p) +bool FlowControl::process(PktType type, Packet* p, bool* new_flow) { auto& con = proto[to_utype(type)]; @@ -364,18 +364,24 @@ bool FlowControl::process(PktType type, Packet* p) set_key(&key, p); Flow* flow = con.cache->find(&key); if ( !flow ) + { flow = HighAvailabilityManager::import(*p, key); - if ( !flow ) - { - if ( !want_flow(type, p) ) - return true; + if ( !flow ) + { + if ( !want_flow(type, p) ) + return true; - flow = con.cache->get(&key); + flow = con.cache->get(&key); - if ( !flow ) - return true; + if ( !flow ) + return true; + + if ( new_flow ) + *new_flow = true; + } } + if ( !flow->session ) { flow->init(type); diff --git a/src/flow/flow_control.h b/src/flow/flow_control.h index 9c3cddd88..4690d801c 100644 --- a/src/flow/flow_control.h +++ b/src/flow/flow_control.h @@ -52,7 +52,7 @@ public: ~FlowControl(); public: - bool process(PktType, snort::Packet*); + bool process(PktType, snort::Packet*, bool* new_flow = nullptr); snort::Flow* find_flow(const snort::FlowKey*); snort::Flow* new_flow(const snort::FlowKey*); diff --git a/src/framework/data_bus.h b/src/framework/data_bus.h index 44eba7c95..fbd2e768c 100644 --- a/src/framework/data_bus.h +++ b/src/framework/data_bus.h @@ -156,6 +156,16 @@ private: // A flow has entered the setup state #define FLOW_STATE_SETUP_EVENT "flow.state_setup" +// A new flow is created on this packet +#define STREAM_ICMP_NEW_FLOW_EVENT "stream.icmp_new_flow" +#define STREAM_IP_NEW_FLOW_EVENT "stream.ip_new_flow" +#define STREAM_UDP_NEW_FLOW_EVENT "stream.udp_new_flow" + +// A TCP flow has the flag; a midstream flow may not publish other events +#define STREAM_TCP_SYN_EVENT "stream.tcp_syn" +#define STREAM_TCP_SYN_ACK_EVENT "stream.tcp_syn_ack" +#define STREAM_TCP_MIDSTREAM_EVENT "stream.tcp_midstream" + // A new standby flow was generated by stream high availability #define STREAM_HA_NEW_FLOW_EVENT "stream.ha.new_flow" diff --git a/src/main/snort_config.h b/src/main/snort_config.h index 7cc5225f0..f66584968 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -73,6 +73,7 @@ enum RunFlag #endif RUN_FLAG__MEM_CHECK = 0x02000000, RUN_FLAG__TRACK_ON_SYN = 0x04000000, + RUN_FLAG__IP_FRAGS_ONLY = 0x08000000, }; enum OutputFlag @@ -667,6 +668,12 @@ public: bool track_on_syn() const { return (run_flags & RUN_FLAG__TRACK_ON_SYN) != 0; } + bool ip_frags_only() const + { return (run_flags & RUN_FLAG__IP_FRAGS_ONLY) != 0; } + + void clear_run_flags(RunFlag flag) + { run_flags &= ~flag; } + void set_run_flags(RunFlag flag) { run_flags |= flag; } diff --git a/src/network_inspectors/rna/CMakeLists.txt b/src/network_inspectors/rna/CMakeLists.txt index 788592ffb..440a6c8bf 100644 --- a/src/network_inspectors/rna/CMakeLists.txt +++ b/src/network_inspectors/rna/CMakeLists.txt @@ -1,5 +1,7 @@ set ( RNA_SOURCES + rna_event_handler.cc + rna_event_handler.h rna_inspector.cc rna_inspector.h rna_module.cc @@ -14,4 +16,4 @@ add_library( rna OBJECT # add_dynamic_module(rna inspectors # ${RNA_SOURCES} # ) -#endif (STATIC_INSPECTORS) \ No newline at end of file +#endif (STATIC_INSPECTORS) diff --git a/src/network_inspectors/rna/dev_notes.txt b/src/network_inspectors/rna/dev_notes.txt index 6933d9304..bd1896d11 100644 --- a/src/network_inspectors/rna/dev_notes.txt +++ b/src/network_inspectors/rna/dev_notes.txt @@ -15,3 +15,9 @@ as input so that RNA can analyze traffic. RNA discoveries will be stored globally in host_tracker objects and to be shared among multiple threads. RNA memory and discovery are bounded by the memcap in host_tracker. + +Packets from untracked sessions (e.g., non-IP) are processed via the eval method as per +proto-bit registrations. Packets from tracked sessions (e.g., IP, TCP, UDP, and ICMP) +are processed via events as per subscriptions. Since RNA needs to see the first packet +of a session published from stream trackers, these modules (e.g., stream, stream_ip, +stream_tcp, and stream_udp) should be enabled whenever RNA module is enabled. diff --git a/src/network_inspectors/rna/rna_event_handler.cc b/src/network_inspectors/rna/rna_event_handler.cc new file mode 100644 index 000000000..d1c317ab6 --- /dev/null +++ b/src/network_inspectors/rna/rna_event_handler.cc @@ -0,0 +1,69 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2019-2019 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. +//-------------------------------------------------------------------------- + +// rna_event_handler.cc author Masud Hasan + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "rna_event_handler.h" + +using namespace snort; + +void RnaIcmpEventHandler::handle(snort::DataEvent&, snort::Flow*) +{ + Profile profile(rna_perf_stats); + + ++rna_stats.icmp; +} + +void RnaIpEventHandler::handle(snort::DataEvent&, snort::Flow*) +{ + Profile profile(rna_perf_stats); + + ++rna_stats.ip; +} + +void RnaUdpEventHandler::handle(snort::DataEvent&, snort::Flow*) +{ + Profile profile(rna_perf_stats); + + ++rna_stats.udp; +} + +void RnaTcpSynEventHandler::handle(snort::DataEvent&, snort::Flow*) +{ + Profile profile(rna_perf_stats); + + ++rna_stats.tcp_syn; +} + +void RnaTcpSynAckEventHandler::handle(snort::DataEvent&, snort::Flow*) +{ + Profile profile(rna_perf_stats); + + ++rna_stats.tcp_syn_ack; +} + +void RnaTcpMidstreamEventHandler::handle(snort::DataEvent&, snort::Flow*) +{ + Profile profile(rna_perf_stats); + + ++rna_stats.tcp_midstream; +} diff --git a/src/network_inspectors/rna/rna_event_handler.h b/src/network_inspectors/rna/rna_event_handler.h new file mode 100644 index 000000000..8a0f8ef8e --- /dev/null +++ b/src/network_inspectors/rna/rna_event_handler.h @@ -0,0 +1,70 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2019-2019 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. +//-------------------------------------------------------------------------- + +// rna_event_handler.h author Masud Hasan + +#ifndef RNA_EVENT_HANDLER_H +#define RNA_EVENT_HANDLER_H + +#include "framework/data_bus.h" + +#include "rna_module.h" + +class RnaIcmpEventHandler : public snort::DataHandler +{ +public: + RnaIcmpEventHandler() : DataHandler(RNA_NAME) { } + void handle(snort::DataEvent&, snort::Flow*) override; +}; + +class RnaIpEventHandler : public snort::DataHandler +{ +public: + RnaIpEventHandler() : DataHandler(RNA_NAME) { } + void handle(snort::DataEvent&, snort::Flow*) override; +}; + +class RnaUdpEventHandler : public snort::DataHandler +{ +public: + RnaUdpEventHandler() : DataHandler(RNA_NAME) { } + void handle(snort::DataEvent&, snort::Flow*) override; +}; + +class RnaTcpSynEventHandler : public snort::DataHandler +{ +public: + RnaTcpSynEventHandler() : DataHandler(RNA_NAME) { } + void handle(snort::DataEvent&, snort::Flow*) override; +}; + +class RnaTcpSynAckEventHandler : public snort::DataHandler +{ +public: + RnaTcpSynAckEventHandler() : DataHandler(RNA_NAME) { } + void handle(snort::DataEvent&, snort::Flow*) override; +}; + +class RnaTcpMidstreamEventHandler : public snort::DataHandler +{ +public: + RnaTcpMidstreamEventHandler() : DataHandler(RNA_NAME) { } + void handle(snort::DataEvent&, snort::Flow*) override; +}; + +#endif diff --git a/src/network_inspectors/rna/rna_inspector.cc b/src/network_inspectors/rna/rna_inspector.cc index 082bd6ad2..b3e18e23c 100644 --- a/src/network_inspectors/rna/rna_inspector.cc +++ b/src/network_inspectors/rna/rna_inspector.cc @@ -31,9 +31,10 @@ #include "log/messages.h" #include "managers/inspector_manager.h" -#include "profiler/profiler.h" #include "protocols/packet.h" +#include "rna_event_handler.h" + #ifdef UNIT_TEST #include "catch/snort_catch.h" #endif @@ -41,7 +42,7 @@ using namespace snort; using namespace std; -THREAD_LOCAL SimpleStats rna_stats; +THREAD_LOCAL RnaStats rna_stats; THREAD_LOCAL ProfileStats rna_perf_stats; //------------------------------------------------------------------------- @@ -61,14 +62,31 @@ RnaInspector::~RnaInspector() delete rna_conf; } +bool RnaInspector::configure(SnortConfig*) +{ + DataBus::subscribe( STREAM_ICMP_NEW_FLOW_EVENT, new RnaIcmpEventHandler() ); + DataBus::subscribe( STREAM_IP_NEW_FLOW_EVENT, new RnaIpEventHandler() ); + DataBus::subscribe( STREAM_UDP_NEW_FLOW_EVENT, new RnaUdpEventHandler() ); + DataBus::subscribe( STREAM_TCP_SYN_EVENT, new RnaTcpSynEventHandler() ); + DataBus::subscribe( STREAM_TCP_SYN_ACK_EVENT, new RnaTcpSynAckEventHandler() ); + DataBus::subscribe( STREAM_TCP_MIDSTREAM_EVENT, new RnaTcpMidstreamEventHandler() ); + + return true; +} + void RnaInspector::eval(Packet* p) { Profile profile(rna_perf_stats); - if (p->packet_flags & PKT_REBUILT_STREAM) - return; + // Handling untracked sessions, e.g., non-IP packets + assert( !p->flow ); + assert( !(BIT((unsigned)p->type()) & PROTO_BIT__ANY_SSN) ); - ++rna_stats.total_packets; + ++rna_stats.other_packets; + +#ifdef NDEBUG + UNUSED(p); +#endif } void RnaInspector::show(SnortConfig*) @@ -130,7 +148,7 @@ bool RnaInspector::load_rna_conf() { string line; getline(in_stream, line); - line_num++; + ++line_num; if (line.empty() or line.front() == '#') continue; @@ -206,7 +224,7 @@ static const InspectApi rna_inspector_api = rna_mod_dtor }, IT_CONTROL, - PROTO_BIT__ANY_IP, + PROTO_BIT__ALL ^ PROTO_BIT__ANY_SSN, nullptr, // buffers nullptr, // service rna_inspector_pinit, diff --git a/src/network_inspectors/rna/rna_inspector.h b/src/network_inspectors/rna/rna_inspector.h index 88edda724..41b4e9154 100644 --- a/src/network_inspectors/rna/rna_inspector.h +++ b/src/network_inspectors/rna/rna_inspector.h @@ -36,6 +36,7 @@ public: RnaInspector(RnaModule*); ~RnaInspector() override; + bool configure(snort::SnortConfig*) override; void eval(snort::Packet*) override; void show(snort::SnortConfig*) override; void tinit() override; diff --git a/src/network_inspectors/rna/rna_module.cc b/src/network_inspectors/rna/rna_module.cc index 23ee648cf..1bbf064e9 100644 --- a/src/network_inspectors/rna/rna_module.cc +++ b/src/network_inspectors/rna/rna_module.cc @@ -27,6 +27,7 @@ #include #include "log/messages.h" +#include "main/snort_config.h" #ifdef UNIT_TEST #include "catch/snort_catch.h" @@ -35,7 +36,7 @@ using namespace snort; //------------------------------------------------------------------------- -// rna params +// rna params and pegs //------------------------------------------------------------------------- static const Parameter rna_params[] = @@ -55,6 +56,18 @@ static const Parameter rna_params[] = { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } }; +static const PegInfo rna_pegs[] = +{ + { CountType::SUM, "icmp", "count of ICMP packets received" }, + { CountType::SUM, "ip", "count of IP packets received" }, + { CountType::SUM, "udp", "count of UDP packets received" }, + { CountType::SUM, "tcp_syn", "count of TCP SYN packets received" }, + { CountType::SUM, "tcp_syn_ack", "count of TCP SYN-ACK packets received" }, + { CountType::SUM, "tcp_midstream", "count of TCP midstream packets received" }, + { CountType::SUM, "other_packets", "count of packets received without session tracking" }, + { CountType::END, nullptr, nullptr}, +}; + //------------------------------------------------------------------------- // rna module //------------------------------------------------------------------------- @@ -69,7 +82,7 @@ RnaModule::~RnaModule() bool RnaModule::begin(const char* fqn, int, SnortConfig*) { - if (strcmp(fqn, "rna")) + if (strcmp(fqn, RNA_NAME)) return false; else if (!mod_conf) mod_conf = new RnaModuleConfig; @@ -92,11 +105,19 @@ bool RnaModule::set(const char*, Value& v, SnortConfig*) return true; } -bool RnaModule::end(const char* fqn, int, SnortConfig*) +bool RnaModule::end(const char* fqn, int, SnortConfig* sc) { - if (mod_conf == nullptr and strcmp(fqn, "rna") == 0) + if ( mod_conf == nullptr and strcmp(fqn, RNA_NAME) == 0 ) return false; + sc->set_run_flags(RUN_FLAG__TRACK_ON_SYN); // Internal flag to track TCP on SYN + + if ( sc->ip_frags_only() ) + { + WarningMessage("RNA: Disabling stream.ip_frags_only option!\n"); + sc->clear_run_flags(RUN_FLAG__IP_FRAGS_ONLY); + } + return true; } @@ -111,7 +132,7 @@ PegCount* RnaModule::get_counts() const { return (PegCount*)&rna_stats; } const PegInfo* RnaModule::get_pegs() const -{ return snort::simple_pegs; } +{ return rna_pegs; } ProfileStats* RnaModule::get_profile() const { return &rna_perf_stats; } @@ -122,6 +143,7 @@ TEST_CASE("RNA module", "[rna_module]") SECTION("module begin, set, end") { RnaModule mod; + SnortConfig sc; CHECK_FALSE(mod.begin("dummy", 0, nullptr)); CHECK(mod.end("rna", 0, nullptr) == false); @@ -145,7 +167,7 @@ TEST_CASE("RNA module", "[rna_module]") Value v5("dummy"); CHECK(mod.set(nullptr, v5, nullptr) == false); - CHECK(mod.end("rna", 0, nullptr) == true); + CHECK(mod.end("rna", 0, &sc) == true); RnaModuleConfig* rc = mod.get_config(); CHECK(rc != nullptr); @@ -156,5 +178,35 @@ TEST_CASE("RNA module", "[rna_module]") delete rc; } + + SECTION("ip_frags_only is false") + { + RnaModule mod; + SnortConfig sc; + + sc.set_run_flags(RUN_FLAG__IP_FRAGS_ONLY); + CHECK(sc.ip_frags_only() == true); + + CHECK(mod.begin(RNA_NAME, 0, nullptr) == true); + CHECK(mod.end(RNA_NAME, 0, &sc) == true); + CHECK(sc.ip_frags_only() == false); + + delete mod.get_config(); + } + + SECTION("track_on_syn is true") + { + RnaModule mod; + SnortConfig sc; + + sc.clear_run_flags(RUN_FLAG__TRACK_ON_SYN); + CHECK(sc.track_on_syn() == false); + + CHECK(mod.begin(RNA_NAME, 0, nullptr) == true); + CHECK(mod.end(RNA_NAME, 0, &sc) == true); + CHECK(sc.track_on_syn() == true); + + delete mod.get_config(); + } } #endif diff --git a/src/network_inspectors/rna/rna_module.h b/src/network_inspectors/rna/rna_module.h index 479d98b95..f5656380e 100644 --- a/src/network_inspectors/rna/rna_module.h +++ b/src/network_inspectors/rna/rna_module.h @@ -22,13 +22,25 @@ #define RNA_MODULE_H #include "framework/module.h" +#include "profiler/profiler.h" #include "rna_config.h" #define RNA_NAME "rna" #define RNA_HELP "Real-time network awareness and OS fingerprinting (experimental)" -extern THREAD_LOCAL SimpleStats rna_stats; +struct RnaStats +{ + PegCount icmp; + PegCount ip; + PegCount udp; + PegCount tcp_syn; + PegCount tcp_syn_ack; + PegCount tcp_midstream; + PegCount other_packets; +}; + +extern THREAD_LOCAL RnaStats rna_stats; extern THREAD_LOCAL snort::ProfileStats rna_perf_stats; class RnaModule : public snort::Module diff --git a/src/stream/base/stream_base.cc b/src/stream/base/stream_base.cc index f8cfe9646..837cc2c33 100644 --- a/src/stream/base/stream_base.cc +++ b/src/stream/base/stream_base.cc @@ -24,6 +24,7 @@ #include "flow/flow_control.h" #include "flow/prune_stats.h" +#include "framework/data_bus.h" #include "log/messages.h" #include "main/snort_config.h" #include "main/snort_types.h" @@ -142,7 +143,6 @@ class StreamBase : public Inspector public: StreamBase(const StreamModuleConfig*); - bool configure(SnortConfig*) override; void show(SnortConfig*) override; void tinit() override; @@ -210,12 +210,6 @@ void StreamBase::tterm() FlushBucket::clear(); } -bool StreamBase::configure(SnortConfig* sc) -{ - config.track_on_syn = sc->track_on_syn(); - return true; -} - void StreamBase::show(SnortConfig*) { LogMessage("Stream Base config:\n"); @@ -240,8 +234,14 @@ void StreamBase::eval(Packet* p) break; case PktType::IP: - if ( p->has_ip() and ((p->ptrs.decode_flags & DECODE_FRAG) or !config.ip_frags_only) ) - flow_con->process(PktType::IP, p); + if ( p->has_ip() and ((p->ptrs.decode_flags & DECODE_FRAG) or + !SnortConfig::get_conf()->ip_frags_only()) ) + { + bool new_flow = false; + flow_con->process(PktType::IP, p, &new_flow); + if ( new_flow ) + DataBus::publish(STREAM_IP_NEW_FLOW_EVENT, p); + } break; case PktType::TCP: @@ -254,14 +254,22 @@ void StreamBase::eval(Packet* p) flow_con->process(PktType::IP, p); if ( p->ptrs.udph ) - flow_con->process(PktType::UDP, p); + { + bool new_flow = false; + flow_con->process(PktType::UDP, p, &new_flow); + if ( new_flow ) + DataBus::publish(STREAM_UDP_NEW_FLOW_EVENT, p); + } break; case PktType::ICMP: if ( p->ptrs.icmph ) { - if ( !flow_con->process(PktType::ICMP, p) ) - flow_con->process(PktType::IP, p); + bool new_flow = false; + if ( !flow_con->process(PktType::ICMP, p, &new_flow) ) + flow_con->process(PktType::IP, p, &new_flow); + if ( new_flow ) + DataBus::publish(STREAM_ICMP_NEW_FLOW_EVENT, p); } break; diff --git a/src/stream/base/stream_module.cc b/src/stream/base/stream_module.cc index e3f3a2fde..afdcd6d65 100644 --- a/src/stream/base/stream_module.cc +++ b/src/stream/base/stream_module.cc @@ -27,6 +27,7 @@ #include "detection/rules.h" #include "log/messages.h" #include "main/snort.h" +#include "main/snort_config.h" #include "main/snort_debug.h" using namespace snort; @@ -137,7 +138,8 @@ bool StreamModule::set(const char* fqn, Value& v, SnortConfig* c) } else if ( v.is("ip_frags_only") ) { - config.ip_frags_only = v.get_bool(); + if ( v.get_bool() ) + c->set_run_flags(RUN_FLAG__IP_FRAGS_ONLY); return true; } else if ( strstr(fqn, "ip_cache") ) diff --git a/src/stream/base/stream_module.h b/src/stream/base/stream_module.h index bbff1a671..1710fe477 100644 --- a/src/stream/base/stream_module.h +++ b/src/stream/base/stream_module.h @@ -73,8 +73,6 @@ struct StreamModuleConfig FlowConfig file_cfg; unsigned footprint; - bool ip_frags_only; - bool track_on_syn; }; class StreamModule : public snort::Module diff --git a/src/stream/libtcp/tcp_stream_tracker.cc b/src/stream/libtcp/tcp_stream_tracker.cc index b58cf98e2..e784b9776 100644 --- a/src/stream/libtcp/tcp_stream_tracker.cc +++ b/src/stream/libtcp/tcp_stream_tracker.cc @@ -105,11 +105,18 @@ TcpStreamTracker::TcpEvent TcpStreamTracker::set_tcp_event(TcpSegmentDescriptor& { tcp_event = TCP_SYN_RECV_EVENT; tcpStats.syns++; + if ( tcp_state == TcpStreamTracker::TCP_LISTEN ) + DataBus::publish(STREAM_TCP_SYN_EVENT, tsd.get_pkt()); } else if ( tcph->is_syn_ack() ) { tcp_event = TCP_SYN_ACK_RECV_EVENT; tcpStats.syn_acks++; + if ( tcp_state == TcpStreamTracker::TCP_SYN_SENT or + (!Stream::is_midstream(tsd.get_flow()) and + (tcp_state == TcpStreamTracker::TCP_LISTEN or + tcp_state == TcpStreamTracker::TCP_STATE_NONE)) ) + DataBus::publish(STREAM_TCP_SYN_ACK_EVENT, tsd.get_pkt()); } else if ( tcph->is_rst() ) { diff --git a/src/stream/tcp/tcp_state_listen.cc b/src/stream/tcp/tcp_state_listen.cc index c2a4d9d64..8ffc88947 100644 --- a/src/stream/tcp/tcp_state_listen.cc +++ b/src/stream/tcp/tcp_state_listen.cc @@ -144,7 +144,11 @@ bool TcpStateListen::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& Flow* flow = tsd.get_flow(); flow->session_state |= STREAM_STATE_MIDSTREAM; - flow->set_session_flags(SSNFLAG_MIDSTREAM); + if ( !Stream::is_midstream(flow) ) + { + flow->set_session_flags(SSNFLAG_MIDSTREAM); + DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt()); + } trk.init_on_data_seg_sent(tsd); trk.session->init_new_tcp_session(tsd); @@ -167,7 +171,11 @@ bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& Flow* flow = tsd.get_flow(); flow->session_state |= STREAM_STATE_MIDSTREAM; - flow->set_session_flags(SSNFLAG_MIDSTREAM); + if ( !Stream::is_midstream(flow) ) + { + flow->set_session_flags(SSNFLAG_MIDSTREAM); + DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt()); + } trk.init_on_data_seg_recv(tsd); trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs()); trk.session->handle_data_segment(tsd); diff --git a/src/stream/tcp/tcp_state_none.cc b/src/stream/tcp/tcp_state_none.cc index 8bdef30fe..45e83ea11 100644 --- a/src/stream/tcp/tcp_state_none.cc +++ b/src/stream/tcp/tcp_state_none.cc @@ -141,7 +141,11 @@ bool TcpStateNone::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr Flow* flow = tsd.get_flow(); flow->session_state |= STREAM_STATE_MIDSTREAM; - flow->set_session_flags(SSNFLAG_MIDSTREAM); + if ( !Stream::is_midstream(flow) ) + { + flow->set_session_flags(SSNFLAG_MIDSTREAM); + DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt()); + } trk.init_on_data_seg_sent(tsd); trk.session->init_new_tcp_session(tsd); @@ -164,7 +168,11 @@ bool TcpStateNone::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr Flow* flow = tsd.get_flow(); flow->session_state |= STREAM_STATE_MIDSTREAM; - flow->set_session_flags(SSNFLAG_MIDSTREAM); + if ( !Stream::is_midstream(flow) ) + { + flow->set_session_flags(SSNFLAG_MIDSTREAM); + DataBus::publish(STREAM_TCP_MIDSTREAM_EVENT, tsd.get_pkt()); + } trk.init_on_data_seg_recv(tsd); trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->config->require_3whs());