]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2656 in SNORT/snort3 from ~KAMURTHI/snort3:ha_appid to master
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Thu, 10 Dec 2020 22:41:39 +0000 (22:41 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Thu, 10 Dec 2020 22:41:39 +0000 (22:41 +0000)
Squashed commit of the following:

commit 040522d0063caca6466e808eeeb0bbd44a9e277e
Author: Kanimozhi Murthi <kamurthi@cisco.com>
Date:   Sun Nov 15 11:58:35 2020 -0500

    appid: add support for apps, http host, url and tls host in HA

16 files changed:
src/network_inspectors/appid/CMakeLists.txt
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_api.h
src/network_inspectors/appid/appid_ha.cc [new file with mode: 0644]
src/network_inspectors/appid/appid_ha.h [new file with mode: 0644]
src/network_inspectors/appid/appid_http_session.cc
src/network_inspectors/appid/appid_http_session.h
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.cc
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_http_session_test.cc
src/network_inspectors/appid/test/appid_mock_session.h
src/network_inspectors/appid/test/appid_session_api_test.cc

index e0246f137d7329d1dbfc83e3dcfc1dd2f0af9560..0d0f37a85111474a914c64ed662b8d63a8e87b47 100644 (file)
@@ -163,6 +163,8 @@ set ( APPID_SOURCES
     appid_discovery.cc
     appid_discovery.h
     appid_dns_session.h
+    appid_ha.cc
+    appid_ha.h
     appid_http_session.cc
     appid_http_session.h
     appid_peg_counts.h
index 82877ae899f8474b3daa5cd9713cfba1c4d82242..b8ddccffd42da4923b84432bb1bb86cb4caa0329 100644 (file)
@@ -115,122 +115,6 @@ AppId AppIdApi::get_application_id(const char* appName, const AppIdContext& ctxt
     return ctxt.get_odp_ctxt().get_app_info_mgr().get_appid_by_name(appName);
 }
 
-#define APPID_HA_FLAGS_APP ( 1 << 0 )
-#define APPID_HA_FLAGS_TP_DONE ( 1 << 1 )
-#define APPID_HA_FLAGS_SVC_DONE ( 1 << 2 )
-#define APPID_HA_FLAGS_HTTP ( 1 << 3 )
-
-uint32_t AppIdApi::produce_ha_state(const Flow& flow, uint8_t* buf)
-{
-    assert(buf);
-    AppIdSessionHA* appHA = (AppIdSessionHA*)buf;
-    AppIdSession* asd = get_appid_session(flow);
-    if (asd)
-    {
-        appHA->flags = APPID_HA_FLAGS_APP;
-        if (asd->is_tp_appid_available())
-            appHA->flags |= APPID_HA_FLAGS_TP_DONE;
-        if (asd->is_service_detected())
-            appHA->flags |= APPID_HA_FLAGS_SVC_DONE;
-        if (asd->get_session_flags(APPID_SESSION_HTTP_SESSION))
-            appHA->flags |= APPID_HA_FLAGS_HTTP;
-        appHA->appId[0] = asd->get_tp_app_id();
-        appHA->appId[1] = asd->get_service_id();
-        appHA->appId[2] = asd->client_inferred_service_id;
-        appHA->appId[3] = asd->get_port_service_id();
-        const AppIdHttpSession* hsession = asd->get_http_session();
-        if (hsession)
-            appHA->appId[4] = hsession->payload.get_id();
-        else
-            appHA->appId[4] = asd->get_payload_id();
-        appHA->appId[5] = asd->get_tp_payload_app_id();
-        if (hsession)
-            appHA->appId[6] = hsession->client.get_id();
-        else
-            appHA->appId[6] = asd->get_client_id();
-        appHA->appId[7] = asd->misc_app_id;
-        appHA->asid = asd->asid;
-    }
-    else
-        memset(appHA, 0, sizeof(*appHA));
-
-    return sizeof(*appHA);
-}
-
-uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpProtocol proto,
-    SfIp* ip, uint16_t port)
-{
-    const AppIdSessionHA* appHA = (const AppIdSessionHA*)buf;
-    if (appHA->flags & APPID_HA_FLAGS_APP)
-    {
-        AppIdSession* asd =
-            (AppIdSession*)(flow.get_flow_data(AppIdSession::inspector_id));
-
-        if (!asd)
-        {
-            AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-            if (inspector)
-            {
-                asd = new AppIdSession(proto, ip, port, *inspector,
-                    inspector->get_ctxt().get_odp_ctxt(), appHA->asid);
-                flow.set_flow_data(asd);
-                asd->set_service_id(appHA->appId[1], asd->get_odp_ctxt());
-                if (asd->get_service_id() == APP_ID_FTP_CONTROL)
-                {
-                    asd->set_session_flags(APPID_SESSION_CLIENT_DETECTED |
-                            APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
-                    if (!ServiceDiscovery::add_ftp_service_state(*asd))
-                        asd->set_session_flags(APPID_SESSION_CONTINUE);
-
-                    asd->service_disco_state = APPID_DISCO_STATE_STATEFUL;
-                }
-                else
-                    asd->service_disco_state = APPID_DISCO_STATE_FINISHED;
-
-                asd->client_disco_state = APPID_DISCO_STATE_FINISHED;
-                if (asd->tpsession)
-                    asd->tpsession->set_state(TP_STATE_HA);
-            }
-        }
-
-        if (!asd)
-        {
-            return sizeof(*appHA);
-        }
-
-        if((appHA->flags & APPID_HA_FLAGS_TP_DONE) && asd->tpsession)
-        {
-            asd->tpsession->set_state(TP_STATE_TERMINATED);
-            asd->set_session_flags(APPID_SESSION_NO_TPI);
-        }
-
-        if (appHA->flags & APPID_HA_FLAGS_SVC_DONE)
-            asd->set_service_detected();
-
-        if (appHA->flags & APPID_HA_FLAGS_HTTP)
-            asd->set_session_flags(APPID_SESSION_HTTP_SESSION);
-
-        asd->set_tp_app_id(appHA->appId[0]);
-        asd->set_service_id(appHA->appId[1], asd->get_odp_ctxt());
-        asd->client_inferred_service_id = appHA->appId[2];
-        asd->set_port_service_id(appHA->appId[3]);
-        AppIdHttpSession* hsession = nullptr;
-        if (appHA->appId[1] == APP_ID_HTTP or appHA->appId[1] == APP_ID_RTMP)
-            hsession = asd->create_http_session();
-        if (hsession)
-            hsession->payload.set_id(appHA->appId[4]);
-        else
-            asd->set_payload_id(appHA->appId[4]);
-        asd->set_tp_payload_app_id(appHA->appId[5]);
-        if (hsession)
-            hsession->client.set_id(appHA->appId[6]);
-        else
-            asd->set_client_id(appHA->appId[6]);
-        asd->misc_app_id = appHA->appId[7];
-    }
-    return sizeof(*appHA);
-}
-
 bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
     const char* first_alt_name, const char* common_name, const char* org_unit,
     bool sni_mismatch, AppId& service_id, AppId& client_id, AppId& payload_id)
index 2e49a18870300b8f238c3a3d7a8628c55dc71404..ab6c80b42fb62ad7eca358625d3b6a77e64ba65f 100644 (file)
@@ -34,16 +34,6 @@ class AppIdSession;
 
 namespace snort
 {
-
-#define APPID_HA_SESSION_APP_NUM_MAX 8    // maximum number of appIds replicated for a flow/session
-
-struct AppIdSessionHA
-{
-    uint16_t flags;
-    uint16_t asid;
-    AppId appId[APPID_HA_SESSION_APP_NUM_MAX];
-};
-
 // -----------------------------------------------------------------------------
 // AppId API
 // -----------------------------------------------------------------------------
@@ -58,9 +48,6 @@ public:
     const char* get_application_name(AppId app_id, const Flow& flow);
     const char* get_application_name(const Flow& flow, bool from_client);
     AppId get_application_id(const char* appName, const AppIdContext& ctxt);
-    uint32_t produce_ha_state(const Flow& flow, uint8_t* buf);
-    uint32_t consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t length, IpProtocol,
-        SfIp*, uint16_t initiatorPort);
     bool ssl_app_group_id_lookup(Flow* flow, const char*, const char*, const char*,
         const char*, bool, AppId& service_id, AppId& client_id, AppId& payload_id);
     const AppIdSessionApi* get_appid_session_api(const Flow& flow) const;
diff --git a/src/network_inspectors/appid/appid_ha.cc b/src/network_inspectors/appid/appid_ha.cc
new file mode 100644 (file)
index 0000000..9b672e4
--- /dev/null
@@ -0,0 +1,354 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// appid_ha.cc author Kani Murthi <kamurthi@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "appid_ha.h"
+
+#include "flow/flow_key.h"
+#include "managers/inspector_manager.h"
+
+#include "appid_debug.h"
+#include "appid_session.h"
+#include "tp_lib_handler.h"
+
+#define APPID_HA_FLAGS_TP_DONE ( 1 << 0 )
+#define APPID_HA_FLAGS_SVC_DONE ( 1 << 1 )
+#define APPID_HA_FLAGS_HTTP ( 1 << 2 )
+
+using namespace snort;
+
+THREAD_LOCAL AppIdHAAppsClient* AppIdHAManager::ha_apps_client = nullptr;
+THREAD_LOCAL AppIdHAHttpClient* AppIdHAManager::ha_http_client = nullptr;
+THREAD_LOCAL AppIdHATlsHostClient* AppIdHAManager::ha_tls_host_client = nullptr;
+
+static AppIdSession* create_appid_session(Flow& flow, const FlowKey* key)
+{
+    AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+    AppIdSession* asd = new AppIdSession(static_cast<IpProtocol>(key->ip_protocol),
+        flow.flags.client_initiated ? &flow.client_ip : &flow.server_ip,
+        flow.flags.client_initiated ? flow.client_port : flow.server_port, *inspector,
+        inspector->get_ctxt().get_odp_ctxt(), key->addressSpaceId);
+    if (appidDebug->is_active())
+        LogMessage("AppIdDbg %s high-avail - New AppId session created in consume\n",
+            appidDebug->get_debug_session());
+
+    flow.set_flow_data(asd);
+    asd->flow = &flow;
+
+    return asd;
+}
+
+bool AppIdHAAppsClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg,
+    uint8_t size)
+{
+    assert(key and flow);
+    if (size != sizeof(AppIdSessionHAApps))
+        return false;
+
+    AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+    if (!inspector)
+        return false;
+
+    AppIdSession* asd = (AppIdSession*)(flow->get_flow_data(AppIdSession::inspector_id));
+    const AppIdSessionHAApps* appHA = (const AppIdSessionHAApps*)msg.cursor;
+
+    if (appidDebug->is_enabled())
+    {
+        appidDebug->activate(flow, asd, inspector->get_ctxt().config.log_all_sessions);
+        LogMessage("AppIdDbg %s high-avail - Consuming app data - flags 0x%x, service %d, client %d, "
+            "payload %d, misc %d, referred %d, client_inferred_service %d, port_service %d, "
+            "tp_app %d, tp_payload %d\n",
+            appidDebug->get_debug_session(), appHA->flags, appHA->appId[APPID_HA_APP_SERVICE],
+            appHA->appId[APPID_HA_APP_CLIENT], appHA->appId[APPID_HA_APP_PAYLOAD],
+            appHA->appId[APPID_HA_APP_MISC], appHA->appId[APPID_HA_APP_REFERRED],
+            appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE],
+            appHA->appId[APPID_HA_APP_PORT_SERVICE], appHA->appId[APPID_HA_APP_TP],
+            appHA->appId[APPID_HA_APP_TP_PAYLOAD]);
+    }
+
+    if (!asd)
+    {
+        asd = create_appid_session(*flow, key);
+        asd->set_service_id(appHA->appId[APPID_HA_APP_SERVICE], asd->get_odp_ctxt());
+        if (asd->get_service_id() == APP_ID_FTP_CONTROL)
+        {
+            asd->set_session_flags(APPID_SESSION_CLIENT_DETECTED |
+                APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
+            if (!ServiceDiscovery::add_ftp_service_state(*asd))
+                asd->set_session_flags(APPID_SESSION_CONTINUE);
+
+            asd->service_disco_state = APPID_DISCO_STATE_STATEFUL;
+        }
+        else
+            asd->service_disco_state = APPID_DISCO_STATE_FINISHED;
+
+        asd->client_disco_state = APPID_DISCO_STATE_FINISHED;
+        if (asd->get_tp_appid_ctxt())
+        {
+            const TPLibHandler* tph = TPLibHandler::get();
+            TpAppIdCreateSession tpsf = tph->tpsession_factory();
+            if ( !(asd->tpsession = tpsf(*asd->get_tp_appid_ctxt())) )
+                ErrorMessage("appid: Could not allocate asd.tpsession data in consume");
+            else
+                asd->tpsession->set_state(TP_STATE_HA);
+        }
+    }
+
+    if ((appHA->flags & APPID_HA_FLAGS_TP_DONE) and asd->tpsession)
+    {
+        asd->tpsession->set_state(TP_STATE_TERMINATED);
+        asd->set_session_flags(APPID_SESSION_NO_TPI);
+    }
+
+    if (appHA->flags & APPID_HA_FLAGS_SVC_DONE)
+        asd->set_service_detected();
+
+    if (appHA->flags & APPID_HA_FLAGS_HTTP)
+        asd->set_session_flags(APPID_SESSION_HTTP_SESSION);
+    asd->set_service_id(appHA->appId[APPID_HA_APP_SERVICE], asd->get_odp_ctxt());
+    AppIdHttpSession* hsession = nullptr;
+    if (appHA->appId[APPID_HA_APP_SERVICE] == APP_ID_HTTP or
+        appHA->appId[APPID_HA_APP_SERVICE] == APP_ID_RTMP)
+        hsession = asd->create_http_session();
+    if (hsession)
+    {
+        hsession->client.set_id(appHA->appId[APPID_HA_APP_CLIENT]);
+        hsession->payload.set_id(appHA->appId[APPID_HA_APP_PAYLOAD]);
+        hsession->misc_app_id = appHA->appId[APPID_HA_APP_MISC];
+        hsession->referred_payload_app_id = appHA->appId[APPID_HA_APP_REFERRED];
+    }
+    else
+    {
+        asd->set_client_id(appHA->appId[APPID_HA_APP_CLIENT]);
+        asd->set_payload_id(appHA->appId[APPID_HA_APP_PAYLOAD]);
+        asd->misc_app_id = appHA->appId[APPID_HA_APP_MISC];
+    }
+    asd->client_inferred_service_id = appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE];
+    asd->set_port_service_id(appHA->appId[APPID_HA_APP_PORT_SERVICE]);
+    asd->set_tp_app_id(appHA->appId[APPID_HA_APP_TP]);
+    asd->set_tp_payload_app_id(appHA->appId[APPID_HA_APP_TP_PAYLOAD]);
+
+    asd->set_consumed_ha_data(true);
+
+    msg.advance_cursor(sizeof(AppIdSessionHAApps));
+    return true;
+}
+
+bool AppIdHAAppsClient::produce(Flow& flow, HAMessage& msg)
+{
+    if (!msg.fits(sizeof(AppIdSessionHAApps)))
+        return false;
+    assert(msg.cursor);
+
+    AppIdSession* asd = (AppIdSession*)flow.get_flow_data(AppIdSession::inspector_id);
+    if (!asd)
+        return false;
+
+    AppIdSessionHAApps* appHA = (AppIdSessionHAApps*)(msg.cursor);
+    if (asd->is_tp_appid_available())
+        appHA->flags |= APPID_HA_FLAGS_TP_DONE;
+    if (asd->is_service_detected())
+        appHA->flags |= APPID_HA_FLAGS_SVC_DONE;
+    if (asd->get_session_flags(APPID_SESSION_HTTP_SESSION))
+        appHA->flags |= APPID_HA_FLAGS_HTTP;
+    appHA->appId[APPID_HA_APP_SERVICE] = asd->get_service_id();
+    const AppIdHttpSession* hsession = asd->get_http_session(0);
+    if (hsession)
+    {
+        appHA->appId[APPID_HA_APP_CLIENT] = hsession->client.get_id();
+        appHA->appId[APPID_HA_APP_PAYLOAD] = hsession->payload.get_id();
+        appHA->appId[APPID_HA_APP_MISC] = hsession->misc_app_id;
+        appHA->appId[APPID_HA_APP_REFERRED] = hsession->referred_payload_app_id;
+    }
+    else
+    {
+        appHA->appId[APPID_HA_APP_CLIENT] = asd->get_client_id();
+        appHA->appId[APPID_HA_APP_PAYLOAD] = asd->get_payload_id();
+        appHA->appId[APPID_HA_APP_MISC] = asd->misc_app_id;
+        appHA->appId[APPID_HA_APP_REFERRED] = APP_ID_NONE;
+    }
+    appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE] = asd->client_inferred_service_id;
+    appHA->appId[APPID_HA_APP_PORT_SERVICE] = asd->get_port_service_id();
+    appHA->appId[APPID_HA_APP_TP] = asd->get_tp_app_id();
+    appHA->appId[APPID_HA_APP_TP_PAYLOAD] = asd->get_tp_payload_app_id();
+
+    if (appidDebug->is_active())
+        LogMessage("AppIdDbg %s high-avail - Producing app data - flags 0x%x, service %d, client %d, "
+            "payload %d, misc %d, referred %d, client_inferred_service %d, port_service %d, "
+            "tp_app %d, tp_payload %d\n",
+            appidDebug->get_debug_session(), appHA->flags, appHA->appId[APPID_HA_APP_SERVICE],
+            appHA->appId[APPID_HA_APP_CLIENT], appHA->appId[APPID_HA_APP_PAYLOAD],
+            appHA->appId[APPID_HA_APP_MISC], appHA->appId[APPID_HA_APP_REFERRED],
+            appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE],
+            appHA->appId[APPID_HA_APP_PORT_SERVICE], appHA->appId[APPID_HA_APP_TP],
+            appHA->appId[APPID_HA_APP_TP_PAYLOAD]);
+
+    msg.advance_cursor(sizeof(AppIdSessionHAApps));
+    return true;
+}
+
+bool AppIdHAHttpClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg,
+    uint8_t size)
+{
+    assert(key and flow);
+
+    if (size != sizeof(AppIdSessionHAHttp))
+        return false;
+
+    AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+    if (!inspector)
+        return false;
+
+    AppIdSession* asd = appid_api.get_appid_session(*flow);
+    AppIdSessionHAHttp* appHA = (AppIdSessionHAHttp*)msg.cursor;
+    if (appidDebug->is_enabled())
+    {
+        appidDebug->activate(flow, asd, inspector->get_ctxt().config.log_all_sessions);
+        LogMessage("AppIdDbg %s high-avail - Consuming HTTP data - URL %s, host %s\n",
+            appidDebug->get_debug_session(), appHA->url, appHA->host);
+    }
+
+    if (!asd)
+        asd = create_appid_session(*flow, key);
+
+    AppidChangeBits change_bits;
+    AppIdHttpSession* hsession = asd->get_http_session();
+    if (!hsession)
+        hsession = asd->create_http_session();
+
+    hsession->set_field(MISC_URL_FID, new std::string(appHA->url), change_bits);
+    hsession->set_field(REQ_HOST_FID, new std::string(appHA->host), change_bits);
+
+    asd->set_consumed_ha_data(true);
+
+    msg.advance_cursor(sizeof(AppIdSessionHAHttp));
+    return true;
+}
+
+bool AppIdHAHttpClient::produce(Flow& flow, HAMessage& msg)
+{
+    if (!msg.fits(sizeof(AppIdSessionHAHttp)))
+        return false;
+    assert(msg.cursor);
+
+    AppIdSession* asd = appid_api.get_appid_session(flow);
+    if (!asd)
+      return false;
+
+    const AppIdHttpSession* hsession = asd->get_http_session();
+    if (!hsession)
+        return false;
+
+    const char* url = hsession->get_cfield(MISC_URL_FID);
+    const char* host = hsession->get_cfield(REQ_HOST_FID);
+    if (!url and !host)
+        return false;
+
+    AppIdSessionHAHttp* appHA = (AppIdSessionHAHttp*)msg.cursor;
+
+    if (url)
+    {
+        auto length = strlen(url);
+        if (length >= APPID_HA_MAX_FIELD_LEN)
+            length = APPID_HA_MAX_FIELD_LEN - 1;
+        memcpy(appHA->url, (void *)url, length);
+        appHA->url[length] = '\0';
+    }
+    else
+        appHA->url[0] = '\0';
+
+    if (host)
+    {
+        auto length = strlen(host);
+        if (length >= APPID_HA_MAX_FIELD_LEN)
+            length = APPID_HA_MAX_FIELD_LEN - 1;
+        memcpy(appHA->host, (void *)host, length);
+        appHA->host[length] = '\0';
+    }
+    else
+        appHA->host[0] = '\0';
+
+    if (appidDebug->is_active())
+        LogMessage("AppIdDbg %s high-avail - Producing HTTP data - URL %s, host %s\n",
+            appidDebug->get_debug_session(), appHA->url, appHA->host);
+
+    msg.advance_cursor(sizeof(AppIdSessionHAHttp));
+    return true;
+}
+
+bool AppIdHATlsHostClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg,
+    uint8_t size)
+{
+    assert(key and flow);
+    if (size != sizeof(AppIdSessionHATlsHost))
+        return false;
+
+    AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+    if (!inspector)
+        return false;
+
+    AppIdSession* asd = appid_api.get_appid_session(*flow);
+    AppIdSessionHATlsHost* appHA = (AppIdSessionHATlsHost*)msg.cursor;
+    if (appidDebug->is_enabled())
+    {
+        appidDebug->activate(flow, asd, inspector->get_ctxt().config.log_all_sessions);
+        LogMessage("AppIdDbg %s high-avail - Consuming TLS host - %s\n",
+            appidDebug->get_debug_session(), appHA->tls_host);
+    }
+
+    if (!asd)
+        asd = create_appid_session(*flow, key);
+
+    asd->set_tls_host(appHA->tls_host);
+
+    asd->set_consumed_ha_data(true);
+
+    msg.advance_cursor(sizeof(AppIdSessionHATlsHost));
+    return true;
+}
+
+bool AppIdHATlsHostClient::produce(Flow& flow, HAMessage& msg)
+{
+    if (!msg.fits(sizeof(AppIdSessionHATlsHost)))
+        return false;
+    assert(msg.cursor);
+
+    AppIdSession* asd = appid_api.get_appid_session(flow);
+    if (!asd or !asd->get_api().get_tls_host())
+        return false;
+
+    AppIdSessionHATlsHost* appHA = (AppIdSessionHATlsHost*)msg.cursor;
+    const char* tls_host = asd->get_api().get_tls_host();
+    auto length = strlen(tls_host);
+    if (length >= APPID_HA_MAX_FIELD_LEN)
+        length = APPID_HA_MAX_FIELD_LEN - 1;
+    memcpy(appHA->tls_host, tls_host, length);
+    appHA->tls_host[length] = '\0';
+
+    if (appidDebug->is_active())
+        LogMessage("AppIdDbg %s high-avail - Producing TLS host - %s\n",
+            appidDebug->get_debug_session(), appHA->tls_host);
+
+    msg.advance_cursor(sizeof(AppIdSessionHATlsHost));
+    return true;
+}
diff --git a/src/network_inspectors/appid/appid_ha.h b/src/network_inspectors/appid/appid_ha.h
new file mode 100644 (file)
index 0000000..cf5596b
--- /dev/null
@@ -0,0 +1,112 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+
+// appid_ha.h author Kani Murthi <kamurthi@cisco.com>
+
+#ifndef APPID_HA_H
+#define APPID_HA_H
+
+#include "flow/flow.h"
+#include "flow/ha.h"
+#include "appid_inspector.h"
+
+#define APPID_HA_MAX_FIELD_LEN 32
+
+enum AppIdHAAppType
+{
+    APPID_HA_APP_SERVICE = 0,
+    APPID_HA_APP_CLIENT,
+    APPID_HA_APP_PAYLOAD,
+    APPID_HA_APP_MISC,
+    APPID_HA_APP_REFERRED,
+    APPID_HA_APP_CLIENT_INFERRED_SERVICE,
+    APPID_HA_APP_PORT_SERVICE,
+    APPID_HA_APP_TP,
+    APPID_HA_APP_TP_PAYLOAD,
+    APPID_HA_APP_MAX
+};
+
+struct AppIdSessionHAApps
+{
+    uint16_t flags;
+    AppId appId[APPID_HA_APP_MAX];
+};
+
+struct AppIdSessionHAHttp
+{
+    char url[APPID_HA_MAX_FIELD_LEN];
+    char host[APPID_HA_MAX_FIELD_LEN];
+};
+
+struct AppIdSessionHATlsHost
+{
+    char tls_host[APPID_HA_MAX_FIELD_LEN];
+};
+
+class AppIdHAAppsClient : public snort::FlowHAClient
+{
+public:
+    AppIdHAAppsClient() : FlowHAClient(sizeof(AppIdSessionHAApps), false) { }
+    bool consume(snort::Flow*&, const snort::FlowKey*, snort::HAMessage&, uint8_t size) override;
+    bool produce(snort::Flow&, snort::HAMessage&) override;
+};
+
+class AppIdHAHttpClient : public snort::FlowHAClient
+{
+public:
+    AppIdHAHttpClient() : FlowHAClient(sizeof(AppIdSessionHAHttp), false) { }
+    bool consume(snort::Flow*&, const snort::FlowKey*, snort::HAMessage&, uint8_t size) override;
+    bool produce(snort::Flow&, snort::HAMessage&) override;
+};
+
+class AppIdHATlsHostClient : public snort::FlowHAClient
+{
+public:
+    AppIdHATlsHostClient() : FlowHAClient(sizeof(AppIdSessionHATlsHost), false) { }
+    bool consume(snort::Flow*&, const snort::FlowKey*, snort::HAMessage&, uint8_t size) override;
+    bool produce(snort::Flow&, snort::HAMessage&) override;
+};
+
+class AppIdHAManager
+{
+public:
+    static void tinit()
+    {
+        if ( snort::HighAvailabilityManager::active() )
+        {   
+            ha_apps_client = new AppIdHAAppsClient;
+            ha_http_client = new AppIdHAHttpClient;
+            ha_tls_host_client = new AppIdHATlsHostClient;
+        }
+    }
+    static void tterm()
+    {
+        if ( snort::HighAvailabilityManager::active() )
+        {   
+            delete ha_apps_client;
+            delete ha_http_client;
+            delete ha_tls_host_client;
+        }
+    }
+
+    static THREAD_LOCAL AppIdHAAppsClient* ha_apps_client;
+    static THREAD_LOCAL AppIdHAHttpClient* ha_http_client;
+    static THREAD_LOCAL AppIdHATlsHostClient* ha_tls_host_client;
+};
+
+#endif
index 5607cc9886cb1beaa1c85aea236c03cde44c4dfa..ca77eb4b0f7e3cf7d170c705948ce9b98a36d517 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "appid_http_session.h"
 
