]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1557 in SNORT/snort3 from ~RUCOMBS/snort3:various to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Mon, 25 Mar 2019 16:55:42 +0000 (12:55 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Mon, 25 Mar 2019 16:55:42 +0000 (12:55 -0400)
Squashed commit of the following:

commit b953cc05bab4496ade6f9db8a31cc9e25c965740
Author: russ <rucombs@cisco.com>
Date:   Sun Mar 24 12:09:49 2019 -0400

    stream_tcp: fix up stream order flags

    -- use trivial fsm for proper flagging
    -- remove useless checks from smtp
    -- reorder tracker data members to save 48 bytes / flow

commit 2a04335c17f174bb575e9179a91cb9dc81c20f4e
Author: russ <rucombs@cisco.com>
Date:   Sat Mar 23 00:35:36 2019 -0400

    stream_tcp: add track_only to disable reassembly

commit bdfb917a0a350477b7d02a0acf073931e1926f81
Author: russ <rucombs@cisco.com>
Date:   Fri Mar 22 14:39:32 2019 -0400

    conf: remove obscure and slow automatic iface var assignments; use Lua instead

commit 9173b5a8862e22b2a8d2d3b86f09045d0d5a26de
Author: russ <rucombs@cisco.com>
Date:   Thu Mar 21 20:23:06 2019 -0400

    profiler: add quick exit if not configured to minimize overhead (rule times)

commit 97804d99baafb7b60785f198758ba7e9d1c472cd
Author: russ <rucombs@cisco.com>
Date:   Thu Mar 21 17:46:56 2019 -0400

    appid: fixup profiling

    -- use generic DeepProfile instead of APPID_DEEP_PERF_PROFILING
    -- change tp_library to deep profile consistent with subprofiles

18 files changed:
src/flow/flow.cc
src/main/modules.cc
src/network_inspectors/appid/appid_http_session.cc
src/network_inspectors/appid/client_plugins/client_discovery.cc
src/network_inspectors/appid/ips_appid_option.cc
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/service_plugins/service_discovery.cc
src/network_inspectors/appid/tp_appid_utils.cc
src/parser/parser.cc
src/profiler/rule_profiler.cc
src/profiler/rule_profiler_defs.h
src/service_inspectors/smtp/smtp.cc
src/stream/libtcp/tcp_stream_tracker.cc
src/stream/libtcp/tcp_stream_tracker.h
src/stream/tcp/tcp_module.cc
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_session.h
src/stream/tcp/tcp_stream_config.h

index 34d01e37985ee70df8f7b57d1195a5790209a5b1..a8adde24d093d6216e7a053b52d2139a1e0ad078 100644 (file)
@@ -359,8 +359,6 @@ void Flow::markup_packet_flags(Packet* p)
         if ( p->packet_flags & PKT_STREAM_UNEST_UNI )
             p->packet_flags ^= PKT_STREAM_UNEST_UNI;
     }
-    if ( ssn_state.session_flags & SSNFLAG_STREAM_ORDER_BAD )
-        p->packet_flags |= PKT_STREAM_ORDER_BAD;
 }
 
 void Flow::set_direction(Packet* p)
index b4cc4602731fe2c857ff3afc1a5a3a63ce8f770d..a0f11bfc8f4586221656940f8a9ca78ec9a6a174 100755 (executable)
@@ -513,6 +513,7 @@ bool ProfilerModule::set(const char* fqn, Value& v, SnortConfig* sc)
 bool ProfilerModule::end(const char*, int, SnortConfig* sc)
 {
     TimeProfilerStats::set_enabled(sc->profiler->time.show);
+    RuleContext::set_enabled(sc->profiler->rule.show);
     return true;
 }
 
index 87496370c900be8bf83d2745911c9c24d3e1e362..a3c73539f025f9a5518586be029d76fc766a0b41 100644 (file)
@@ -52,7 +52,6 @@ static const char* httpFieldName[ NUM_HTTP_FIELDS ] = // for use in debug messag
     "body",
 };
 
