]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2133 in SNORT/snort3 from ~CLJUDGE/snort3:mark_service_unknown_if...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 20 Apr 2020 01:28:21 +0000 (01:28 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Mon, 20 Apr 2020 01:28:21 +0000 (01:28 +0000)
Squashed commit of the following:

commit d28c407da03e2a6e9ad3d6becddae6cbf3140d00
Author: Cliff Judge <cljudge@cisco.com>
Date:   Tue Apr 14 22:58:44 2020 -0400

    appid: setting up packet counters to make sure flows with one-way data don't pend forever

src/network_inspectors/appid/app_info_table.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/service_plugins/service_discovery.cc

index 75b21b54f12c87a52a8be5fd006c1f7e0eb2d3cf..d07c95d171e655e0553953cf4df17f95e8da9a78 100644 (file)
@@ -58,17 +58,17 @@ AppInfoTableEntry::AppInfoTableEntry(AppId id, char* name)
     app_name_key = AppInfoManager::strdup_to_lower(name);
 }
 
-AppInfoTableEntry::AppInfoTableEntry(AppId id, char* name, AppId sid, AppId cid, AppId pid)
-    appId(id), serviceId(sid), clientId(cid), payloadId(pid), app_name(name)
+AppInfoTableEntry::AppInfoTableEntry(AppId id, char* name, AppId sid, AppId cid, AppId pid) :
+    appId(id), serviceId(sid), clientId(cid), payloadId(pid), app_name(name)
 {
     app_name_key = AppInfoManager::strdup_to_lower(name);
 }
 
 AppInfoTableEntry::~AppInfoTableEntry()
 {
-    if ( app_name )
+    if (app_name)
         snort_free(app_name);
-    if ( app_name_key )
+    if (app_name_key)
         snort_free(app_name_key);
 }
 
@@ -87,27 +87,26 @@ AppInfoTableEntry* AppInfoManager::find_app_info_by_name(const char* app_name)
     const char* search_name = AppInfoManager::strdup_to_lower(app_name);
 
     app = app_info_name_table.find(search_name);
-    if ( app != app_info_name_table.end() )
+    if (app != app_info_name_table.end())
         entry = app->second;
 
     snort_free((void*)search_name);
     return entry;
 }
 
-bool AppInfoManager::add_entry_to_app_info_name_table(const char* app_name, AppInfoTableEntry* entry)
+bool AppInfoManager::add_entry_to_app_info_name_table(const char* app_name,
+    AppInfoTableEntry* entry)
 {
     bool added = true;
 
-    if ( !is_existing_entry(entry) )
+    if (!is_existing_entry(entry))
         app_info_name_table[app_name] = entry;
     else
     {
-        WarningMessage(
-            "App name, \"%s\"is a duplicate entry will be shared by each detector.\n",
+        WarningMessage("App name, \"%s\" is a duplicate entry will be shared by each detector.\n",
             app_name);
         added = false;
     }
-
     return added;
 }
 
@@ -115,8 +114,8 @@ AppId AppInfoManager::get_static_app_info_entry(AppId appid)
 {
     if (appid > 0 && appid < SF_APPID_BUILDIN_MAX)
         return appid;
-    if ( ( appid >= SF_APPID_CSD_MIN ) &&
-        appid < ( SF_APPID_CSD_MIN + ( SF_APPID_MAX - SF_APPID_BUILDIN_MAX ) ) )
+    if ((appid >= SF_APPID_CSD_MIN) &&
+        appid < (SF_APPID_CSD_MIN + (SF_APPID_MAX - SF_APPID_BUILDIN_MAX)))
         return (SF_APPID_BUILDIN_MAX + appid - SF_APPID_CSD_MIN);
     return 0;
 }
@@ -131,7 +130,6 @@ char* AppInfoManager::strdup_to_lower(const char* source)
         *lcd = tolower(*lcd);
         lcd++;
     }
-
     return dest;
 }
 
@@ -140,8 +138,8 @@ bool AppInfoManager::configured()
     return !app_info_table.empty();
 }
 
-AppInfoTableEntry* AppInfoManager::get_app_info_entry(AppId appId, const
-    AppInfoTable& lookup_table)
+AppInfoTableEntry* AppInfoManager::get_app_info_entry(AppId appId,
+    const AppInfoTable& lookup_table)
 {
     AppId tmp;
     AppInfoTable::const_iterator app;
@@ -150,16 +148,15 @@ AppInfoTableEntry* AppInfoManager::get_app_info_entry(AppId appId, const
     if ((tmp = get_static_app_info_entry(appId)))
     {
         app = lookup_table.find(tmp);
-        if ( app != lookup_table.end() )
+        if (app != lookup_table.end())
             entry = app->second;
     }
     else
     {
         app = custom_app_info_table.find(appId);
-        if ( app != custom_app_info_table.end() )
+        if (app != custom_app_info_table.end())
             entry = app->second;
     }
-
     return entry;
 }
 
@@ -182,13 +179,12 @@ AppInfoTableEntry* AppInfoManager::add_dynamic_app_entry(const char* app_name)
         entry = new AppInfoTableEntry(next_custom_appid++, snort_strdup(app_name));
         custom_app_info_table[entry->appId] = entry;
 
-        if ( !add_entry_to_app_info_name_table(entry->app_name_key, entry) )
+        if (!add_entry_to_app_info_name_table(entry->app_name_key, entry))
         {
             delete entry;
             return nullptr;
         }
     }
