]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1229 in SNORT/snort3 from appid_ooo to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 21 May 2018 20:54:09 +0000 (16:54 -0400)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Mon, 21 May 2018 20:54:09 +0000 (16:54 -0400)
Squashed commit of the following:

commit da9049260a50d2a5e08b7e024c7d05f53f18d609
Author: Shravan Rangaraju <shrarang@cisco.com>
Date:   Tue May 15 09:54:57 2018 -0400

    appid: do not inspect out-of-order flows, ignore zero-payload packets for client/service discovery

src/network_inspectors/appid/appid_api.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_discovery.h
src/network_inspectors/appid/tp_appid_utils.cc

index 829887277377d5a0c8fafd93caff44763eec68aa..eab8e1c311a7f977bb5853bd0f3ef333807f1d01 100644 (file)
@@ -85,9 +85,7 @@ namespace snort
 #define APPID_SESSION_NO_TPI                (1ULL << 38)
 #define APPID_SESSION_IGNORE_FLOW           (1ULL << 39)
 #define APPID_SESSION_IGNORE_FLOW_LOGGED    (1ULL << 40)
-#define APPID_SESSION_OOO_LOGGED            (1ULL << 41)
-#define APPID_SESSION_TPI_OOO_LOGGED        (1ULL << 42)
-#define APPID_SESSION_EXPECTED_EVALUATE     (1ULL << 43)
+#define APPID_SESSION_EXPECTED_EVALUATE     (1ULL << 41)
 #define APPID_SESSION_IGNORE_ID_FLAGS \
     (APPID_SESSION_IGNORE_FLOW | \
     APPID_SESSION_NOT_A_SERVICE | \
index 29f7c80ff0a2de489fcdec811381595357983ae5..c54f23858b28d666685bd20f4227a70e2cb74e64 100644 (file)
@@ -51,7 +51,7 @@
 
 using namespace snort;
 
-bool do_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&);
+bool do_tp_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&);
 
 AppIdDiscovery::AppIdDiscovery(AppIdInspector& ins)
     : inspector(ins)
@@ -134,6 +134,19 @@ int AppIdDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&)
     return APPID_EINVALID;
 }
 
+void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
+{
+    IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
+    AppidSessionDirection direction = APP_ID_FROM_INITIATOR;
+    AppIdSession* asd = (AppIdSession*)p->flow->get_flow_data(AppIdSession::inspector_id);
+
+    if (!do_pre_discovery(p, &asd, inspector, protocol, direction)) return;
+
+    bool is_discovery_done = do_discovery(p, *asd, protocol, direction);
+
+    do_post_discovery(p, *asd, direction, is_discovery_done);
+}
+
 static inline int match_pe_network(const SfIp* pktAddr, const PortExclusion* pe)
 {
     const uint32_t* pkt = pktAddr->get_ip6_ptr();
@@ -339,6 +352,8 @@ static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirectio
     }
     else if ( p->is_rebuilt() && !p->flow->is_proxied() )
     {
+        // FIXIT-M: In snort2x, a rebuilt packet was ignored whether it had a session or not. 
+        // Here, we are ignoring rebuilt packet only if it has a session. Why?
         if ( asd )
         {
             AppIdHttpSession* hsession = asd->get_http_session();
@@ -353,8 +368,8 @@ static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirectio
                         hsession->get_field_offset(REQ_COOKIE_FID),
                         hsession->get_field_end_offset(REQ_COOKIE_FID));
             }
-        appid_stats.ignored_packets++;
-        return true;
+            appid_stats.ignored_packets++;
+            return true;
         }
     }
 
@@ -601,88 +616,96 @@ static void lookup_appid_by_host_port(AppIdSession& asd, Packet* p, IpProtocol p
     }
 }
 
