From: Mike Stepanek (mstepane) Date: Mon, 21 May 2018 20:54:09 +0000 (-0400) Subject: Merge pull request #1229 in SNORT/snort3 from appid_ooo to master X-Git-Tag: 3.0.0-245~4 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=eb43978e5e173f942160a404e2d6414cf41dff97;p=thirdparty%2Fsnort3.git Merge pull request #1229 in SNORT/snort3 from appid_ooo to master Squashed commit of the following: commit da9049260a50d2a5e08b7e024c7d05f53f18d609 Author: Shravan Rangaraju 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 --- diff --git a/src/network_inspectors/appid/appid_api.h b/src/network_inspectors/appid/appid_api.h index 829887277..eab8e1c31 100644 --- a/src/network_inspectors/appid/appid_api.h +++ b/src/network_inspectors/appid/appid_api.h @@ -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 | \ diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index 29f7c80ff..c54f23858 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -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); } } diff --git a/src/network_inspectors/appid/appid_discovery.h b/src/network_inspectors/appid/appid_discovery.h index c93c45f67..b986a82a2 100644 --- a/src/network_inspectors/appid/appid_discovery.h +++ b/src/network_inspectors/appid/appid_discovery.h @@ -26,6 +26,7 @@ #include #include +#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 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 diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index 70de5621d..3b2fe0b81 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -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 , 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 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)