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);
}
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;
}
{
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;
}
*lcd = tolower(*lcd);
lcd++;
}
-
return dest;
}
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;
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;
}
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;
}
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")))
|| 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")))
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);
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")))
{
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
}
FILE* tableFile = fopen(filepath, "r");
- if ( !tableFile )
+ if (!tableFile)
{
ParseError("appid: could not open %s", filepath);
}
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);
#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;
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();
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);
}
AppIdDiscovery::~AppIdDiscovery()
{
- for (auto pd : pattern_data )
+ for (auto pd : pattern_data)
delete pd;
pattern_data.clear();
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;
}
{
}
-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);
}
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;
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)))
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;
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;
{
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)
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)
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;
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;
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;
}
}
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());
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))
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;
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
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;
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);
}
}
}
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;
}
// 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)
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;
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;
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)
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;
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
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);
{
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);
{
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);
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);
}
}
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);
}
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);
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)
delete it->second;
flow_data.erase(it);
}
-
return data;
}
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;
}
}
-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;
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;
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);
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)
}
}
+ /* 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())