-
     return entry;
 }
 
@@ -325,16 +321,22 @@ void AppInfoManager::load_odp_config(OdpContext& odp_ctxt, const char* path)
             else if (!(strcasecmp(conf_key, "host_port_app_cache_lookup_interval")))
             {
                 int host_port_app_cache_lookup_interval = atoi(conf_val);
-                if (host_port_app_cache_lookup_interval < MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL
-                    || host_port_app_cache_lookup_interval > MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL )
+                if (host_port_app_cache_lookup_interval <
+                    MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL ||
+                    host_port_app_cache_lookup_interval >
+                    MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL)
                 {
-                     ParseWarning(WARN_CONF,
-                        "AppId: invalid host_port_app_cache_lookup_interval %d, must be between %d and %d\n.",
-                        host_port_app_cache_lookup_interval, MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL , MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL);
+                    ParseWarning(WARN_CONF,
+                        "AppId: invalid host_port_app_cache_lookup_interval %d, "
+                        "must be between %d and %d\n.",
+                        host_port_app_cache_lookup_interval,
+                        MIN_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL,
+                        MAX_HOST_PORT_APP_CACHE_LOOKUP_INTERVAL);
                 }
                 else
                 {
-                     odp_ctxt.host_port_app_cache_lookup_interval = host_port_app_cache_lookup_interval;
+                    odp_ctxt.host_port_app_cache_lookup_interval =
+                        host_port_app_cache_lookup_interval;
                 }
             }
             else if (!(strcasecmp(conf_key, "host_port_app_cache_lookup_range")))
@@ -344,12 +346,14 @@ void AppInfoManager::load_odp_config(OdpContext& odp_ctxt, const char* path)
                     || host_port_app_cache_lookup_range > MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE)
                 {
                      ParseWarning(WARN_CONF,
-                        "AppId: invalid host_port_app_cache_lookup_range %d, must be between %d and %d\n.",
-                        host_port_app_cache_lookup_range , MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE, MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE);
+                        "AppId: invalid host_port_app_cache_lookup_range %d, "
+                        "must be between %d and %d\n.", host_port_app_cache_lookup_range,
+                        MIN_HOST_PORT_APP_CACHE_LOOKUP_RANGE,
+                        MAX_HOST_PORT_APP_CACHE_LOOKUP_RANGE);
                 }
                 else
                 {
-                     odp_ctxt.host_port_app_cache_lookup_range = host_port_app_cache_lookup_range;
+                    odp_ctxt.host_port_app_cache_lookup_range = host_port_app_cache_lookup_range;
                 }
             }
             else if (!(strcasecmp(conf_key, "is_host_port_app_cache_runtime")))
@@ -398,7 +402,8 @@ void AppInfoManager::load_odp_config(OdpContext& odp_ctxt, const char* path)
                     set_app_info_flags(APP_ID_BITTORRENT, APPINFO_FLAG_DEFER);
                     set_app_info_flags(APP_ID_BITTORRENT, APPINFO_FLAG_DEFER_PAYLOAD);
                     odp_ctxt.max_tp_flow_depth = 25;
-                    LogMessage("AppId: host_port_app_cache_lookup_interval %d\n", odp_ctxt.host_port_app_cache_lookup_interval);
+                    LogMessage("AppId: host_port_app_cache_lookup_interval %d\n",
+                        odp_ctxt.host_port_app_cache_lookup_interval);
                     LogMessage("AppId: recheck_for_portservice_appid enabled\n");
                     LogMessage("AppId: defer_to_thirdparty %d\n", APP_ID_BITTORRENT);
                     LogMessage("AppId: defer_payload_to_thirdparty %d\n", APP_ID_BITTORRENT);
@@ -503,6 +508,51 @@ void AppInfoManager::load_odp_config(OdpContext& odp_ctxt, const char* path)
                     continue;
                 }
             }