-void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
+bool AppIdDiscovery::handle_unmonitored_session(AppIdSession* asd, const Packet* p,
+    IpProtocol protocol, AppidSessionDirection dir, AppIdInspector& inspector,
+    uint64_t& flow_flags)
 {
-    IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
-    bool isTpAppidDiscoveryDone = true;
-    AppidSessionDirection direction = APP_ID_FROM_INITIATOR;
-
-    AppIdSession* asd = (AppIdSession*)p->flow->get_flow_data(AppIdSession::inspector_id);
-    if ( !set_network_attributes(asd, p, protocol, direction) )
-    {
-        appid_stats.ignored_packets++;
-        return;
-    }
-
-    if (appidDebug->is_enabled())
-        appidDebug->activate(p->flow, asd, inspector.get_appid_config()->mod_config->log_all_sessions);
-
-    if ( is_packet_ignored(asd, p, direction) )
-        return;
-
-    // Create a TPDiscovery object from a TPLibHandle.
-    uint64_t flow_flags;
     if (asd)
-        flow_flags = is_session_monitored(*asd, p, direction, inspector);
+        flow_flags = is_session_monitored(*asd, p, dir, inspector);
     else
-        flow_flags = is_session_monitored(p, direction, inspector);
+        flow_flags = is_session_monitored(p, dir, inspector);
+
+    if ( flow_flags & (APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED) )
+        return false;
 
-    if ( !( flow_flags & (APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED) ) )
+    if ( !asd )
     {
-        if ( !asd )
-        {
-            uint16_t port = 0;
+        uint16_t port = 0;
 
-            const SfIp* ip = (direction == APP_ID_FROM_INITIATOR) ?
-                p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
-            if ((protocol == IpProtocol::TCP || protocol == IpProtocol::UDP)
-                && p->ptrs.sp != p->ptrs.dp)
-            {
-                port = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp;
-            }
+        const SfIp* ip = (dir == APP_ID_FROM_INITIATOR) ?
+            p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
+        if ((protocol == IpProtocol::TCP || protocol == IpProtocol::UDP)
+            && p->ptrs.sp != p->ptrs.dp)
+        {
+            port = (dir == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp;
+        }
 
-            // FIXIT-H - Creating AppId session even when flow is ignored (not monitored, e.g.,
-            // when AppId discovery is disabled) will consume a lot of unneeded memory and perform
-            // unneeded tasks in constructor. Snort2 uses static APPID_SESSION_STRUCT_FLAG ignore_fsf.
-            // Snort3 may use something like that or a dummy class/object having only common.flow_type
-            // to let us know that it is APPID_FLOW_TYPE_IGNORE type and thus being returned early
-            // from this method due to set_network_attributes() checking.
-            AppIdSession* tmp_session = new AppIdSession(protocol, ip, port, inspector);
+        // FIXIT-H - Creating AppId session even when flow is ignored (not monitored, e.g.,
+        // when AppId discovery is disabled) will consume a lot of unneeded memory and perform
+        // unneeded tasks in constructor. Snort2 uses static APPID_SESSION_STRUCT_FLAG ignore_fsf.
+        // Snort3 may use something like that or a dummy class/object having only common.flow_type
+        // to let us know that it is APPID_FLOW_TYPE_IGNORE type and thus being returned early
+        // from this method due to set_network_attributes() checking.
+        AppIdSession* tmp_session = new AppIdSession(protocol, ip, port, inspector);
 
-            if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
-                APPID_SESSION_BIDIRECTIONAL_CHECKED)
-            {
-                tmp_session->common.flow_type = APPID_FLOW_TYPE_IGNORE;
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s Not monitored\n", appidDebug->get_debug_session());
-            }
-            else
-            {
-                tmp_session->common.flow_type = APPID_FLOW_TYPE_TMP;
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s Unknown monitoring\n", appidDebug->get_debug_session());
-            }
-            tmp_session->common.flags = flow_flags;
-            tmp_session->common.policyId = inspector.get_appid_config()->appIdPolicyId;
-            p->flow->set_flow_data(tmp_session);
+        if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
+            APPID_SESSION_BIDIRECTIONAL_CHECKED)
+        {
+            tmp_session->common.flow_type = APPID_FLOW_TYPE_IGNORE;
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s Not monitored\n", appidDebug->get_debug_session());
         }
         else
         {
-            asd->common.flags = flow_flags;
-            if ( ( flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
-                APPID_SESSION_BIDIRECTIONAL_CHECKED )
-                asd->common.flow_type = APPID_FLOW_TYPE_IGNORE;
-            asd->common.policyId = asd->config->appIdPolicyId;
+            tmp_session->common.flow_type = APPID_FLOW_TYPE_TMP;
             if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s Not monitored\n", appidDebug->get_debug_session());
+                LogMessage("AppIdDbg %s Unknown monitoring\n", appidDebug->get_debug_session());
         }
+        tmp_session->common.flags = flow_flags;
+        tmp_session->common.policyId = inspector.get_appid_config()->appIdPolicyId;
+        p->flow->set_flow_data(tmp_session);
+    }
+    else
+    {
+        asd->common.flags = flow_flags;
+        if ( ( flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
+            APPID_SESSION_BIDIRECTIONAL_CHECKED )
+            asd->common.flow_type = APPID_FLOW_TYPE_IGNORE;
+        asd->common.policyId = asd->config->appIdPolicyId;
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s Not monitored\n", appidDebug->get_debug_session());
+    }
+
+    return true;
+}
+
+// Return false if the packet or the session doesn't need to be inspected
+bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInspector& inspector,
+    IpProtocol& protocol, AppidSessionDirection& direction)
+{
+    AppIdSession* asd = *p_asd;
 
-        return;
+    if ( !set_network_attributes(asd, p, protocol, direction) )
+    {
+        appid_stats.ignored_packets++;
+        return false;
     }
 
+    if ( appidDebug->is_enabled() )
+        appidDebug->activate(p->flow, asd, inspector.get_appid_config()->mod_config->log_all_sessions);
+
+    if ( is_packet_ignored(asd, p, direction) )
+        return false;
+
+    uint64_t flow_flags;
+    if ( handle_unmonitored_session(asd, p, protocol, direction, inspector, flow_flags) )
+        return false;
+
+    // FIXIT-M - Potential memory leak for TMP sessions. handle_unmonitored_session() already
+    // TMP session and that is not being freed before creating the new one below
     if ( !asd || asd->common.flow_type == APPID_FLOW_TYPE_TMP )
     {
-        asd = AppIdSession::allocate_session(p, protocol, direction, inspector);
+        *p_asd = asd = AppIdSession::allocate_session(p, protocol, direction, inspector);
         if (p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
         {
             asd->set_session_flags(APPID_SESSION_MID);
@@ -693,8 +716,8 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
             LogMessage("AppIdDbg %s New AppId session\n", appidDebug->get_debug_session());
     }
 
-    // FIXIT-L - from this point on we always have a valid ptr to an AppIdSession and a Packet
-    //           refactor to pass these as refs and delete any checks for null
+    // FIXIT-L - from this point on we always have a valid ptr to a Packet
+    //           refactor to pass this as ref and delete any checks for null
     appid_stats.processed_packets++;
     asd->session_packet_count++;
 
@@ -716,60 +739,91 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
                 appidDebug->get_debug_session(), asd->service.get_id());
         }
 
-        return;
+        return false;
     }
 
-    // FIXIT-H - Bring APPID_SESSION_OOO related changes from snort2 ASAP for performance reason
-    if (p->packet_flags & PKT_STREAM_ORDER_BAD)
-        asd->set_session_flags(APPID_SESSION_OOO);
-    else if ( p->is_tcp() && p->ptrs.tcph )
+    if (p->ptrs.tcph and !asd->get_session_flags(APPID_SESSION_OOO))
     {
-        const auto* tcph = p->ptrs.tcph;
-        if ( tcph->is_rst() && asd->previous_tcp_flags == TH_SYN )
+        if ((p->packet_flags & PKT_STREAM_ORDER_BAD) ||
+            (p->dsize && !(p->packet_flags & (PKT_STREAM_ORDER_OK | PKT_REBUILT_STREAM))))
         {
-            uint16_t port = 0;
-            const SfIp* ip = nullptr;
-
-            asd->set_session_flags(APPID_SESSION_SYN_RST);
-            if (asd->service_ip.is_set())
+            asd->set_session_flags(APPID_SESSION_OOO);
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s Packet out-of-order, %s%sflow\n", appidDebug->get_debug_session(),
+                    (p->packet_flags & PKT_STREAM_ORDER_BAD)? "bad ":"not-ok ",
+                    asd->get_session_flags(APPID_SESSION_MID)? "mid-stream ":"");
+
+            // Shut off service/client discoveries, since they skip not-ok data packets and
+            // may keep failing on subsequent data packets causing performance degradation
+            if (!asd->get_session_flags(APPID_SESSION_MID) ||
+                (p->ptrs.sp != 21 && p->ptrs.dp != 21)) // exception for ftp-control
             {
-                ip = &asd->service_ip;
-                port = asd->service_port;
+                asd->service_disco_state = APPID_DISCO_STATE_FINISHED;
+                asd->client_disco_state = APPID_DISCO_STATE_FINISHED;
+                asd->set_session_flags(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CLIENT_DETECTED);
+                if (appidDebug->is_active())
+                    LogMessage("AppIdDbg %s stopped service/client discovery\n", appidDebug->get_debug_session());
             }
-            else
+        }
+        else
+        {
+            const auto* tcph = p->ptrs.tcph;
+            if ( tcph->is_rst() && asd->previous_tcp_flags == TH_SYN )
             {
-                ip = p->ptrs.ip_api.get_src();
-                port = p->ptrs.sp;
+                uint16_t port = 0;
+                const SfIp* ip = nullptr;
+
+                asd->set_session_flags(APPID_SESSION_SYN_RST);
+                if (asd->service_ip.is_set())
+                {
+                    ip = &asd->service_ip;
+                    port = asd->service_port;
+                }
+                else
+                {
+                    ip = p->ptrs.ip_api.get_src();
+                    port = p->ptrs.sp;
+                }
+
+                AppIdServiceState::check_reset(*asd, ip, port);
             }
 
-            AppIdServiceState::check_reset(*asd, ip, port);
+            asd->previous_tcp_flags = p->ptrs.tcph->th_flags;
         }
-
-        asd->previous_tcp_flags = p->ptrs.tcph->th_flags;
     }
 