+#include "flow/ha.h"
 #include "memory/memory_cap.h"
 #include "profiler/profiler.h"
 
@@ -71,9 +72,15 @@ void AppIdHttpSession::set_http_change_bits(AppidChangeBits& change_bits, HttpFi
     {
     case REQ_HOST_FID:
         change_bits.set(APPID_HOST_BIT);
+        assert(asd.flow);
+        if (asd.flow->ha_state)
+            asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
         break;
     case MISC_URL_FID:
         change_bits.set(APPID_URL_BIT);
+        assert(asd.flow);
+        if (asd.flow->ha_state)
+            asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
         break;
     case REQ_AGENT_FID:
         change_bits.set(APPID_USERAGENT_BIT);
@@ -401,14 +408,17 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits, HttpPat
     }
 }
 
-void AppIdHttpSession::set_client(AppId app_id, AppidChangeBits& change_bits, const char* type,
-    const char* version)
+void AppIdHttpSession::set_client(AppId app_id, AppidChangeBits& change_bits,
+    const char* type, const char* version)
 {
     if (app_id <= APP_ID_NONE or (app_id == client.get_id()))
         return;
 
     client.set_id(app_id);
     change_bits.set(APPID_CLIENT_BIT);
+    assert(asd.flow);
+    if (asd.flow->ha_state)
+        asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     if (version)
     {
         client.set_version(version);
@@ -423,14 +433,17 @@ void AppIdHttpSession::set_client(AppId app_id, AppidChangeBits& change_bits, co
     }
 }
 
-void AppIdHttpSession::set_payload(AppId app_id, AppidChangeBits& change_bits, const char* type,
-    const char* version)
+void AppIdHttpSession::set_payload(AppId app_id, AppidChangeBits& change_bits,
+    const char* type, const char* version)
 {
     if (app_id == APP_ID_NONE or (app_id == payload.get_id()))
         return;
 
     payload.set_id(app_id);
     change_bits.set(APPID_PAYLOAD_BIT);
+    assert(asd.flow);
+    if (asd.flow->ha_state)
+        asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     payload.set_version(version);
 
     if (appidDebug->is_active())
index fff88a14d64b71671a5cc9114f71825c94a7d408..ea7fbe38c290ef008807d42f19a0b390c654bbc3 100644 (file)
@@ -150,7 +150,8 @@ public:
 
     void clear_all_fields();
     void set_client(AppId, AppidChangeBits&, const char*, const char* version = nullptr);
-    void set_payload(AppId, AppidChangeBits&, const char* type = nullptr, const char* version = nullptr);
+    void set_payload(AppId, AppidChangeBits&, const char* type = nullptr,
+        const char* version = nullptr);
     void set_referred_payload(AppId, AppidChangeBits&);
 
     uint32_t get_http2_stream_id() const
index ffbde75307fb12fde5e141b69f50b62889ba0db4..238a45bb0cc4bab3f592e2c4a3f869a7aaed84e6 100644 (file)
@@ -38,6 +38,7 @@
 #include "appid_dcerpc_event_handler.h"
 #include "appid_debug.h"
 #include "appid_discovery.h"
+#include "appid_ha.h"
 #include "appid_http_event_handler.h"
 #include "appid_peg_counts.h"
 #include "appid_session.h"
@@ -160,6 +161,8 @@ void AppIdInspector::tinit()
         pkt_thread_tp_appid_ctxt->tinit();
     if (ctxt->config.log_all_sessions)
         appidDebug->set_enabled(true);
+     if ( snort::HighAvailabilityManager::active() )
+        AppIdHAManager::tinit();
 }
 
 void AppIdInspector::tterm()
@@ -171,6 +174,8 @@ void AppIdInspector::tterm()
     odp_thread_local_ctxt = nullptr;
     if (pkt_thread_tp_appid_ctxt)
         pkt_thread_tp_appid_ctxt->tfini();
+    if ( snort::HighAvailabilityManager::active() )
+        AppIdHAManager::tterm();
 }
 
 void AppIdInspector::eval(Packet* p)