+            else if (!(strcasecmp(conf_key, "max_bytes_before_service_fail")))
+            {
+                uint64_t max_bytes_before_service_fail = atoi(conf_val);
+                if (max_bytes_before_service_fail < MIN_MAX_BYTES_BEFORE_SERVICE_FAIL)
+                {
+                    ParseWarning(WARN_CONF, "AppId: invalid max_bytes_before_service_fail "
+                        "%" PRIu64 " must be greater than %u.\n", max_bytes_before_service_fail,
+                        MIN_MAX_BYTES_BEFORE_SERVICE_FAIL);
+                }
+                else
+                {
+                    odp_ctxt.max_bytes_before_service_fail = max_bytes_before_service_fail;
+                }
+            }
+            else if (!(strcasecmp(conf_key, "max_packet_before_service_fail")))
+            {
+                uint16_t max_packet_before_service_fail = atoi(conf_val);
+                if (max_packet_before_service_fail < MIN_MAX_PKTS_BEFORE_SERVICE_FAIL)
+                {
+                    ParseWarning(WARN_CONF, "AppId: invalid max_packet_before_service_fail "
+                        "%" PRIu16 ", must be greater than %u.\n", max_packet_before_service_fail,
+                        MIN_MAX_PKTS_BEFORE_SERVICE_FAIL);
+                }
+                else
+                {
+                    odp_ctxt.max_packet_before_service_fail = max_packet_before_service_fail;
+                }
+            }
+            else if (!(strcasecmp(conf_key, "max_packet_service_fail_ignore_bytes")))
+            {
+                uint16_t max_packet_service_fail_ignore_bytes = atoi(conf_val);
+                if (max_packet_service_fail_ignore_bytes <
+                    MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES)
+                {
+                    ParseWarning(WARN_CONF, "AppId: invalid max_packet_service_fail_ignore_bytes"
+                        "%" PRIu16 ", must be greater than %u.\n",
+                        max_packet_service_fail_ignore_bytes,
+                        MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES);
+                }
+                else
+                {
+                    odp_ctxt.max_packet_service_fail_ignore_bytes =
+                        max_packet_service_fail_ignore_bytes;
+                }
+            }
             /* App Priority bit set*/
             else if (!(strcasecmp(conf_key, "app_priority")))
             {
@@ -602,7 +652,7 @@ SnortProtocolId AppInfoManager::add_appid_protocol_reference(const char* protoco
 void AppInfoManager::init_appid_info_table(AppIdConfig& config,
     SnortConfig* sc, OdpContext& odp_ctxt)
 {
-    if ( !config.app_detector_dir )
+    if (!config.app_detector_dir)
     {
         return;  // no lua detectors, no rule support, already warned
     }
@@ -613,7 +663,7 @@ void AppInfoManager::init_appid_info_table(AppIdConfig& config,
 
     FILE* tableFile = fopen(filepath, "r");
 
-    if ( !tableFile )
+    if (!tableFile)
     {
         ParseError("appid: could not open %s", filepath);
     }
@@ -694,7 +744,7 @@ void AppInfoManager::init_appid_info_table(AppIdConfig& config,
             if ((app_id = get_static_app_info_entry(entry->payloadId)))
                 app_info_payload_table[app_id] = entry;
 
-            if ( !add_entry_to_app_info_name_table(entry->app_name_key, entry) )
+            if (!add_entry_to_app_info_name_table(entry->app_name_key, entry))
                 delete entry;
         }
         fclose(tableFile);
index 7bce597b058be0b5f9b72a29c0190840f11a1d56..7f39f9a4f9fb2c21ac6cf18b0c8c9003a2cc98ea 100644 (file)
 
 #define APP_ID_PORT_ARRAY_SIZE  65536
 
+#define MIN_MAX_BYTES_BEFORE_SERVICE_FAIL 4096
+#define MIN_MAX_PKTS_BEFORE_SERVICE_FAIL 5
+#define MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES 15
+
+extern SnortProtocolId snortId_for_unsynchronized;
+extern SnortProtocolId snortId_for_ftp_data;
+extern SnortProtocolId snortId_for_http2;
 
 class PatternClientDetector;
 class PatternServiceDetector;
@@ -96,6 +103,9 @@ public:
     bool http_response_version_enabled = false;
     bool allow_port_wildcard_host_cache = false;
     bool recheck_for_portservice_appid = false;
+    uint64_t max_bytes_before_service_fail = MIN_MAX_BYTES_BEFORE_SERVICE_FAIL;
+    uint16_t max_packet_before_service_fail = MIN_MAX_PKTS_BEFORE_SERVICE_FAIL;
+    uint16_t max_packet_service_fail_ignore_bytes = MIN_MAX_PKT_BEFORE_SERVICE_FAIL_IGNORE_BYTES;
 
     OdpContext(AppIdConfig&, snort::SnortConfig*);
     void initialize();
@@ -120,7 +130,8 @@ public:
         return host_port_cache.find(ip, port, proto, *this);
     }
 
-    bool host_port_cache_add(const snort::SfIp* ip, uint16_t port, IpProtocol proto, unsigned type, AppId appid)
+    bool host_port_cache_add(const snort::SfIp* ip, uint16_t port, IpProtocol proto, unsigned type,
+        AppId appid)
     {
         return host_port_cache.add(ip, port, proto, type, appid);
     }
index e9fe0f34ada03a5d0eede6e2ac52e2f86bc6178b..36378e902d1378461e3032887ac3cf049feec2c7 100644 (file)
@@ -57,7 +57,7 @@ AppIdDiscovery::AppIdDiscovery()
 
 AppIdDiscovery::~AppIdDiscovery()
 {
-    for (auto pd : pattern_data )
+    for (auto pd : pattern_data)
         delete pd;
 
     pattern_data.clear();
@@ -65,10 +65,10 @@ AppIdDiscovery::~AppIdDiscovery()
     delete tcp_patterns;
     delete udp_patterns;
 
-    for ( auto kv : tcp_detectors )
+    for (auto kv : tcp_detectors)
         delete kv.second;
 
-    for ( auto kv : udp_detectors )
+    for (auto kv : udp_detectors)
         delete kv.second;
 }
 
@@ -76,13 +76,13 @@ void AppIdDiscovery::tterm()
 {
 }
 
-void AppIdDiscovery::register_detector(const std::string& name, AppIdDetector* cd,  IpProtocol proto)
+void AppIdDiscovery::register_detector(const std::string& name, AppIdDetector* cd, IpProtocol proto)
 {
     // FIXIT-L - check for dup name?
-    if ( proto == IpProtocol::TCP )
-        tcp_detectors[ name ] = cd;
-    else if ( proto == IpProtocol::UDP )
-        udp_detectors[ name ] = cd;
+    if (proto == IpProtocol::TCP)
+        tcp_detectors[name] = cd;
+    else if (proto == IpProtocol::UDP)
+        udp_detectors[name] = cd;
     else
         ErrorMessage("Detector %s has unsupported protocol %u", name.c_str(), (unsigned)proto);
 }
@@ -122,7 +122,7 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
     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, outer_protocol, direction) )
+    if (!do_pre_discovery(p, &asd, inspector, protocol, outer_protocol, direction))
         return;
 
     AppId service_id = APP_ID_NONE;
@@ -179,7 +179,7 @@ static inline unsigned get_ipfuncs_flags(const Packet* p, bool dst)
 
 static inline bool is_special_session_monitored(const Packet* p)
 {
-    if ( p->is_ip4() )
+    if (p->is_ip4())
     {
         if (p->is_udp() && ((p->ptrs.sp == 68 && p->ptrs.dp == 67)
             || (p->ptrs.sp == 67 &&  p->ptrs.dp == 68)))
@@ -247,7 +247,7 @@ static bool set_network_attributes(AppIdSession* asd, Packet* p, IpProtocol& pro
 
 static bool is_packet_ignored(Packet* p)
 {
-    if ( p->is_rebuilt() and !p->flow->is_proxied())
+    if (p->is_rebuilt() and !p->flow->is_proxied())
     {
         appid_stats.ignored_packets++;
         return true;
@@ -256,7 +256,8 @@ static bool is_packet_ignored(Packet* p)
     return false;
 }
 
-static uint64_t is_session_monitored(const AppIdSession& asd, const Packet* p, AppidSessionDirection dir)
+static uint64_t is_session_monitored(const AppIdSession& asd, const Packet* p,
+    AppidSessionDirection dir)
 {
     uint64_t flags;
     uint64_t flow_flags = APPID_SESSION_DISCOVER_APP;
@@ -455,26 +456,26 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp
 {
     AppIdSession* asd = *p_asd;
 
-    if ( !set_network_attributes(asd, p, protocol, outer_protocol, direction) )
+    if (!set_network_attributes(asd, p, protocol, outer_protocol, direction))
     {
         appid_stats.ignored_packets++;
         return false;
     }
 
-    if ( appidDebug->is_enabled() )
+    if (appidDebug->is_enabled())
         appidDebug->activate(p->flow, asd,
             inspector.get_ctxt().config.log_all_sessions);
 
-    if ( is_packet_ignored(p) )
+    if (is_packet_ignored(p))
         return false;
 
     uint64_t flow_flags;
-    if ( handle_unmonitored_session(asd, p, protocol, direction, inspector, 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 )
+    if (!asd || asd->common.flow_type == APPID_FLOW_TYPE_TMP)
     {
         *p_asd = asd = AppIdSession::allocate_session(p, protocol, direction, &inspector);
         if (p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
@@ -494,9 +495,23 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp
     asd->session_packet_count++;
 
     if (direction == APP_ID_FROM_INITIATOR)
+    {
         asd->stats.initiator_bytes += p->pkth->pktlen;
+        if (p->dsize)
+        {
+            asd->init_pkts_without_reply++;
+            asd->init_bytes_without_reply += p->dsize;
+        }
+    }
     else
+    {
         asd->stats.responder_bytes += p->pkth->pktlen;
+        if (p->dsize)
+        {
+            asd->init_pkts_without_reply = 0;
+            asd->init_bytes_without_reply = 0;
+        }
+    }
 
     asd->common.flags = flow_flags;
     if (!asd->get_session_flags(APPID_SESSION_PAYLOAD_SEEN) and p->dsize)
@@ -512,15 +527,16 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp
             publish_appid_event(change_bits, p->flow);
             asd->set_session_flags(APPID_SESSION_IGNORE_FLOW_IDED);
         }
-
         if (appidDebug->is_active() &&
             !asd->get_session_flags(APPID_SESSION_IGNORE_FLOW_LOGGED))
         {
             asd->set_session_flags(APPID_SESSION_IGNORE_FLOW_LOGGED);
 
-            const char *app_name = asd->ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd->service.get_id());
+            const char *app_name =
+                asd->ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd->service.get_id());
             LogMessage("AppIdDbg %s Ignoring connection with service %s (%d)\n",
-                appidDebug->get_debug_session(), app_name ? app_name : "unknown", asd->service.get_id());
+                appidDebug->get_debug_session(), app_name ? app_name : "unknown",
+                asd->service.get_id());
         }
 
         return false;
@@ -555,7 +571,7 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp
         else
         {
             const auto* tcph = p->ptrs.tcph;
-            if ( tcph->is_rst() && asd->previous_tcp_flags == TH_SYN )
+            if (tcph->is_rst() && asd->previous_tcp_flags == TH_SYN)
             {
                 uint16_t port = 0;
                 const SfIp* ip = nullptr;
@@ -571,10 +587,8 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp
                     ip = p->ptrs.ip_api.get_src();
                     port = p->ptrs.sp;
                 }
-
                 AppIdServiceState::check_reset(*asd, ip, port);
             }
-
             asd->previous_tcp_flags = p->ptrs.tcph->th_flags;
         }
     }
@@ -622,8 +636,8 @@ void AppIdDiscovery::do_port_based_discovery(Packet* p, AppIdSession& asd, IpPro
         asd.service.set_port_service_id(id);
         if (appidDebug->is_active())
         {
-            const char *app_name =
-                asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd.service.get_port_service_id());
+            AppId ps_id = asd.service.get_port_service_id();
+            const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(ps_id);
             LogMessage("AppIdDbg %s Port service %s (%d) from port\n",
                 appidDebug->get_debug_session(), app_name ? app_name : "unknown",
                 asd.service.get_port_service_id());
@@ -644,9 +658,11 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
     if (!(asd.scan_flags & SCAN_HOST_PORT_FLAG))
         check_static = true;
 
-    if ((asd.session_packet_count % asd.ctxt.get_odp_ctxt().host_port_app_cache_lookup_interval == 0) and
-        (asd.session_packet_count <= asd.ctxt.get_odp_ctxt().host_port_app_cache_lookup_range) and
-        asd.ctxt.get_odp_ctxt().is_host_port_app_cache_runtime )
+    if ((asd.session_packet_count %
+            asd.ctxt.get_odp_ctxt().host_port_app_cache_lookup_interval == 0) and
+        (asd.session_packet_count <=
+            asd.ctxt.get_odp_ctxt().host_port_app_cache_lookup_range) and
+        asd.ctxt.get_odp_ctxt().is_host_port_app_cache_runtime)
         check_dynamic = true;
 
     if (!(check_static || check_dynamic))
@@ -657,7 +673,7 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
     AppIdHttpSession* hsession = asd.get_http_session();
 
     const TunnelDest* tun_dest = hsession->get_tun_dest();
-    if(tun_dest)
+    if (tun_dest)
     {
         ip = &(tun_dest->ip);
         port = tun_dest->port;
@@ -714,7 +730,8 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
         auto ht = host_cache.find(*ip);
         if (ht)
         {
-          AppId appid = ht->get_appid(port, protocol, true, asd.ctxt.get_odp_ctxt().allow_port_wildcard_host_cache);
+            AppId appid = ht->get_appid(port, protocol, true,
+                asd.ctxt.get_odp_ctxt().allow_port_wildcard_host_cache);
             if (appid > APP_ID_NONE)
             {
                 // FIXIT-L: Make this more generic to support service and payload IDs
@@ -723,20 +740,23 @@ bool AppIdDiscovery::do_host_port_based_discovery(Packet* p, AppIdSession& asd,
                 asd.set_session_flags(APPID_SESSION_HOST_CACHE_MATCHED);
             }
         }
-
         return true;
     }
-
     return false;
 }
 
-static inline bool is_check_host_cache_valid(AppIdSession& asd, AppId service_id, AppId client_id, AppId payload_id, AppId misc_id)
+static inline bool is_check_host_cache_valid(AppIdSession& asd, AppId service_id, AppId client_id,
+    AppId payload_id, AppId misc_id)
 {
-    bool is_payload_client_misc_none = (payload_id <= APP_ID_NONE and client_id <= APP_ID_NONE and misc_id <= APP_ID_NONE);
-    bool is_appid_none = is_payload_client_misc_none and (service_id <= APP_ID_NONE or service_id == APP_ID_UNKNOWN_UI or
-        (asd.ctxt.get_odp_ctxt().recheck_for_portservice_appid and service_id == asd.service.get_port_service_id()));
-    bool is_ssl_none = asd.ctxt.get_odp_ctxt().check_host_cache_unknown_ssl and asd.get_session_flags(APPID_SESSION_SSL_SESSION) and
-                          (not(asd.tsession and asd.tsession->get_tls_host() and asd.tsession->get_tls_cname()));
+    bool is_payload_client_misc_none = (payload_id <= APP_ID_NONE and client_id <= APP_ID_NONE and
+        misc_id <= APP_ID_NONE);
+    bool is_appid_none = is_payload_client_misc_none and (service_id <= APP_ID_NONE or
+        service_id == APP_ID_UNKNOWN_UI or
+        (asd.ctxt.get_odp_ctxt().recheck_for_portservice_appid and
+        service_id == asd.service.get_port_service_id()));
+    bool is_ssl_none = asd.ctxt.get_odp_ctxt().check_host_cache_unknown_ssl and
+        asd.get_session_flags(APPID_SESSION_SSL_SESSION) and
+        (not(asd.tsession and asd.tsession->get_tls_host() and asd.tsession->get_tls_cname()));
     if (is_appid_none or is_ssl_none or asd.ctxt.get_odp_ctxt().check_host_port_app_cache)
         return true;
     return false;
@@ -759,10 +779,11 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
             asd.misc_app_id = misc_id = id;
             if (appidDebug->is_active())
             {
-                const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().
-                    get_app_name(asd.misc_app_id);
+                const char *app_name =
+                    asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd.misc_app_id);
                 LogMessage("AppIdDbg %s Outer protocol service %s (%d)\n",
-                    appidDebug->get_debug_session(), app_name ? app_name : "unknown", asd.misc_app_id);
+                    appidDebug->get_debug_session(), app_name ? app_name : "unknown",
+                    asd.misc_app_id);
             }
         }
     }
@@ -779,17 +800,19 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
                 asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
                 if (appidDebug->is_active())
                 {
-                    const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(asd.service.get_port_service_id());
+                    AppId ps_id = asd.service.get_port_service_id();
+                    const char *app_name =
+                        asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(ps_id);
                     LogMessage("AppIdDbg %s Protocol service %s (%d) from protocol\n",
-                        appidDebug->get_debug_session(), app_name ? app_name : "unknown", asd.service.get_port_service_id());
+                        appidDebug->get_debug_session(), app_name ? app_name : "unknown", ps_id);
                 }
             }
             asd.set_session_flags(APPID_SESSION_PORT_SERVICE_DONE);
         }
         else
         {
-             service_id = asd.pick_service_app_id();
-             misc_id = asd.pick_misc_app_id();
+            service_id = asd.pick_service_app_id();
+            misc_id = asd.pick_misc_app_id();
         }
         return true;
     }