-#ifdef APPID_DEEP_PERF_PROFILING
 static THREAD_LOCAL snort::ProfileStats process_http_perf_stats;
 static ProfileStats* get_profile(const char*)
 {
@@ -62,9 +61,6 @@ void appid_http_profiler_init()
 {
     Profiler::register_module("http_process", "appid", get_profile);
 }
-#else
-void appid_http_profiler_init() { return; }
-#endif
 
 AppIdHttpSession::AppIdHttpSession(AppIdSession& asd)
     : asd(asd)
@@ -389,9 +385,7 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits)
 int AppIdHttpSession::process_http_packet(AppidSessionDirection direction,
     AppidChangeBits& change_bits)
 {
-#ifdef APPID_DEEP_PERF_PROFILING
-    snort::Profile profile(process_http_perf_stats);
-#endif
+    DeepProfile profile(process_http_perf_stats);
     AppId service_id = APP_ID_NONE;
     AppId client_id = APP_ID_NONE;
     AppId payload_id = APP_ID_NONE;
index 5f99e73d51be0a529639d75d21efb5c86dcf5bfa..41272420bb3c54d5248c70b32745c0123fb5ac56 100644 (file)
@@ -52,13 +52,11 @@ using namespace snort;
 
 #define MAX_CANDIDATE_CLIENTS 10
 
-#ifdef APPID_DEEP_PERF_PROFILING
 static THREAD_LOCAL ProfileStats client_disco_perf_stats;
 static ProfileStats* get_profile(const char*)
 {
     return &client_disco_perf_stats;
 }
-#endif
 
 ClientDiscovery* ClientDiscovery::discovery_manager = nullptr;
 THREAD_LOCAL ClientAppMatch* match_free_list = nullptr;
@@ -128,9 +126,7 @@ void ClientDiscovery::initialize()
     for ( auto kv : udp_detectors )
         kv.second->initialize();
 
-#ifdef APPID_DEEP_PERF_PROFILING
     Profiler::register_module("client_discovery", "appid", get_profile);
-#endif
 }
 
 void ClientDiscovery::finalize_client_plugins()
@@ -362,9 +358,7 @@ void ClientDiscovery::exec_client_detectors(AppIdSession& asd, Packet* p,
 bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p,
     AppidSessionDirection direction, AppidChangeBits& change_bits)
 {
-#ifdef APPID_DEEP_PERF_PROFILING
-    Profile profile(client_disco_perf_stats);
-#endif
+    DeepProfile profile(client_disco_perf_stats);
     bool isTpAppidDiscoveryDone = false;
     AppInfoTableEntry* entry;
     uint32_t prevRnaClientState = asd.client_disco_state;
index fb377a3a5395045064601d3db9a1cd7d107a750b..6b90aa3d531b8ecee2a7ddf4285b3c85d599a252 100644 (file)
@@ -122,11 +122,9 @@ IpsOption::EvalStatus AppIdIpsOption::eval(Cursor&, Packet* p)
     if ( !p->flow )
         return NO_MATCH;
 
-#ifdef APPID_DEEP_PERF_PROFILING
-    Profile profile(ips_appid_perf_stats);
-#endif
-
+    DeepProfile profile(ips_appid_perf_stats);
     AppIdSession* session = appid_api.get_appid_session(*(p->flow));
+
     if ( !session )
         return NO_MATCH;
 
index 1bdd445fd73d4ce216cc65051633d57f47f87ac0..181d88700d27435e91c0bf20ef7216adfea399a5 100644 (file)
@@ -64,7 +64,6 @@ enum LuaLogLevels
     LUA_LOG_TRACE = 5,
 };
 
-#ifdef APPID_DEEP_PERF_PROFILING
 // FIXIT-L: Add separate perf stats for ODP detectors and custom
 // detectors if more granularity is desired
 static THREAD_LOCAL ProfileStats lua_validate_perf_stats;
@@ -77,9 +76,6 @@ void lua_detector_profiler_init()
 {
     Profiler::register_module("lua_validate", "appid", get_profile);
 }
-#else
-void lua_detector_profiler_init() { return; }
-#endif
 
 static std::unordered_map<AppId, CHPApp*>* CHP_glossary = nullptr; // tracks http multipatterns
 