index ba1b793c0ea375663259c908e595cca91bd28f04..ed7bb58322933db42d2d0385ec7827ec4929bbf4 100644 (file)
@@ -890,18 +890,21 @@ AppId AppIdSession::pick_ss_referred_payload_app_id() const
 void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
     AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
 {
-    api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits);
+    assert(flow);
+    api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits, *flow);
 }
 
 void AppIdSession::set_ss_application_ids(AppId client_id, AppId payload_id,
     AppidChangeBits& change_bits)
 {
-    api.set_ss_application_ids(client_id, payload_id, change_bits);
+    assert(flow);
+    api.set_ss_application_ids(client_id, payload_id, change_bits, *flow);
 }
 
 void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
 {
-    api.set_application_ids_service(service_id, change_bits);
+    assert(flow);
+    api.set_application_ids_service(service_id, change_bits, *flow);
 }
 
 void AppIdSession::reset_session_data(AppidChangeBits& change_bits)
@@ -1071,6 +1074,23 @@ void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packe
         api.published = true;
     }
 
+    if (consumed_ha_data)
+    {
+        AppIdHttpSession* hsession = get_http_session();
+        if (hsession)
+        {
+            if (hsession->get_field(MISC_URL_FID))
+                change_bits.set(APPID_URL_BIT);
+            if (hsession->get_field(REQ_HOST_FID))
+                change_bits.set(APPID_HOST_BIT);
+        }
+
+        if (api.get_tls_host())
+            change_bits.set(APPID_TLSHOST_BIT);
+
+        consumed_ha_data = false;
+    }
+
     if (change_bits.none())
         return;
 