@@ -818,7 +841,8 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
     // 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))
     {
-        asd.ctxt.get_odp_ctxt().get_service_disco_mgr().identify_service(asd, p, direction, change_bits);
+        asd.ctxt.get_odp_ctxt().get_service_disco_mgr().identify_service(asd, p, direction,
+            change_bits);
 
         if (asd.get_session_flags(APPID_SESSION_SERVICE_DETECTED |
             APPID_SESSION_CONTINUE) == APPID_SESSION_SERVICE_DETECTED)
@@ -832,20 +856,22 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
     else if (protocol != IpProtocol::TCP || (p->packet_flags & PKT_STREAM_ORDER_OK))
     {
         if (asd.service_disco_state != APPID_DISCO_STATE_FINISHED)
-            is_discovery_done = asd.ctxt.get_odp_ctxt().get_service_disco_mgr().do_service_discovery(
-                asd, p, direction, change_bits);
+            is_discovery_done =
+                asd.ctxt.get_odp_ctxt().get_service_disco_mgr().do_service_discovery(asd, p,
+                    direction, change_bits);
         if (asd.client_disco_state != APPID_DISCO_STATE_FINISHED)
-            is_discovery_done = asd.ctxt.get_odp_ctxt().get_client_disco_mgr().do_client_discovery(
-                asd, p, direction, change_bits);
+            is_discovery_done =
+                asd.ctxt.get_odp_ctxt().get_client_disco_mgr().do_client_discovery(asd, p,
+                    direction, change_bits);
         asd.set_session_flags(APPID_SESSION_ADDITIONAL_PACKET);
     }
 
     service_id = asd.pick_service_app_id();
 
     // Length-based service detection if no service is found yet
-    if ( (service_id <= APP_ID_NONE or service_id == APP_ID_UNKNOWN_UI) and (p->dsize > 0) and
+    if ((service_id <= APP_ID_NONE or service_id == APP_ID_UNKNOWN_UI) and (p->dsize > 0) and
          (asd.length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX) and
-         !asd.get_session_flags(APPID_SESSION_OOO) )
+         !asd.get_session_flags(APPID_SESSION_OOO))
     {
         uint8_t index = asd.length_sequence.sequence_cnt;
         asd.length_sequence.proto = protocol;
@@ -871,15 +897,18 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
     client_id = asd.pick_client_app_id();
     misc_id =  asd.pick_misc_app_id();
 
-    bool is_http_tunnel = ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) || (asd.payload.get_id() == APP_ID_HTTP_SSL_TUNNEL)) ? true:false;
-    if (is_check_host_cache_valid(asd, service_id, client_id, payload_id, misc_id) or (is_http_tunnel))
+    bool is_http_tunnel = ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) ||
+        (asd.payload.get_id() == APP_ID_HTTP_SSL_TUNNEL)) ? true:false;
+
+    if (is_check_host_cache_valid(asd, service_id, client_id, payload_id, misc_id) or
+        (is_http_tunnel))
     {
-        if(is_http_tunnel)
+        if (is_http_tunnel)
         {
             AppIdHttpSession* hsession = asd.get_http_session();
-            if(hsession and (asd.scan_flags & SCAN_HTTP_URI_FLAG))
+            if (hsession and (asd.scan_flags & SCAN_HTTP_URI_FLAG))
             {
-                if(hsession->get_tun_dest())
+                if (hsession->get_tun_dest())
                     hsession->free_tun_dest();
                 hsession->set_tun_dest();
                 asd.scan_flags &= ~SCAN_HTTP_URI_FLAG;
@@ -912,16 +941,16 @@ void AppIdDiscovery::do_post_discovery(Packet* p, AppIdSession& asd,
             asd.set_session_flags(APPID_SESSION_CONTINUE);
     }
 
-    if ( service_id !=  APP_ID_NONE )
+    if (service_id !=  APP_ID_NONE)
     {
-        if ( payload_id != asd.past_indicator and payload_id != APP_ID_NONE)
+        if (payload_id != asd.past_indicator and payload_id != APP_ID_NONE)
         {
             asd.past_indicator = payload_id;
             check_session_for_AF_indicator(p, direction, (AppId)payload_id);
         }
 
-        if ( asd.past_forecast != service_id and asd.past_forecast != APP_ID_UNKNOWN and
-             asd.payload.get_id() == APP_ID_NONE )
+        if (asd.past_forecast != service_id and asd.past_forecast != APP_ID_UNKNOWN and
+             asd.payload.get_id() == APP_ID_NONE)
         {
             asd.past_forecast = check_session_for_AF_forecast(asd, p, direction, service_id);
             if (asd.past_forecast != APP_ID_UNKNOWN)
index be44b8d22374f7b2289fff8af9a8dd1e3b207713..29d7c7e8d3b6d81a386e686e723f8e15f9f9181f 100644 (file)
@@ -298,7 +298,8 @@ void AppIdSession::sync_with_snort_protocol_id(AppId newAppId, Packet* p)
             break;
         }
 
-        AppInfoTableEntry* entry = ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_entry(newAppId);
+        AppInfoTableEntry* entry =
+            ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_entry(newAppId);
         if (entry)
         {
             SnortProtocolId tmp_snort_protocol_id = entry->snort_protocol_id;
@@ -345,7 +346,8 @@ void AppIdSession::check_app_detection_restart(AppidChangeBits& change_bits)
         encrypted.referred_id = pick_referred_payload_app_id();
         reinit_session_data(change_bits);
         if (appidDebug->is_active())
-            LogMessage("AppIdDbg %s SSL decryption is available, restarting app detection\n", appidDebug->get_debug_session());
+            LogMessage("AppIdDbg %s SSL decryption is available, restarting app detection\n",
+                appidDebug->get_debug_session());
 
         // APPID_SESSION_ENCRYPTED is set upon receiving a command which upgrades the session to
         // SSL. Next packet after the command will have encrypted traffic.  In the case of a
@@ -415,8 +417,9 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits)
     if ((scan_flags & SCAN_SSL_HOST_FLAG) and tls_str)
     {
         size_t size = strlen(tls_str);
-        if ((ret = ctxt.get_odp_ctxt().get_ssl_matchers().scan_hostname((const uint8_t*)tls_str, size,
-                client_id, payload_id)))
+        if ((ret =
+            ctxt.get_odp_ctxt().get_ssl_matchers().scan_hostname((const uint8_t*)tls_str, size,
+            client_id, payload_id)))
         {
             if (client.get_id() == APP_ID_NONE or client.get_id() == APP_ID_SSL_CLIENT)
                 set_client_appid_data(client_id, change_bits);
@@ -429,7 +432,7 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits)
     {
         size_t size = strlen(tls_str);
         if ((ret = ctxt.get_odp_ctxt().get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size,
-                client_id, payload_id)))
+            client_id, payload_id)))
         {
             if (client.get_id() == APP_ID_NONE or client.get_id() == APP_ID_SSL_CLIENT)
                 set_client_appid_data(client_id, change_bits);
@@ -442,7 +445,7 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits)
     {
         size_t size = strlen(tls_str);
         if ((ret = ctxt.get_odp_ctxt().get_ssl_matchers().scan_cname((const uint8_t*)tls_str, size,
-                client_id, payload_id)))
+            client_id, payload_id)))
         {
             set_client_appid_data(client_id, change_bits);
             set_payload_appid_data(payload_id, change_bits);
@@ -454,7 +457,8 @@ void AppIdSession::examine_ssl_metadata(Packet* p, AppidChangeBits& change_bits)
         payload.get_id() == APP_ID_NONE)
     {
         if (appidDebug->is_active())
-            LogMessage("AppIdDbg %s End of SSL/TLS handshake detected with no payloadAppId, so setting to unknown\n", appidDebug->get_debug_session());
+            LogMessage("AppIdDbg %s End of SSL/TLS handshake detected with no payloadAppId, "
+                "so setting to unknown\n", appidDebug->get_debug_session());
         payload.set_id(APP_ID_UNKNOWN);
     }
 }