@@ -2640,9 +2636,7 @@ LuaServiceObject::LuaServiceObject(AppIdDiscovery* sdm, const std::string& detec
 
 int LuaServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-#ifdef APPID_DEEP_PERF_PROFILING
-    Profile profile(lua_validate_perf_stats);
-#endif
+    DeepProfile profile(lua_validate_perf_stats);
     //FIXIT-M: RELOAD - use lua references to get user data object from stack
     auto my_lua_state = lua_detector_mgr? lua_detector_mgr->L : nullptr;
     lua_settop(my_lua_state,0);
@@ -2720,9 +2714,7 @@ LuaStateDescriptor* LuaObject::validate_lua_state(bool packet_context)
 
 int LuaClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-#ifdef APPID_DEEP_PERF_PROFILING
-    Profile profile(lua_validate_perf_stats);
-#endif
+    DeepProfile profile(lua_validate_perf_stats);
     //FIXIT-M: RELOAD - use lua references to get user data object from stack
     auto my_lua_state = lua_detector_mgr? lua_detector_mgr->L : nullptr;
     std::string name = this->name + "_";
index a5f57839ebff1e0a4b6c5d78bc3b29da8524af1f..f35fcd473365c0525477c1a1e08b9657cb6c7504 100644 (file)
 
 using namespace snort;
 
-#ifdef APPID_DEEP_PERF_PROFILING
 static THREAD_LOCAL ProfileStats service_disco_perf_stats;
 static ProfileStats* get_profile(const char*)
 {
     return &service_disco_perf_stats;
 }
-#endif
 
 static ServiceDetector* ftp_service;
 ServiceDiscovery* ServiceDiscovery::discovery_manager = nullptr;
@@ -182,9 +180,7 @@ void ServiceDiscovery::initialize()
         service_detector_list.emplace_back(kv.second);
     }
 
-#ifdef APPID_DEEP_PERF_PROFILING
     Profiler::register_module("service_discovery", "appid", get_profile);
-#endif
 }
 
 void ServiceDiscovery::finalize_service_patterns()