index 4e4fd53445b29f4b9170242e457c8ec8e33b4d91..2eb364d476935e8e31bfde86bd64c0fc380b5d65 100644 (file)
@@ -562,6 +562,11 @@ public:
             api.set_tls_host(tsession->get_tls_host());
     }
 
+    void set_tls_host(const char* tls_host)
+    {
+        api.set_tls_host(tls_host);
+    }
+
     OdpContext& get_odp_ctxt() const
     {
         return odp_ctxt;
@@ -610,6 +615,11 @@ public:
         api.clear_user_logged_in();
     }
 
+    void set_consumed_ha_data(bool val)
+    {
+        consumed_ha_data = val;
+    }
+
 private:
     uint16_t prev_http2_raw_packet = 0;
 
@@ -629,6 +639,7 @@ private:
     OdpContext& odp_ctxt;
     uint32_t odp_ctxt_version;
     ThirdPartyAppIdContext* tp_appid_ctxt = nullptr;
+    bool consumed_ha_data = false;
 };
 
 #endif
index aed49b8888b0a5e80b505f40dfaaf092a9cfade8..8039bc96b066f2fb9312f84c7c3f3534e80af7a8 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "appid_session_api.h"
 
+#include "flow/ha.h"
 #include "managers/inspector_manager.h"
 #include "appid_inspector.h"
 #include "appid_session.h"