@@ -503,12 +507,11 @@ void AppIdSession::set_client_appid_data(AppId id, AppidChangeBits& change_bits,
     if (id != cur_id)
     {
         if (cur_id)
-            if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(cur_id) > ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(id))
+            if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(cur_id) >
+                ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(id))
                 return;
-
         client.set_id(id);
     }
-
     client.set_version(version, change_bits);
 }
 
@@ -529,7 +532,8 @@ void AppIdSession::set_payload_appid_data(AppId id, AppidChangeBits& change_bits
     if (id <= APP_ID_NONE)
         return;
 
-    if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(payload.get_id()) > ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(id))
+    if (ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(payload.get_id()) >
+        ctxt.get_odp_ctxt().get_app_info_mgr().get_priority(id))
         return;
     payload.set_id(id);
     payload.set_version(version, change_bits);
@@ -551,6 +555,13 @@ void AppIdSession::set_service_appid_data(AppId id, AppidChangeBits& change_bits
     service.update(id, change_bits, version);
 }
 
+bool AppIdSession::is_svc_taking_too_much_time()
+{
+    return (init_pkts_without_reply > ctxt.get_odp_ctxt().max_packet_service_fail_ignore_bytes ||
+        (init_pkts_without_reply > ctxt.get_odp_ctxt().max_packet_before_service_fail &&
+        init_bytes_without_reply > ctxt.get_odp_ctxt().max_bytes_before_service_fail));
+}
+
 void AppIdSession::free_tls_session_data()
 {
     if (tsession)
@@ -616,7 +627,6 @@ void* AppIdSession::remove_flow_data(unsigned id)
         delete it->second;
         flow_data.erase(it);
     }