@@ -595,9 +591,7 @@ int ServiceDiscovery::add_ftp_service_state(AppIdSession& asd)
 bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
     AppidSessionDirection direction, AppidChangeBits& change_bits)
 {
-#ifdef APPID_DEEP_PERF_PROFILING
-    Profile profile(service_disco_perf_stats);
-#endif
+    DeepProfile profile(service_disco_perf_stats);
     bool isTpAppidDiscoveryDone = false;
     uint32_t prevRnaServiceState = asd.service_disco_state;
     AppId tp_app_id = asd.get_tp_app_id();
index 34f1a3ce0a94ca60ffa266ae45f68e83782d05d3..66a49af3ab9f640e46cb73391eb0c007e69c56bb 100644 (file)
@@ -54,8 +54,8 @@ using namespace snort;
 typedef AppIdHttpSession::pair_t pair_t;
 
 static THREAD_LOCAL ProfileStats tp_lib_perf_stats;
-#ifdef APPID_DEEP_PERF_PROFILING
 static THREAD_LOCAL ProfileStats tp_disco_perf_stats;
+
 static ProfileStats* get_profile(const char* key)
 {
     if ( !strcmp(key, "tp_discovery") )
@@ -64,21 +64,12 @@ static ProfileStats* get_profile(const char* key)
         return &tp_lib_perf_stats;
     return nullptr;
 }
+
 void tp_appid_profiler_init()
 {
     Profiler::register_module("tp_discovery", "appid", get_profile);
     Profiler::register_module("tp_library", "tp_discovery", get_profile);
 }
-#else
-static ProfileStats* get_profile(const char*)
-{
-    return &tp_lib_perf_stats;
-}
-void tp_appid_profiler_init()
-{
-    Profiler::register_module("tp_library", "appid", get_profile);
-}
-#endif
 
 static inline bool contains(const vector<AppId>& vec, const AppId val)
 {
@@ -645,10 +636,7 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo
 bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol,
     Packet* p, AppidSessionDirection& direction, AppidChangeBits& change_bits)
 {
-#ifdef APPID_DEEP_PERF_PROFILING
-    Profile tp_disco_profile(tp_disco_perf_stats);
-#endif
-
+    DeepProfile tp_disco_profile(tp_disco_perf_stats);
     AppId tp_app_id = asd.get_tp_app_id();
 
     if (tp_app_id == APP_ID_SSH && asd.payload.get_id() != APP_ID_SFTP &&
@@ -685,10 +673,11 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol,
             if (protocol != IpProtocol::TCP || (p->packet_flags & PKT_STREAM_ORDER_OK)
                 || asd.config->mod_config->tp_allow_probes)
             {
-                Profile tp_lib_profile(tp_lib_perf_stats);
+                DeepProfile tp_lib_profile(tp_lib_perf_stats);
                 int tp_confidence;
                 ThirdPartyAppIDAttributeData tp_attribute_data;
                 vector<AppId> tp_proto_list;
+
                 if (!asd.tpsession)
                 {
                     const TPLibHandler* tph = TPLibHandler::get();
index a5b6f3473500e7b2ca9a4316a7fe0aeb36aabba7..11e28ddcf9907c03df3ec00b329d9af720834df4 100644 (file)
@@ -201,98 +201,6 @@ static void OtnInit(SnortConfig* sc)
         ParseAbort("ParseRulesFile otn_map ghash_new failed.");
 }
 
-#define IFACE_VARS_MAX 128
-typedef struct iface_var
-{
-    char name[128];
-    uint32_t net;
-    uint32_t netmask;
-} iface_var_t;
-
-/****************************************************************************
- *
- * Function  : DefineIfaceVar()
- * Purpose   : Assign network address and network mask to IFACE_ADDR_VARNAME
- *             variable.
- * Arguments : interface name (string) netaddress and netmask (4 octets each)
- * Returns   : void function
- *
- ****************************************************************************/
-static void DefineIfaceVar(SnortConfig* sc, char* iname, const uint8_t* network, const uint8_t* netmask)
-{
-    char valbuf[32];
-    char varbuf[BUFSIZ];
-
-    if ((network == nullptr) || (*network == 0))
-        return;
-
-    SnortSnprintf(varbuf, BUFSIZ, "%s_ADDRESS", iname);
-
-    SnortSnprintf(valbuf, 32, "%d.%d.%d.%d/%d.%d.%d.%d",
-        network[0] & 0xff, network[1] & 0xff, network[2] & 0xff,
-        network[3] & 0xff, netmask[0] & 0xff, netmask[1] & 0xff,
-        netmask[2] & 0xff, netmask[3] & 0xff);
-
-    VarDefine(sc, varbuf, valbuf);
-}
-
-// Find all up interfaces and define iface_ADDRESS vars for them
-static void DefineAllIfaceVars(SnortConfig* sc)
-{
-    // FIXIT-L don't come back here on reload unless we are going to find
-    // new ifaces.  Cache retrieved devs so if user is running with dropped
-    // privs and does a reload, we can use previous values
-    static int num_vars = 0;
-
-    // should be more than enough to cover the number of interfaces on a machine
-    static iface_var_t iface_vars[IFACE_VARS_MAX];
-
-    if (num_vars > 0)
-    {
-        int i;
-
-        for (i = 0; i < num_vars; i++)
-        {
-            DefineIfaceVar(sc, iface_vars[i].name,
-                (uint8_t*)&iface_vars[i].net,
-                (uint8_t*)&iface_vars[i].netmask);
-        }
-    }
-    else
-    {
-        char errbuf[PCAP_ERRBUF_SIZE];
-        pcap_if_t* alldevs;
-        pcap_if_t* dev;
-        bpf_u_int32 net, netmask;
-
-        if (pcap_findalldevs(&alldevs, errbuf) == -1)
-            return;
-
-        for (dev = alldevs; dev != nullptr; dev = dev->next)
-        {
-            if (pcap_lookupnet(dev->name, &net, &netmask, errbuf) == 0)
-            {
-                /* We've hit the maximum variables we can cache */
-                if (num_vars >= IFACE_VARS_MAX)
-                    break;
-
-                SnortSnprintf(iface_vars[num_vars].name,
-                    sizeof(iface_vars[num_vars].name), "%s", dev->name);
-
-                DefineIfaceVar(sc, iface_vars[num_vars].name,
-                    (uint8_t*)&net,
-                    (uint8_t*)&netmask);
-
-                iface_vars[num_vars].net = net;
-                iface_vars[num_vars].netmask = netmask;
-                num_vars++;
-            }
-        }
-
-        pcap_freealldevs(alldevs);
-    }
-}
-
 static RuleListNode* addNodeToOrderedList(RuleListNode* ordered_list,
     RuleListNode* node, int evalIndex)
 {
@@ -397,11 +305,6 @@ SnortConfig* ParseSnortConf(const SnortConfig* boot_conf, const char* fname, boo
     sc->rate_filter_config = RateFilter_ConfigNew();
     sc->detection_filter_config = DetectionFilterConfigNew();
 
-    /* If snort is not run with root privileges, no interfaces will be defined,
-     * so user beware if an iface_ADDRESS variable is used in snort.conf and
-     * snort is not run as root (even if just in read mode) */
-    DefineAllIfaceVars(sc);
-
     /* Add command line defined variables - duplicates will already
      * have been resolved */
     while (tmp != nullptr)
index e1a15eb6d3e4f5eefffbc869aad261e6b363f914..3fa0d078f562c261176919df7da0ff7cd1ded289 100644 (file)
@@ -55,6 +55,8 @@ using namespace snort;
 
 #define s_rule_table_title "rule profile"
 
+bool RuleContext::enabled = false;
+
 static inline OtnState& operator+=(OtnState& lhs, const OtnState& rhs)
 {
     lhs.elapsed += rhs.elapsed;
@@ -334,7 +336,7 @@ void reset_rule_profiler_stats()
 
 void RuleContext::stop(bool match)
 {
-    if ( finished )
+    if ( !enabled or finished )
         return;
 
     finished = true;
@@ -682,6 +684,7 @@ TEST_CASE( "rule profiler sorting", "[profiler][rule_profiler]" )
 TEST_CASE( "rule profiler time context", "[profiler][rule_profiler]" )
 {
     dot_node_state_t stats;
+    RuleContext::set_enabled(true);
 
     stats.elapsed = 0_ticks;
     stats.checks = 0;
@@ -740,12 +743,14 @@ TEST_CASE( "rule profiler time context", "[profiler][rule_profiler]" )
         CHECK( stats.elapsed_match == save.elapsed_match );
         CHECK( stats.checks == save.checks );
     }
+    RuleContext::set_enabled(false);
 }
 
 TEST_CASE( "rule pause", "[profiler][rule_profiler]" )
 {
     dot_node_state_t stats;
     RuleContext ctx(stats);
+    RuleContext::set_enabled(true);
 
     {
         RulePause pause(ctx);
@@ -753,6 +758,7 @@ TEST_CASE( "rule pause", "[profiler][rule_profiler]" )
     }
 
     CHECK( ctx.active() );
+    RuleContext::set_enabled(false);
 }
 
 #endif
index d168b47d0f23fb95a1d92be5e1d438dace4bc4bb..c0a7988eb8b318a17777b484978afe3951fa6395 100644 (file)
@@ -55,20 +55,24 @@ public:
     { stop(); }
 
     void start()
-    { sw.start(); }
+    { if ( enabled ) sw.start(); }
 
     void pause()
-    { sw.stop(); }
+    { if ( enabled ) sw.stop(); }
 
     void stop(bool = false);
 
     bool active() const
-    { return sw.active(); }
+    { return enabled and sw.active(); }
+
+    static void set_enabled(bool b)
+    { enabled = b; }
 
 private:
     dot_node_state_t& stats;
     Stopwatch<SnortClock> sw;
     bool finished = false;
+    static bool enabled;
 };
 
 class RulePause
index 1ff7e1beb431eb17e53bb60c787fd5287f8cab55..1aaef0436252296bc9aa42e001c552e8a3595a64 100644 (file)
@@ -1050,14 +1050,7 @@ static void SMTP_ProcessServerPacket(
         else if ( !p->test_session_flags(SSNFLAG_MIDSTREAM)
             && !Stream::missed_packets(p->flow, SSN_DIR_BOTH))
         {
-            /* Check to see if the raw packet is in order */
-            if (p->packet_flags & PKT_STREAM_ORDER_OK)
-            {
-                /* revert back to command state - assume server didn't accept STARTTLS */
-                smtp_ssn->state = STATE_COMMAND;
-            }
-            else
-                return;
+            smtp_ssn->state = STATE_COMMAND;
         }
     }
 
@@ -1188,7 +1181,7 @@ static void snort_smtp(SMTP_PROTO_CONF* config, Packet* p)
             {
                 smtp_ssn->state = STATE_TLS_SERVER_PEND;
             }
-            else if (p->packet_flags & PKT_STREAM_ORDER_OK)
+            else
             {
                 /* reset state - server may have rejected STARTTLS command */
                 smtp_ssn->state = STATE_COMMAND;
index 4257966309bc503c4335641962f433d0bd5f8d0e..86eb7ece45b6c0d8b9f1e3a0f8d17b0c586a6b47 100644 (file)
@@ -55,7 +55,7 @@ const char* tcp_event_names[] = {
 };
 
 TcpStreamTracker::TcpStreamTracker(bool client) :
-    client_tracker(client), tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN)
+    tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN), client_tracker(client)
 { }
 
 TcpStreamTracker::~TcpStreamTracker()
@@ -198,6 +198,7 @@ void TcpStreamTracker::init_tcp_state()
     fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN;
     fin_seq_set = false;
     rst_pkt_sent = false;
+    order = 0;
 }
 
 //-------------------------------------------------------------------------
index b2f0fd2d4f5ca47e2589bc6b9f4aeefe65096d06..920ee7d505948a904ec34c9a78e0e343adecb4fd 100644 (file)
@@ -51,7 +51,7 @@ class TcpSession;
 class TcpStreamTracker
 {
 public:
-    enum TcpState
+    enum TcpState : uint8_t
     {
         TCP_LISTEN,
         TCP_SYN_SENT,
@@ -68,7 +68,7 @@ public:
         TCP_MAX_STATES
     };
 
-    enum TcpEvent
+    enum TcpEvent : uint8_t
     {
         TCP_SYN_SENT_EVENT,
         TCP_SYN_RECV_EVENT,
@@ -85,7 +85,7 @@ public:
         TCP_MAX_EVENTS
     };
 
-    enum FinSeqNumStatus { FIN_NOT_SEEN, FIN_WITH_SEQ_SEEN, FIN_WITH_SEQ_ACKED };
+    enum FinSeqNumStatus : uint8_t { FIN_NOT_SEEN, FIN_WITH_SEQ_SEEN, FIN_WITH_SEQ_ACKED };
 
     TcpStreamTracker(bool client);
     virtual ~TcpStreamTracker();
@@ -277,63 +277,71 @@ public:
     virtual bool is_segment_seq_valid(TcpSegmentDescriptor&);
     virtual void flush_data_on_fin_recv(TcpSegmentDescriptor&);
 
-    bool client_tracker;
-    TcpState tcp_state;
-    TcpEvent tcp_event = TCP_MAX_EVENTS;
-    bool require_3whs = false;
-
+public:
     uint32_t snd_una = 0; // SND.UNA - send unacknowledged
     uint32_t snd_nxt = 0; // SND.NXT - send next
     uint32_t snd_wnd = 0; // SND.WND - send window
-    uint16_t snd_up = 0;  // SND.UP  - send urgent pointer
     uint32_t snd_wl1 = 0; // SND.WL1 - segment sequence number used for last window update
     uint32_t snd_wl2 = 0; // SND.WL2 - segment acknowledgment number used for last window update
     uint32_t iss = 0;     // ISS     - initial send sequence number
 
     uint32_t rcv_nxt = 0; // RCV.NXT - receive next
     uint32_t rcv_wnd = 0; // RCV.WND - receive window
-    uint16_t rcv_up = 0;  // RCV.UP  - receive urgent pointer
     uint32_t irs = 0;     // IRS     - initial receive sequence number
 
+    uint16_t snd_up = 0;  // SND.UP  - send urgent pointer
+    uint16_t rcv_up = 0;  // RCV.UP  - receive urgent pointer
+
+    TcpState tcp_state;
+    TcpEvent tcp_event = TCP_MAX_EVENTS;
+
+    bool client_tracker;
+    bool require_3whs = false;
     bool rst_pkt_sent = false;
 
 // FIXIT-L make these non-public
 public:
-    uint32_t r_win_base = 0; /* remote side window base sequence number
-     * (i.e. the last ack we got) */
-
-    TcpSession* session = nullptr;
     TcpNormalizerPolicy normalizer;
     TcpReassemblerPolicy reassembler;
-    snort::StreamSplitter* splitter = nullptr;
 
-    uint32_t small_seg_count = 0;
-    uint8_t alert_count = 0;
     StreamAlertInfo alerts[MAX_SESSION_ALERTS];
-    FlushPolicy flush_policy = STREAM_FLPOLICY_IGNORE;
+
     // this is intended to be private to paf but is included
     // directly to avoid the need for allocation; do not directly
     // manipulate within this module.
     PAF_State paf_state;    // for tracking protocol aware flushing
 
+    TcpSession* session = nullptr;
+    snort::StreamSplitter* splitter = nullptr;
+
+    FlushPolicy flush_policy = STREAM_FLPOLICY_IGNORE;
+
+    uint32_t r_win_base = 0; // remote side window base sequence number (the last ack we got)
+    uint32_t small_seg_count = 0;
+
+    uint16_t wscale = 0; /* window scale setting */
+    uint16_t mss = 0; /* max segment size */
+
+    uint8_t alert_count = 0;
+    uint8_t order = 0;
+
+    FinSeqNumStatus fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN;
+
 protected:
     // FIXIT-H reorganize per-flow structs to minimize padding
     uint32_t ts_last_packet = 0;
     uint32_t ts_last = 0; /* last timestamp (for PAWS) */
-    uint16_t tf_flags = 0;
 
-    uint8_t mac_addr[6] = { };
-    bool mac_addr_valid = false;
     uint32_t fin_final_seq = 0;
     uint32_t fin_seq_adjust = 0;
-    bool fin_seq_set = false;  // FIXIT-M should be obviated by tcp state
+
+    uint16_t tf_flags = 0;
+
+    uint8_t mac_addr[6] = { };
     uint8_t tcp_options_len = 0;
 
-    // FIXIT-L make this protected...
-public:
-    uint16_t wscale = 0; /* window scale setting */
-    uint16_t mss = 0; /* max segment size */
-    FinSeqNumStatus fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN;
+    bool mac_addr_valid = false;
+    bool fin_seq_set = false;  // FIXIT-M should be obviated by tcp state
 };
 
 // <--- note -- the 'state' parameter must be a reference
index 6c6cf00ab1ec81c7e638ba9cd7ee49817d96449d..6698937fbd41e3962d88ec3592f768e97db34f82 100644 (file)
@@ -187,6 +187,9 @@ static const Parameter s_params[] =
     { "session_timeout", Parameter::PT_INT, "1:max31", "30",
       "session tracking timeout" },
 
+    { "track_only", Parameter::PT_BOOL, nullptr, "false",
+      "disable reassembly if true" },
+
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
@@ -331,6 +334,13 @@ bool StreamTcpModule::set(const char*, Value& v, SnortConfig*)
         else
             config->flags &= ~STREAM_CONFIG_SHOW_PACKETS;
     }
+    else if ( v.is("track_only") )
+    {
+        if ( v.get_bool() )
+            config->flags |= STREAM_CONFIG_NO_REASSEMBLY;
+        else
+            config->flags &= ~STREAM_CONFIG_NO_REASSEMBLY;
+    }
     else
         return false;
 
index f5aa03aa93af8b1ee0d2e88e20b588ff1cd4adcf..6a0593de4123dd57494bc32900e919abbd22d2f3 100644 (file)
@@ -343,6 +343,30 @@ void TcpSession::process_tcp_stream(TcpSegmentDescriptor& tsd)
     }
 }
 
+void TcpSession::update_stream_order(TcpSegmentDescriptor& tsd, bool aligned)
+{
+    switch ( listener->order )
+    {
+    case 0:
+        if ( aligned )
+            tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK;
+        else
+            listener->order = 1;
+        break;
+    case 1:
+        if ( aligned )
+        {
+            tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK;
+            listener->order = 2;
+        }
+        break;
+    default:
+        if ( !(flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD) )
+            flow->set_session_flags(SSNFLAG_STREAM_ORDER_BAD);
+        tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_BAD;
+    }
+}
+
 int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd)
 {
     DeepProfile profile(s5TcpDataPerfStats);
@@ -378,12 +402,8 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd)
 
         if (tsd.get_seg_len() != 0)
         {
-            if (!( flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD))
-                tsd.get_pkt()->packet_flags |= PKT_STREAM_ORDER_OK;
-
+            update_stream_order(tsd, true);
             process_tcp_stream(tsd);
-            /* set flags to session flags */
-
             return STREAM_ALIGNED;
         }
     }