@@ -306,27 +307,35 @@ bool AppIdSessionApi::is_http_inspection_done() const
 }
 
 void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id,
-    AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
+    AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits, Flow& flow)
 {
     if (application_ids[APP_PROTOID_SERVICE] != service_id)
     {
         application_ids[APP_PROTOID_SERVICE] = service_id;
         change_bits.set(APPID_SERVICE_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
     if (application_ids[APP_PROTOID_CLIENT] != client_id)
     {
         application_ids[APP_PROTOID_CLIENT] = client_id;
         change_bits.set(APPID_CLIENT_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
     if (application_ids[APP_PROTOID_PAYLOAD] != payload_id)
     {
         application_ids[APP_PROTOID_PAYLOAD] = payload_id;
         change_bits.set(APPID_PAYLOAD_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
     if (application_ids[APP_PROTOID_MISC] != misc_id)
     {
         application_ids[APP_PROTOID_MISC] = misc_id;
         change_bits.set(APPID_MISC_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
     if (application_ids[APP_PROTOID_REFERRED] != referred_id)
     {
@@ -336,26 +345,33 @@ void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id,
 }
 
 void AppIdSessionApi::set_ss_application_ids(AppId client_id, AppId payload_id,
-    AppidChangeBits& change_bits)
+    AppidChangeBits& change_bits, Flow& flow)
 {
     if (application_ids[APP_PROTOID_CLIENT] != client_id)
     {
         application_ids[APP_PROTOID_CLIENT] = client_id;
         change_bits.set(APPID_CLIENT_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
     if (application_ids[APP_PROTOID_PAYLOAD] != payload_id)
     {
         application_ids[APP_PROTOID_PAYLOAD] = payload_id;
         change_bits.set(APPID_PAYLOAD_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
 }
 
-void AppIdSessionApi::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
+void AppIdSessionApi::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits,
+    Flow& flow)
 {
     if (application_ids[APP_PROTOID_SERVICE] != service_id)
     {
         application_ids[APP_PROTOID_SERVICE] = service_id;
         change_bits.set(APPID_SERVICE_BIT);
+        if (flow.ha_state)
+            flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR);
     }
 }
 
index 19a800bf420743c05c3488317de911c51b67cb76..042f3d11a79186efaa6685e6e5b728fed71b8d70 100644 (file)
@@ -177,9 +177,9 @@ private:
     static THREAD_LOCAL uint32_t appid_flow_data_id;
 
     void set_ss_application_ids(AppId service, AppId client, AppId payload, AppId misc,
-        AppId referred, AppidChangeBits& change_bits);
-    void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits);
-    void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits);
+        AppId referred, AppidChangeBits& change_bits, Flow& flow);
+    void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits, Flow& flow);
+    void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits, Flow& flow);
 
     AppIdHttpSession* get_hsession(uint32_t stream_index = 0) const;
 
index 38d167835a504a04e0b03b919143d5dbce61338f..1a5c1f6e6240fe4d69b88c0d26bdd3e2b7b02ef0 100644 (file)
@@ -236,86 +236,6 @@ TEST(appid_api, get_application_id)
     CHECK_EQUAL(id, 1492);
 }
 
-TEST(appid_api, produce_ha_state)
-{
-    AppIdSessionHA appHA, cmp_buf;
-
-    memset((void*)&appHA, 0, sizeof(appHA));
-    memset((void*)&cmp_buf, 0, sizeof(cmp_buf));
-    mock_session->flags |= APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_HTTP_SESSION;
-
-    mock_session->set_tp_app_id(APPID_UT_ID);
-    mock_session->set_service_id(APPID_UT_ID + 1, stub_odp_ctxt);
-    mock_session->client_inferred_service_id = APPID_UT_ID + 2;
-    mock_session->set_port_service_id(APPID_UT_ID + 3);
-    mock_session->set_payload_id(APPID_UT_ID + 4);
-    mock_session->set_tp_payload_app_id(APPID_UT_ID + 5);
-    mock_session->set_client_id(APPID_UT_ID + 6);
-    mock_session->misc_app_id = APPID_UT_ID + 7;
-
-    uint32_t val = appid_api.produce_ha_state(*flow, (uint8_t*)&appHA);
-    CHECK_TRUE(val == sizeof(appHA));
-    CHECK_TRUE(appHA.appId[0] == APPID_UT_ID);
-    CHECK_TRUE(appHA.appId[1] == APPID_UT_ID + 1);
-    CHECK_TRUE(appHA.appId[2] == APPID_UT_ID + 2);
-    CHECK_TRUE(appHA.appId[3] == APPID_UT_ID + 3);
-    CHECK_TRUE(appHA.appId[4] == APPID_UT_ID + 4);
-    CHECK_TRUE(appHA.appId[5] == APPID_UT_ID + 5);
-    CHECK_TRUE(appHA.appId[6] == APPID_UT_ID + 6);
-    CHECK_TRUE(appHA.appId[7] == APPID_UT_ID + 7);
-    CHECK_TRUE(appHA.flags == (APPID_HA_FLAGS_APP | APPID_HA_FLAGS_TP_DONE
-        | APPID_HA_FLAGS_SVC_DONE | APPID_HA_FLAGS_HTTP));
-
-    mock_flow_data= nullptr;
-    SfIp ip;
-    ip.pton(AF_INET, "192.168.1.222");
-    val = appid_api.consume_ha_state(*flow, (uint8_t*)&appHA, 0, IpProtocol::TCP, &ip, 1066);
-    CHECK_TRUE(val == sizeof(appHA));
-
-    AppIdSession* session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id);
-    CHECK_TRUE(session);
-    CHECK_TRUE(session->get_tp_app_id() == appHA.appId[0]);
-    CHECK_TRUE(session->get_service_id() == appHA.appId[1]);
-    CHECK_TRUE(session->client_inferred_service_id == appHA.appId[2]);
-    CHECK_TRUE(session->get_port_service_id() == appHA.appId[3]);
-    CHECK_TRUE(session->get_payload_id() == appHA.appId[4]);
-    CHECK_TRUE(session->get_tp_payload_app_id() == appHA.appId[5]);
-    CHECK_TRUE(session->get_client_id() == appHA.appId[6]);
-    CHECK_TRUE(session->misc_app_id == appHA.appId[7]);
-    CHECK_TRUE(session->service_disco_state == APPID_DISCO_STATE_FINISHED);
-    CHECK_TRUE(session->client_disco_state == APPID_DISCO_STATE_FINISHED);
-    delete &session->get_api();
-    delete session;
-
-    // test logic when service app is ftp control
-    appHA.appId[1] = APP_ID_FTP_CONTROL;
-    mock_flow_data= nullptr;
-    val = appid_api.consume_ha_state(*flow, (uint8_t*)&appHA, 0, IpProtocol::TCP, &ip, 1066);
-    CHECK_TRUE(val == sizeof(appHA));
-
-    session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id);
-    CHECK_TRUE(session);
-    uint64_t flags = session->get_session_flags(APPID_SESSION_CLIENT_DETECTED |
-        APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
-    CHECK_TRUE(flags == (APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_NOT_A_SERVICE
-        | APPID_SESSION_SERVICE_DETECTED));
-    CHECK_TRUE(session->get_service_id() == APP_ID_FTP_CONTROL);
-    CHECK_TRUE(session->service_disco_state == APPID_DISCO_STATE_STATEFUL);
-    CHECK_TRUE(session->client_disco_state == APPID_DISCO_STATE_FINISHED);
-    delete &session->get_api();
-    delete session;
-
-    flow->set_flow_data(nullptr);
-    uint32_t val1 = appid_api.produce_ha_state(*flow, (uint8_t*)&appHA);
-    CHECK_TRUE(val1 == sizeof(appHA));
-    CHECK_TRUE(appHA.flags == 0);
-
-    val = appid_api.consume_ha_state(*flow, (uint8_t*)&appHA, 0, IpProtocol::TCP, &ip, 1066);
-    CHECK_TRUE(val == sizeof(appHA));
-    session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id);
-    CHECK(session == nullptr);
-}
-
 TEST(appid_api, ssl_app_group_id_lookup)
 {
     mock().expectNCalls(4, "publish");
index 796680ae7807bdc3da8343be6c3df3030111f258..c046bd0a0949c15e7801ad54946fb6ffe4df9bf3 100644 (file)
@@ -54,6 +54,7 @@ AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
     StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
 }
 
+void FlowHAState::add(uint8_t) { }
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
 const char* AppInfoManager::get_app_name(AppId)
 {
@@ -106,6 +107,7 @@ static AppIdConfig stub_config;
 static AppIdContext stub_ctxt(stub_config);
 static OdpContext stub_odp_ctxt(stub_config, nullptr);
 OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt;
+static Flow flow;
 
 // AppIdSession mock functions
 AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector,
@@ -181,6 +183,7 @@ TEST_GROUP(appid_http_session)
     {
         SfIp sfip;
         session = new AppIdSession(IpProtocol::IP, &sfip, 0, dummy_appid_inspector, stub_odp_ctxt);
+        session->flow = &flow;
         mock_hsession = new AppIdHttpSession(*session, 0);
         appidDebug = new AppIdDebug();
     }
@@ -200,20 +203,20 @@ TEST(appid_http_session, http_field_ids_enum_order)
     // in appid_http_session.h.
     AppidChangeBits change_bits;
 
-    mock_hsession->set_field( (HttpFieldIds)0, new std::string("agent"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)1, new std::string("host"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)3, new std::string("uri"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)4, new std::string("cookie"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)5, new std::string("req_body"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)6, new std::string("content_type"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)7, new std::string("location"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)8, new std::string("rsp_body"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)9, new std::string("via"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)10, new std::string("response_code"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)11, new std::string("server"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)12, new std::string("xww"), change_bits );
-    mock_hsession->set_field( (HttpFieldIds)13, new std::string("url"), change_bits );
+    mock_hsession->set_field( (HttpFieldIds)0, new std::string("agent"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)1, new std::string("host"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)3, new std::string("uri"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)4, new std::string("cookie"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)5, new std::string("req_body"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)6, new std::string("content_type"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)7, new std::string("location"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)8, new std::string("rsp_body"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)9, new std::string("via"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)10, new std::string("response_code"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)11, new std::string("server"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)12, new std::string("xww"), change_bits);
+    mock_hsession->set_field( (HttpFieldIds)13, new std::string("url"), change_bits);
 
     const std::string* field;
     field = mock_hsession->get_field(REQ_AGENT_FID);
@@ -308,7 +311,7 @@ TEST(appid_http_session, change_bits_for_referred_appid)
     session->set_service_id(APP_ID_HTTP, odp_ctxt);
     session->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
     mock_hsession->set_skip_simple_detect(false);
-    mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits );
+    mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits);
     mock_hsession->process_http_packet(APP_ID_FROM_INITIATOR, change_bits, odp_ctxt.get_http_matchers());
 
     // Detect changes in referred appid
index b5cdc4076c3b508573778afe160442b2d0a395b4..eef95e2b795703ef6898d2479b164c9818aa933e 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef APPID_MOCK_SESSION_H
 #define APPID_MOCK_SESSION_H
 
+#include "flow/ha.h"
+
 #include "appid_dns_session.h"
 #include "appid_mock_flow.h"
 #include "appid_mock_http_session.h"
@@ -75,6 +77,8 @@ AppIdConfig::~AppIdConfig() { }
 OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
 OdpContext::~OdpContext() { }
 
+void FlowHAState::add(uint8_t) { }
+
 static AppIdConfig stub_config;
 static AppIdContext stub_ctxt(stub_config);
 static OdpContext stub_odp_ctxt(stub_config, nullptr);
index 23708855b7e301a9d0bdf03e8bca3ab38ecc0ecc..9c86bae12d020db5de4b400b4fa8c685f1f31556 100644 (file)
@@ -34,6 +34,7 @@ AppIdSession* mock_session = nullptr;
 AppIdSessionApi* appid_session_api = nullptr;
 static AppIdConfig config;
 static OdpContext odpctxt(config, nullptr);
+static Flow flow;
 
 void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
 
@@ -53,12 +54,12 @@ namespace snort
 void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id,
     AppId misc_id, AppId referred_id, AppidChangeBits& change_bits)
 {
-    api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits);
+    api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits, *flow);
 }
 
 void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits)
 {
-    api.set_application_ids_service(service_id, change_bits);
+    api.set_application_ids_service(service_id, change_bits, *flow);
 }
 
 TEST_GROUP(appid_session_api)
@@ -69,6 +70,7 @@ TEST_GROUP(appid_session_api)
 
         SfIp ip;
         mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, odpctxt);
+        mock_session->flow = &flow;
         pkt_thread_odp_ctxt = &mock_session->get_odp_ctxt();
         mock_session->set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID,
             APPID_UT_ID, APPID_UT_ID, change_bits);
@@ -131,6 +133,7 @@ TEST(appid_session_api, get_app_id)
 {
     SfIp ip;
     AppIdSession asd(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, odpctxt);
+    asd.flow = &flow;
     AppidChangeBits change_bits;
     asd.set_application_ids_service(APP_ID_HTTP2, change_bits);