-
     return data;
 }
 
@@ -959,12 +969,14 @@ bool AppIdSession::is_tp_appid_available() const
     return true;
 }
 
-void AppIdSession::set_tp_app_id(Packet& p, AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits)
+void AppIdSession::set_tp_app_id(Packet& p, AppidSessionDirection dir, AppId app_id,
+    AppidChangeBits& change_bits)
 {
     if (tp_app_id != app_id)
     {
         tp_app_id = app_id;
-        AppInfoTableEntry* entry = ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_entry(tp_app_id);
+        AppInfoTableEntry* entry =
+            ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_entry(tp_app_id);
         if (entry)
         {
             tp_app_id_deferred = (entry->flags & APPINFO_FLAG_DEFER) ? true : false;
@@ -973,12 +985,14 @@ void AppIdSession::set_tp_app_id(Packet& p, AppidSessionDirection dir, AppId app
     }
 }
 
-void AppIdSession::set_tp_payload_app_id(Packet& p, AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits)
+void AppIdSession::set_tp_payload_app_id(Packet& p, AppidSessionDirection dir, AppId app_id,
+    AppidChangeBits& change_bits)
 {
     if (tp_payload_app_id != app_id)
     {
         tp_payload_app_id = app_id;
-        AppInfoTableEntry* entry = ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_entry(tp_payload_app_id);
+        AppInfoTableEntry* entry =
+            ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_entry(tp_payload_app_id);
         if (entry)
         {
             tp_payload_app_id_deferred = (entry->flags & APPINFO_FLAG_DEFER_PAYLOAD) ? true : false;
index dd1c1cd3b809de0fc62789a0ebbf17fdfbc15796..866082e718113cddcababce9e24cac8d0b0c682a 100644 (file)
@@ -210,6 +210,8 @@ public:
     std::unordered_map<unsigned, AppIdFlowData*> flow_data;
     CommonAppIdData common;
     uint16_t session_packet_count = 0;
+    uint16_t init_pkts_without_reply = 0;
+    uint64_t init_bytes_without_reply = 0;
 
     snort::SfIp service_ip;
     uint16_t service_port = 0;
@@ -285,10 +287,13 @@ public:
     void clear_session_flags(uint64_t flags) { common.flags &= ~flags; }
     uint64_t get_session_flags(uint64_t flags) const { return (common.flags & flags); }
     void set_service_detected() { common.flags |= APPID_SESSION_SERVICE_DETECTED; }
-    bool is_service_detected() { return ((common.flags & APPID_SESSION_SERVICE_DETECTED) == 0) ? false : true; }
+    bool is_service_detected() { return ((common.flags & APPID_SESSION_SERVICE_DETECTED) == 0) ?
+        false : true; }
     void set_client_detected() { common.flags |= APPID_SESSION_CLIENT_DETECTED; }
-    bool is_client_detected() { return ((common.flags & APPID_SESSION_CLIENT_DETECTED) == 0) ? false : true; }
+    bool is_client_detected() { return ((common.flags & APPID_SESSION_CLIENT_DETECTED) == 0) ?
+        false : true; }
     bool is_decrypted() { return ((common.flags & APPID_SESSION_DECRYPTED) == 0) ? false : true; }
+    bool is_svc_taking_too_much_time();
 
     void* get_flow_data(unsigned id);
     int add_flow_data(void* data, unsigned id, AppIdFreeFCN);
@@ -338,8 +343,10 @@ public:
     bool is_tp_processing_done() const;
     bool is_tp_appid_available() const;
 
-    void set_tp_app_id(snort::Packet& p, AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits);
-    void set_tp_payload_app_id(snort::Packet& p, AppidSessionDirection dir, AppId app_id, AppidChangeBits& change_bits);
+    void set_tp_app_id(snort::Packet& p, AppidSessionDirection dir, AppId app_id,
+        AppidChangeBits& change_bits);
+    void set_tp_payload_app_id(snort::Packet& p, AppidSessionDirection dir, AppId app_id,
+        AppidChangeBits& change_bits);
 
     inline void set_tp_app_id(AppId app_id) {
         if (tp_app_id != app_id)
index c1ef13c032d2cc3418e79298fcb45da68121cac3..5471396c271a9881d61f4f34fc85eb0da09d3779 100644 (file)
@@ -670,6 +670,16 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p,
             }
         }
 
+        /* If the session appears to only have the client sending data then 
+           we must mark the service unknown to prevent pending forever. */
+        if (asd.service_disco_state == APPID_DISCO_STATE_STATEFUL &&
+            asd.service.get_id() == APP_ID_NONE && asd.is_svc_taking_too_much_time())
+        {
+                asd.stop_service_inspection(p, direction);
+                asd.service.set_id(APP_ID_UNKNOWN, asd.ctxt.get_odp_ctxt());   
+                return isTpAppidDiscoveryDone;
+        }
+
         AppIdDnsSession* dsession = asd.get_dns_session();
         if (asd.service.get_id() == APP_ID_DNS && asd.ctxt.get_odp_ctxt().dns_host_reporting
             && dsession->get_host())