-    /*HostPort based AppId.  */
-    if ( !(asd->scan_flags & SCAN_HOST_PORT_FLAG) )
-        lookup_appid_by_host_port(*asd, p, protocol, direction);
+    return true;
+}
 
-    asd->check_app_detection_restart();
+bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol protocol,
+    AppidSessionDirection direction)
+{
+    bool is_discovery_done = false;
+
+    // {host, port} based detection
+    if ( !(asd.scan_flags & SCAN_HOST_PORT_FLAG) )
+        lookup_appid_by_host_port(asd, p, protocol, direction);
 
+    asd.check_app_detection_restart();
+
+    // Third party detection
 #ifdef ENABLE_APPID_THIRD_PARTY
-    if(asd->config->have_tp())
-        isTpAppidDiscoveryDone = do_discovery(*asd,protocol,p,direction);
+    if(asd.config->have_tp())
+        is_discovery_done = do_tp_discovery(asd,protocol,p,direction);
 #endif
 
-    if ( !asd->get_session_flags(APPID_SESSION_PORT_SERVICE_DONE) )
+    // Port-based service detection
+    if ( !asd.get_session_flags(APPID_SESSION_PORT_SERVICE_DONE) )
     {
         switch (protocol)
         {
         case IpProtocol::TCP:
-            if (asd->get_session_flags(APPID_SESSION_SYN_RST)) // TCP-specific exception
+            if (asd.get_session_flags(APPID_SESSION_SYN_RST)) // TCP-specific exception
                 break;
             // fallthrough
         case IpProtocol::UDP:
             // Both TCP and UDP need this test to be made
-            //  against only the p->src_port of the response.
+            // against only the p->src_port of the response.
             // For all other cases the port parameter is never checked.
             if (direction != APP_ID_FROM_RESPONDER)
                 break;
@@ -777,107 +831,106 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
         // All protocols other than TCP and UDP come straight here.
         default:
         {
-            asd->service.set_port_service_id(asd->config->get_port_service_id(protocol, p->ptrs.sp));
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s Port service %d\n",
-                    appidDebug->get_debug_session(), asd->service.get_port_service_id());
-            asd->set_session_flags(APPID_SESSION_PORT_SERVICE_DONE);
+            AppId id = asd.config->get_port_service_id(protocol, p->ptrs.sp);
+            if (id > APP_ID_NONE)
+            {
+                asd.service.set_port_service_id(id);
+                if (appidDebug->is_active())
+                    LogMessage("AppIdDbg %s Port service %d from port\n",
+                        appidDebug->get_debug_session(), asd.service.get_port_service_id());
+            }
+            asd.set_session_flags(APPID_SESSION_PORT_SERVICE_DONE);
         }
         break;
         }
     }
 