@@ -402,25 +422,9 @@ int TcpSession::process_tcp_data(TcpSegmentDescriptor& tsd)
             listener->normalizer.trim_win_payload(tsd);
             return STREAM_UNALIGNED;
         }
-
-        if ((listener->get_tcp_state() == TcpStreamTracker::TCP_ESTABLISHED)
-            && (listener->flush_policy == STREAM_FLPOLICY_IGNORE))
-        {
-            if (SEQ_GT(tsd.get_end_seq(), listener->rcv_nxt))
-            {
-                // set next ack so we are within the window going forward on this side.
-                // FIXIT-L for ips, must move all the way to first hole or right end
-                listener->rcv_nxt = tsd.get_end_seq();
-            }
-        }
-
         if (tsd.get_seg_len() != 0)
         {
-            if (!( flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD))
-            {
-                if (!SEQ_LEQ((tsd.get_seg_seq() + tsd.get_seg_len()), listener->rcv_nxt))
-                    flow->set_session_flags(SSNFLAG_STREAM_ORDER_BAD);
-            }
+            update_stream_order(tsd, false);
             process_tcp_stream(tsd);
         }
     }
@@ -967,12 +971,14 @@ bool TcpSession::do_packet_analysis_pre_checks(Packet* p, TcpSegmentDescriptor&
 
     if ( !splitter_init and tsd.get_seg_len() > 0 )
     {
-        client.set_splitter(tsd.get_flow());
-        server.set_splitter(tsd.get_flow());
-
-        client.init_flush_policy();
-        server.init_flush_policy();
+        if ( !(config->flags & STREAM_CONFIG_NO_REASSEMBLY) )
+        {
+            client.set_splitter(tsd.get_flow());
+            server.set_splitter(tsd.get_flow());
 
+            client.init_flush_policy();
+            server.init_flush_policy();
+        }
         splitter_init = true;
     }
 
index 7b9de1e5b0aa5cef944f578e672da82a85836fa4..ba247867b6bd9cf5468f7c22fff09f32b56d9945 100644 (file)
@@ -72,6 +72,7 @@ public:
 private:
     void set_os_policy() override;
     bool flow_exceeds_config_thresholds(TcpSegmentDescriptor&);
+    void update_stream_order(TcpSegmentDescriptor&, bool aligned);
     void process_tcp_stream(TcpSegmentDescriptor&);
     int process_tcp_data(TcpSegmentDescriptor&);
     void swap_trackers();
index f5c48b457ca8a0fbda9face375850b547daf5e39..5bbf9819656f0910d25a3ce67eff192ddd49bc74 100644 (file)
@@ -28,6 +28,7 @@
 
 #define STREAM_CONFIG_SHOW_PACKETS             0x00000001
 #define STREAM_CONFIG_NO_ASYNC_REASSEMBLY      0x00000002
+#define STREAM_CONFIG_NO_REASSEMBLY            0x00000004
 
 #define STREAM_DEFAULT_SSN_TIMEOUT  30