-    /* Length-based detectors. */
-    /* Only check if:
-     *  - Port service didn't find anything (and we haven't yet either).
-     *  - We haven't hit the max packets allowed for detector sequence matches.
-     *  - Packet has data (we'll ignore 0-sized packets in sequencing). */
-    if ( (asd->service.get_port_service_id() <= APP_ID_NONE)
-        && (asd->length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX)
-        && (p->dsize > 0))
-    {
-        uint8_t index = asd->length_sequence.sequence_cnt;
-        asd->length_sequence.proto = protocol;
-        asd->length_sequence.sequence_cnt++;
-        asd->length_sequence.sequence[index].direction = direction;
-        asd->length_sequence.sequence[index].length    = p->dsize;
-        AppId id = find_length_app_cache(&asd->length_sequence);
+    // Length-based service detection
+    if ( (p->dsize > 0) and (asd.service.get_port_service_id() <= APP_ID_NONE)
+        and (asd.length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX) )
+    {
+        uint8_t index = asd.length_sequence.sequence_cnt;
+        asd.length_sequence.proto = protocol;
+        asd.length_sequence.sequence_cnt++;
+        asd.length_sequence.sequence[index].direction = direction;
+        asd.length_sequence.sequence[index].length    = p->dsize;
+        AppId id = find_length_app_cache(&asd.length_sequence);
         if (id > APP_ID_NONE)
         {
-            asd->service.set_port_service_id(id);
-            asd->set_session_flags(APPID_SESSION_PORT_SERVICE_DONE);
+            asd.service.set_port_service_id(id);
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s Port service %d from length\n",
+                    appidDebug->get_debug_session(), asd.service.get_port_service_id());
+            asd.set_session_flags(APPID_SESSION_PORT_SERVICE_DONE);
         }
     }
 
-    /* exceptions for rexec and any other service detector that needs to see SYN and SYN/ACK */
-    if (asd->get_session_flags(APPID_SESSION_REXEC_STDERR))
+    // exceptions for rexec and any other service detector that need to see SYN and SYN/ACK
+    if (asd.get_session_flags(APPID_SESSION_REXEC_STDERR))
     {
-        ServiceDiscovery::get_instance().identify_service(*asd, p, direction);
-        AppIdDnsSession* dsession = asd->get_dns_session();
+        ServiceDiscovery::get_instance().identify_service(asd, p, direction);
+        AppIdDnsSession* dsession = asd.get_dns_session();
 
-        if (asd->service.get_id() == APP_ID_DNS &&
-            asd->config->mod_config->dns_host_reporting && dsession->get_host() )
+        if (asd.service.get_id() == APP_ID_DNS &&
+            asd.config->mod_config->dns_host_reporting && dsession->get_host() )
         {
             AppId client_id = APP_ID_NONE, payload_id = APP_ID_NONE;
             dns_host_scan_hostname((const uint8_t*)dsession->get_host(), dsession->get_host_len(),
                 &client_id, &payload_id);
-            asd->set_client_appid_data(client_id, nullptr);
+            asd.set_client_appid_data(client_id, nullptr);
         }
-        else if (asd->service.get_id() == APP_ID_RTMP)
-            asd->examine_rtmp_metadata();
-        else if (asd->get_session_flags(APPID_SESSION_SSL_SESSION) && asd->tsession)
-            asd->examine_ssl_metadata(p);
-    }
-    // FIXIT-M - snort 2.x has added a check for midstream pickup to this if, do we need that?
-    else if (protocol != IpProtocol::TCP || !p->dsize || (p->packet_flags & PKT_STREAM_ORDER_OK))
-    {
-        if (asd->service_disco_state != APPID_DISCO_STATE_FINISHED)
-            isTpAppidDiscoveryDone =
-                ServiceDiscovery::get_instance().do_service_discovery(*asd, p, direction);
-        if (asd->client_disco_state != APPID_DISCO_STATE_FINISHED)
-            isTpAppidDiscoveryDone =
-                ClientDiscovery::get_instance().do_client_discovery(*asd, p, direction);
-        asd->set_session_flags(APPID_SESSION_ADDITIONAL_PACKET);
+        else if (asd.service.get_id() == APP_ID_RTMP)
+            asd.examine_rtmp_metadata();
+        else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) && asd.tsession)
+            asd.examine_ssl_metadata(p);
     }
-    else
+    // FIXIT-M - snort 2.x has added a check for midstream pickup to this, do we need that?
+    else if (protocol != IpProtocol::TCP || (p->packet_flags & PKT_STREAM_ORDER_OK))
     {
-        if (appidDebug->is_active() && p->dsize &&
-            !asd->get_session_flags(APPID_SESSION_OOO_LOGGED))
-        {
-            asd->set_session_flags(APPID_SESSION_OOO_LOGGED);
-            LogMessage("AppIdDbg %s Packet out-of-order\n", appidDebug->get_debug_session());
-        }
+        if (asd.service_disco_state != APPID_DISCO_STATE_FINISHED)
+            is_discovery_done =
+                ServiceDiscovery::get_instance().do_service_discovery(asd, p, direction);
+        if (asd.client_disco_state != APPID_DISCO_STATE_FINISHED)
+            is_discovery_done =
+                ClientDiscovery::get_instance().do_client_discovery(asd, p, direction);
+        asd.set_session_flags(APPID_SESSION_ADDITIONAL_PACKET);
     }
 
-    AppId service_id = asd->pick_service_app_id();
-    AppId payload_id = asd->pick_payload_app_id();
+    return is_discovery_done;
+}
+
+void AppIdDiscovery::do_post_discovery(Packet* p, AppIdSession& asd,
+    AppidSessionDirection direction, bool is_discovery_done)
+{
+    AppId service_id = asd.pick_service_app_id();
+    AppId payload_id = asd.pick_payload_app_id();
 
     if (service_id > APP_ID_NONE)
     {
-        if (asd->get_session_flags(APPID_SESSION_DECRYPTED))
+        if (asd.get_session_flags(APPID_SESSION_DECRYPTED))
         {
-            if (asd->misc_app_id == APP_ID_NONE)
-                asd->update_encrypted_app_id(service_id);
+            if (asd.misc_app_id == APP_ID_NONE)
+                asd.update_encrypted_app_id(service_id);
         }
 // FIXIT-M Need to determine what api to use for this _dpd function
 #if 1
-        UNUSED(isTpAppidDiscoveryDone);
+        UNUSED(is_discovery_done);
 #else
-        else if (isTpAppidDiscoveryDone && isSslServiceAppId(service_id) &&
+        else if (is_discovery_done && isSslServiceAppId(service_id) &&
             _dpd.isSSLPolicyEnabled(nullptr))
-            asd->set_session_flags(APPID_SESSION_CONTINUE);
+            asd.set_session_flags(APPID_SESSION_CONTINUE);
 #endif
     }
 
-    asd->set_application_ids(service_id, asd->pick_client_app_id(), payload_id,
-        asd->pick_misc_app_id());
+    asd.set_application_ids(service_id, asd.pick_client_app_id(), payload_id,
+        asd.pick_misc_app_id());
 
-    /* Set the field that the Firewall queries to see if we have a search engine. */
-    if (asd->search_support_type == UNKNOWN_SEARCH_ENGINE && payload_id > APP_ID_NONE)
+    // Set the field that the Firewall queries to see if we have a search engine
+    if (asd.search_support_type == UNKNOWN_SEARCH_ENGINE && payload_id > APP_ID_NONE)
     {
         uint flags = AppInfoManager::get_instance().get_app_info_flags(payload_id,
             APPINFO_FLAG_SEARCH_ENGINE | APPINFO_FLAG_SUPPORTED_SEARCH);
-        asd->search_support_type =
+        asd.search_support_type =
             (flags & APPINFO_FLAG_SEARCH_ENGINE) ?
             ((flags & APPINFO_FLAG_SUPPORTED_SEARCH) ? SUPPORTED_SEARCH_ENGINE :
             UNSUPPORTED_SEARCH_ENGINE )
@@ -885,7 +938,7 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
         if (appidDebug->is_active())
         {
             const char* typeString;
-            switch ( asd->search_support_type )
+            switch ( asd.search_support_type )
             {
             case NOT_A_SEARCH_ENGINE: typeString = "NOT_A_SEARCH_ENGINE"; break;
             case SUPPORTED_SEARCH_ENGINE: typeString = "SUPPORTED_SEARCH_ENGINE"; break;
@@ -900,16 +953,16 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
 
     if ( service_id !=  APP_ID_NONE )
     {
-        if ( payload_id != APP_ID_NONE && payload_id != asd->past_indicator)
+        if ( payload_id != APP_ID_NONE && payload_id != asd.past_indicator)
         {
-            asd->past_indicator = payload_id;
+            asd.past_indicator = payload_id;
             check_session_for_AF_indicator(p, direction, (AppId)payload_id);
         }
 
-        if (asd->payload.get_id() == APP_ID_NONE && asd->past_forecast != service_id &&
-            asd->past_forecast != APP_ID_UNKNOWN)
+        if (asd.payload.get_id() == APP_ID_NONE && asd.past_forecast != service_id &&
+            asd.past_forecast != APP_ID_UNKNOWN)
         {
-            asd->past_forecast = check_session_for_AF_forecast(*asd, p, direction,
+            asd.past_forecast = check_session_for_AF_forecast(asd, p, direction,
                 (AppId)service_id);
         }
     }
index c93c45f677e2893e49e889a529505e0a66309b67..b986a82a237a532400dacf11414766013617964c 100644 (file)
@@ -26,6 +26,7 @@
 #include <string>
 #include <vector>
 
+#include "appid_types.h"
 #include "application_ids.h"
 
 #include "protocols/protocol_ids.h"
@@ -130,6 +131,17 @@ protected:
     snort::SearchTool* udp_patterns = nullptr;
     int udp_pattern_count = 0;
     std::vector<AppIdPatternMatchNode*> pattern_data;
+
+private:
+    static bool do_pre_discovery(snort::Packet* p, AppIdSession** p_asd, AppIdInspector& inspector,
+        IpProtocol& protocol, AppidSessionDirection& direction);
+    static bool do_discovery(snort::Packet* p, AppIdSession& asd, IpProtocol protocol,
+        AppidSessionDirection direction);
+    static void do_post_discovery(snort::Packet* p, AppIdSession& asd,
+        AppidSessionDirection direction, bool is_discovery_done);
+    static bool handle_unmonitored_session(AppIdSession* asd, const snort::Packet* p,
+        IpProtocol protocol, AppidSessionDirection dir, AppIdInspector& inspector,
+        uint64_t& flow_flags);
 };
 #endif
 
index 70de5621d93ca24c2f8ddb506b4b4ea8c48c5e49..3b2fe0b818f0ee4fb09fff9519e153d8f78601a1 100644 (file)
@@ -53,7 +53,7 @@ using namespace snort;
 THREAD_LOCAL ProfileStats tpLibPerfStats;
 THREAD_LOCAL ProfileStats tpPerfStats;
 
-bool do_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&);
+bool do_tp_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&);
 
 // std::vector does not have a convenient find() function.
 // There is a generic std::find() in <algorithm>, but this might be faster.
@@ -578,7 +578,7 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo
     }
 }
 
-bool do_discovery(AppIdSession& asd, IpProtocol protocol,
+bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol,
     Packet* p, AppidSessionDirection& direction)
 {
     vector<AppId> tp_proto_list;
@@ -692,13 +692,6 @@ bool do_discovery(AppIdSession& asd, IpProtocol protocol,
             else
             {
                 asd.tp_app_id = APP_ID_NONE;
-                if (appidDebug->is_active() && !asd.get_session_flags(
-                    APPID_SESSION_TPI_OOO_LOGGED))
-                {
-                    asd.set_session_flags(APPID_SESSION_TPI_OOO_LOGGED);
-                    LogMessage("AppIdDbg %s 3rd party packet out-of-order\n",
-                        appidDebug->get_debug_session());
-                }
             }
 
             if (asd.tpsession and asd.tpsession->get_state() == TP_STATE_MONITORING)