]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #706 in SNORT/snort3 from appid_fix_valgrind_issues to master
authorHui Cao (huica) <huica@cisco.com>
Wed, 16 Nov 2016 21:12:00 +0000 (16:12 -0500)
committerHui Cao (huica) <huica@cisco.com>
Wed, 16 Nov 2016 21:12:00 +0000 (16:12 -0500)
Squashed commit of the following:

commit 73e7820760537fa576ec07ce0afdd9d953e93eed
Author: davis mcpherson <davmcphe.cisco.com>
Date:   Wed Nov 16 12:33:42 2016 -0500

    check validity of protocol value in lua api against IpProtocol::RESERVED

commit 7b5c1bb0dededa56807e38b25bdecf953f41c624
Author: davis mcpherson <davmcphe.cisco.com>
Date:   Wed Nov 16 10:25:31 2016 -0500

    memory leak fix where service match objects not deleted when id_state deleted

commit c1fa8a6c82c7e1ad86e47eba6b15b0ea73581b3d
Author: davis mcpherson <davmcphe.cisco.com>
Date:   Wed Nov 16 08:04:51 2016 -0500

    delete host/port and service state maps packet processing thread exits

commit 75caec57317e1a7af368d3cb79539204bdef84f0
Author: davis mcpherson <davis.mcpherson@gmail.com>
Date:   Tue Nov 15 18:05:37 2016 -0500

    refactor service state tables to use std::map

commit f0aab847fcd4fa6f5ac2962da14c92d98fd650a4
Author: davis mcpherson <davis.mcpherson@gmail.com>
Date:   Tue Nov 15 16:06:34 2016 -0500

    refactor host port cache to use std::map

    init session logging id name to null

commit e5bf29005716f4c950247b52021ee9de582fb6d4
Author: davis mcpherson <davmcphe.cisco.com>
Date:   Tue Nov 15 09:28:59 2016 -0500

    when an appid session is deleted ensure all possible allocated resources are checked for and freed

commit f576528b528fa82a905c02f8eaf4d9542e8cccfe
Author: davis mcpherson <davmcphe.cisco.com>
Date:   Thu Nov 10 15:12:33 2016 -0500

    fix memory leaks in appid due to flow data structs not being freed
    fix memory leak due to flow data struct allocated for expected channel not being freed

    fixes for some invalid memory access issues:
     - init all fields in httpSession struct
     - don't scan past end of buffer identifying htpp client
     - insure struct fields and auto vars are initialized

    fixes for some memory access errors due to unitialized variables

30 files changed:
src/framework/decode_data.h
src/hash/sfxhash.cc
src/hash/sfxhash.h
src/network_inspectors/appid/app_info_table.cc
src/network_inspectors/appid/app_info_table.h
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.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_stats.cc
src/network_inspectors/appid/detector_plugins/detector_http.cc
src/network_inspectors/appid/host_port_app_cache.cc
src/network_inspectors/appid/host_port_app_cache.h
src/network_inspectors/appid/length_app_cache.cc
src/network_inspectors/appid/length_app_cache.h
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/lua_detector_flow_api.cc
src/network_inspectors/appid/service_plugins/service_base.cc
src/network_inspectors/appid/service_plugins/service_base.h
src/network_inspectors/appid/service_plugins/service_ftp.cc
src/network_inspectors/appid/service_plugins/service_rexec.cc
src/network_inspectors/appid/service_plugins/service_rpc.cc
src/network_inspectors/appid/service_plugins/service_rshell.cc
src/network_inspectors/appid/service_plugins/service_snmp.cc
src/network_inspectors/appid/service_plugins/service_ssl.cc
src/network_inspectors/appid/service_plugins/service_tftp.cc
src/network_inspectors/appid/service_state.cc
src/network_inspectors/appid/service_state.h
src/protocols/ip.cc

index 64913cd26f39141bc0e0718b0ec092b399f1e1e2..ab8f0b332b16799559cf136afe07f97d7c679459 100644 (file)
@@ -131,6 +131,8 @@ struct DecodeData
     {
         memset(this, 0, offsetof(DecodeData, ip_api));
         ip_api.reset();
+        sp = 0;
+        dp = 0;
     }
 
     inline void set_pkt_type(PktType pkt_type)
index 6f8b5a1a4a6ad4c7d639bb11d5a4c46a43ca34b6..683811dcf4839273be16965601f56c6c6fdbf270 100644 (file)
@@ -135,10 +135,8 @@ void sfxhash_free(SFXHASH* t, void* p)
 
 static int sfxhash_nearest_powerof2(int nrows)
 {
-    unsigned i;
-
     nrows -= 1;
-    for (i=1; i<sizeof(nrows) * 8; i <<= 1)
+    for (unsigned i=1; i<sizeof(nrows) * 8; i <<= 1)
         nrows = nrows | (nrows >> i);
     nrows += 1;
 
@@ -181,9 +179,6 @@ SFXHASH* sfxhash_new(int nrows, int keysize, int datasize, unsigned long maxmem,
     SFXHASH_FREE_FCN usrfree,
     int recycle_flag)
 {
-    int i;
-    SFXHASH* h;
-
     if ( nrows > 0 ) /* make sure we have a prime number */
     {
         /* If nrows is not a power of two, need to find the
@@ -196,7 +191,7 @@ SFXHASH* sfxhash_new(int nrows, int keysize, int datasize, unsigned long maxmem,
     }
 
     /* Allocate the table structure from general memory */
-    h = (SFXHASH*)snort_calloc(sizeof(SFXHASH));
+    SFXHASH* h = (SFXHASH*)snort_calloc(sizeof(SFXHASH));
 
     /* this has a default hashing function */
     h->sfhashfcn = sfhashfcn_new(nrows);
@@ -212,10 +207,8 @@ SFXHASH* sfxhash_new(int nrows, int keysize, int datasize, unsigned long maxmem,
         return 0;
     }
 
-    for ( i=0; i<nrows; i++ )
-    {
-        h->table[i] = 0;
-    }
+    for ( int i = 0; i < nrows; i++ )
+        h->table[i] = nullptr;
 
     h->anrfree  = anrfree;
     h->usrfree  = usrfree;
@@ -285,23 +278,19 @@ void sfxhash_splaymode(SFXHASH* t, int n)
  */
 static void sfxhash_delete_free_list(SFXHASH* t)
 {
-    SFXHASH_NODE* cur = NULL;
-    SFXHASH_NODE* next = NULL;
-
-    if (t == NULL || t->fhead == NULL)
+    if (t == nullptr || t->fhead == nullptr)
         return;
 
-    cur = t->fhead;
-
-    while (cur != NULL)
+    SFXHASH_NODE* cur = t->fhead;
+    while (cur != nullptr)
     {
-        next = cur->gnext;
+        SFXHASH_NODE* next = cur->gnext;
         s_free(t, (void*)cur);
         cur = next;
     }
 
-    t->fhead = NULL;
-    t->ftail = NULL;
+    t->fhead = nullptr;
+    t->ftail = nullptr;
 }
 
 /*!
@@ -314,9 +303,6 @@ static void sfxhash_delete_free_list(SFXHASH* t)
  */
 void sfxhash_delete(SFXHASH* h)
 {
-    unsigned i;
-    SFXHASH_NODE* node, * onode;
-
     if ( !h )
         return;
 
@@ -325,22 +311,22 @@ void sfxhash_delete(SFXHASH* h)
 
     if ( h->table )
     {
-        for (i=0; i<h->nrows; i++)
+        for (unsigned i = 0; i < h->nrows; i++)
         {
-            for ( node=h->table[i]; node; )
+            for ( SFXHASH_NODE* node = h->table[i]; node; )
             {
-                onode = node;
+                SFXHASH_NODE* onode = node;
                 node  = node->next;
 
                 /* Notify user that we are about to free this node function */
                 if ( h->usrfree )
                     h->usrfree(onode->key, onode->data);
 
-                s_free(h,onode);
+                s_free(h, onode);
             }
         }
         s_free(h, h->table);
-        h->table = 0;
+        h->table = nullptr;
     }
 
     sfxhash_delete_free_list(h);
@@ -357,16 +343,14 @@ void sfxhash_delete(SFXHASH* h)
  */
 int sfxhash_make_empty(SFXHASH* h)
 {
-    SFXHASH_NODE* n = NULL;
-    SFXHASH_NODE* tmp = NULL;
-    unsigned i;
+    SFXHASH_NODE* tmp = nullptr;
 
-    if (h == NULL)
+    if (h == nullptr)
         return -1;
 
-    for (i = 0; i < h->nrows; i++)
+    for (unsigned i = 0; i < h->nrows; i++)
     {
-        for (n = h->table[i]; n != NULL; n = tmp)
+        for (SFXHASH_NODE* n = h->table[i]; n != nullptr; n = tmp)
         {
             tmp = n->next;
             if (sfxhash_free_node(h, n) != SFXHASH_OK)
@@ -378,10 +362,10 @@ int sfxhash_make_empty(SFXHASH* h)
 
     h->max_nodes = 0;
     h->crow = 0;
-    h->cnode = NULL;
+    h->cnode = nullptr;
     h->count = 0;
-    h->ghead = NULL;
-    h->gtail = NULL;
+    h->ghead = nullptr;
+    h->gtail = nullptr;
     h->anr_count = 0;
     h->anr_tries = 0;
     h->find_success = 0;
@@ -558,10 +542,8 @@ static void movetofront(SFXHASH* t, SFXHASH_NODE* n)
  */
 static SFXHASH_NODE* sfxhash_newnode(SFXHASH* t)
 {
-    SFXHASH_NODE* hnode;
-
     /* Recycle Old Nodes - if any */
-    hnode = sfxhash_get_free_node(t);
+    SFXHASH_NODE* hnode = sfxhash_get_free_node(t);
 
     /* Allocate memory for a node */
     if ( !hnode )
@@ -606,14 +588,14 @@ static SFXHASH_NODE* sfxhash_newnode(SFXHASH* t)
     }
 
     /* either we are returning a node or we're all full and the user
-     * won't let us allocate anymore and we return NULL */
+     * won't let us allocate anymore and we return nullptr */
     return hnode;
 }
 
 /*
  *
  *  Find a Node based on the key, return the node and the index.
- *  The index is valid even if the return value is NULL, in which
+ *  The index is valid even if the return value is nullptr, in which
  *  case the index is the corect row in which the node should be
  *  created.
  *
@@ -624,13 +606,7 @@ static SFXHASH_NODE* sfxhash_newnode(SFXHASH* t)
 
 static SFXHASH_NODE* sfxhash_find_node_row(SFXHASH* t, const void* key, int* rindex)
 {
-    unsigned hashkey;
-    int index;
-    SFXHASH_NODE* hnode;
-
-    hashkey = t->sfhashfcn->hash_fcn(t->sfhashfcn,
-        (unsigned char*)key,
-        t->keysize);
+    unsigned hashkey = t->sfhashfcn->hash_fcn(t->sfhashfcn, (unsigned char*)key, t->keysize);
 
 /*     printf("hashkey: %u t->keysize: %d\n", hashkey, t->keysize);
        flowkey_fprint(stdout, key);
@@ -638,16 +614,15 @@ static SFXHASH_NODE* sfxhash_find_node_row(SFXHASH* t, const void* key, int* rin
 
 //     index   = hashkey % t->nrows;
     /* Modulus is slow. Switched to a table size that is a power of 2. */
-    index  = hashkey & (t->nrows - 1);
-
+    int index  = hashkey & (t->nrows - 1);
     *rindex = index;
 
-    for ( hnode=t->table[index]; hnode; hnode=hnode->next )
+    for (SFXHASH_NODE* hnode = t->table[index]; hnode; hnode = hnode->next )
     {
-        if ( !t->sfhashfcn->keycmp_fcn(hnode->key,key,t->keysize) )
+        if ( !t->sfhashfcn->keycmp_fcn(hnode->key, key, t->keysize) )
         {
             if ( t->splay > 0 )
-                movetofront(t,hnode);
+                movetofront(t, hnode);
 
             t->find_success++;
             return hnode;
@@ -655,7 +630,7 @@ static SFXHASH_NODE* sfxhash_find_node_row(SFXHASH* t, const void* key, int* rin
     }
 
     t->find_fail++;
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -678,12 +653,10 @@ static SFXHASH_NODE* sfxhash_find_node_row(SFXHASH* t, const void* key, int* rin
  */
 static int sfxhash_add_ex(SFXHASH* t, const void* key, void* data, void** data_ptr)
 {
-    int index;
-    SFXHASH_NODE* hnode;
+    int index = 0;
 
     /* Enforce uniqueness: Check for the key in the table */
-    hnode = sfxhash_find_node_row(t, key, &index);
-
+    SFXHASH_NODE* hnode = sfxhash_find_node_row(t, key, &index);
     if ( hnode )
     {
         t->cnode = hnode;
@@ -742,7 +715,7 @@ static int sfxhash_add_ex(SFXHASH* t, const void* key, void* data, void** data_p
 
 int sfxhash_add(SFXHASH* t, void* key, void* data)
 {
-    return sfxhash_add_ex(t, key, data, NULL);
+    return sfxhash_add_ex(t, key, data, nullptr);
 }
 
 /*!
@@ -764,12 +737,11 @@ int sfxhash_add(SFXHASH* t, void* key, void* data)
  */
 SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key)
 {
-    int index;
-    SFXHASH_NODE* hnode;
+    int index = 0;
+    SFXHASH_NODE* hnode = nullptr;
 
     /* Enforce uniqueness: Check for the key in the table */
     hnode = sfxhash_find_node_row(t, key, &index);
-
     if ( hnode )
     {
         t->cnode = hnode;
@@ -783,7 +755,7 @@ SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key)
     hnode = sfxhash_newnode(t);
     if ( !hnode )
     {
-        return NULL;
+        return nullptr;
     }
 
     /* Set up the new key pointer */
@@ -803,7 +775,7 @@ SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key)
     }
     else
     {
-        hnode->data = NULL;
+        hnode->data = nullptr;
     }
 
     /* Link the node into the table row list */
@@ -830,7 +802,7 @@ SFXHASH_NODE* sfxhash_get_node(SFXHASH* t, const void* key)
  */
 SFXHASH_NODE* sfxhash_find_node(SFXHASH* t, const void* key)
 {
-    int rindex;
+    int rindex = 0;
 
     return sfxhash_find_node_row(t, key, &rindex);
 }
@@ -847,15 +819,12 @@ SFXHASH_NODE* sfxhash_find_node(SFXHASH* t, const void* key)
  */
 void* sfxhash_find(SFXHASH* t, void* key)
 {
-    SFXHASH_NODE* hnode;
-    int rindex;
-
-    hnode = sfxhash_find_node_row(t, key, &rindex);
-
+    int rindex = 0;
+    SFXHASH_NODE* hnode = sfxhash_find_node_row(t, key, &rindex);
     if ( hnode )
         return hnode->data;
 
-    return NULL;
+    return nullptr;
 }
 
 /**
@@ -863,7 +832,7 @@ void* sfxhash_find(SFXHASH* t, void* key)
  *
  * t table pointer
  *
- * return the head of the list or NULL
+ * return the head of the list or nullptr
  */
 SFXHASH_NODE* sfxhash_ghead(SFXHASH* t)
 {
@@ -872,7 +841,7 @@ SFXHASH_NODE* sfxhash_ghead(SFXHASH* t)
         return t->ghead;
     }
 
-    return NULL;
+    return nullptr;
 }
 
 /**
@@ -880,7 +849,7 @@ SFXHASH_NODE* sfxhash_ghead(SFXHASH* t)
  *
  * n current node
  *
- * return the next node in the list or NULL when at the end
+ * return the next node in the list or nullptr when at the end
  */
 SFXHASH_NODE* sfxhash_gnext(SFXHASH_NODE* n)
 {
@@ -889,7 +858,7 @@ SFXHASH_NODE* sfxhash_gnext(SFXHASH_NODE* n)
         return n->gnext;
     }
 
-    return NULL;
+    return nullptr;
 }
 
 /**
@@ -897,13 +866,11 @@ SFXHASH_NODE* sfxhash_gnext(SFXHASH_NODE* n)
  *
  * n current node
  *
- * return the next node in the list or NULL when at the end
+ * return the next node in the list or nullptr when at the end
  */
 SFXHASH_NODE* sfxhash_gfindnext(SFXHASH* t)
 {
-    SFXHASH_NODE* n;
-
-    n = t->gnode;
+    SFXHASH_NODE* n = t->gnode;
     if (n)
         t->gnode = n->gnext;
     return n;
@@ -914,7 +881,7 @@ SFXHASH_NODE* sfxhash_gfindnext(SFXHASH* t)
  *
  * t table pointer
  *
- * return the head of the list or NULL
+ * return the head of the list or nullptr
  */
 SFXHASH_NODE* sfxhash_gfindfirst(SFXHASH* t)
 {
@@ -923,10 +890,10 @@ SFXHASH_NODE* sfxhash_gfindfirst(SFXHASH* t)
         if (t->ghead)
             t->gnode = t->ghead->gnext;
         else
-            t->gnode = NULL;
+            t->gnode = nullptr;
         return t->ghead;
     }
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -940,14 +907,11 @@ SFXHASH_NODE* sfxhash_gfindfirst(SFXHASH* t)
  */
 void* sfxhash_mru(SFXHASH* t)
 {
-    SFXHASH_NODE* hnode;
-
-    hnode = sfxhash_ghead(t);
-
+    SFXHASH_NODE* hnode = sfxhash_ghead(t);
     if ( hnode )
         return hnode->data;
 
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -961,14 +925,11 @@ void* sfxhash_mru(SFXHASH* t)
  */
 void* sfxhash_lru(SFXHASH* t)
 {
-    SFXHASH_NODE* hnode;
-
-    hnode = t->gtail;
-
+    SFXHASH_NODE* hnode = t->gtail;
     if ( hnode )
         return hnode->data;
 
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -982,14 +943,11 @@ void* sfxhash_lru(SFXHASH* t)
  */
 SFXHASH_NODE* sfxhash_mru_node(SFXHASH* t)
 {
-    SFXHASH_NODE* hnode;
-
-    hnode = sfxhash_ghead(t);
-
+    SFXHASH_NODE* hnode = sfxhash_ghead(t);
     if ( hnode )
         return hnode;
 
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -1003,14 +961,11 @@ SFXHASH_NODE* sfxhash_mru_node(SFXHASH* t)
  */
 SFXHASH_NODE* sfxhash_lru_node(SFXHASH* t)
 {
-    SFXHASH_NODE* hnode;
-
-    hnode = t->gtail;
-
+    SFXHASH_NODE* hnode = t->gtail;
     if ( hnode )
         return hnode;
 
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -1025,16 +980,15 @@ SFXHASH_NODE* sfxhash_lru_node(SFXHASH* t)
  */
 unsigned sfxhash_maxdepth(SFXHASH* t)
 {
-    unsigned i;
     unsigned max_depth = 0;
 
     SFXHASH_NODE* hnode;
 
-    for ( i=0; i<t->nrows; i++ )
+    for ( unsigned i = 0; i < t->nrows; i++ )
     {
         unsigned cur_depth = 0;
 
-        for (hnode = t->table[i]; hnode != NULL; hnode = hnode->next)
+        for (hnode = t->table[i]; hnode != nullptr; hnode = hnode->next)
         {
             cur_depth++;
         }
@@ -1086,20 +1040,15 @@ int sfxhash_free_node(SFXHASH* t, SFXHASH_NODE* hnode)
  */
 int sfxhash_remove(SFXHASH* t, void* key)
 {
-    SFXHASH_NODE* hnode;
-    unsigned hashkey, index;
-
-    hashkey = t->sfhashfcn->hash_fcn(t->sfhashfcn,
-        (unsigned char*)key,
-        t->keysize);
+    unsigned hashkey = t->sfhashfcn->hash_fcn(t->sfhashfcn, (unsigned char*)key, t->keysize);
 
 //    index = hashkey % t->nrows;
     /* Modulus is slow */
-    index   = hashkey & (t->nrows - 1);
+    unsigned index   = hashkey & (t->nrows - 1);
 
-    for ( hnode=t->table[index]; hnode; hnode=hnode->next )
+    for ( SFXHASH_NODE* hnode = t->table[index]; hnode; hnode = hnode->next )
     {
-        if ( !t->sfhashfcn->keycmp_fcn(hnode->key,key,t->keysize) )
+        if ( !t->sfhashfcn->keycmp_fcn(hnode->key, key, t->keysize) )
         {
             return sfxhash_free_node(t, hnode);
         }
@@ -1146,25 +1095,23 @@ static void sfxhash_next(SFXHASH* t)
  */
 SFXHASH_NODE* sfxhash_findfirst(SFXHASH* t)
 {
-    SFXHASH_NODE* n;
-
     if (!t)
-        return NULL;
+        return nullptr;
 
     /* Start with 1st row */
-    for ( t->crow=0; t->crow < t->nrows; t->crow++ )
+    for ( t->crow = 0; t->crow < t->nrows; t->crow++ )
     {
         /* Get 1st Non-Null node in row list */
         t->cnode = t->table[ t->crow ];
         if ( t->cnode )
         {
-            n = t->cnode;
+            SFXHASH_NODE* n = t->cnode;
             sfxhash_next(t);   // load t->cnode with the next entry
             return n;
         }
     }
 
-    return NULL;
+    return nullptr;
 }
 
 /*!
@@ -1178,12 +1125,10 @@ SFXHASH_NODE* sfxhash_findfirst(SFXHASH* t)
  */
 SFXHASH_NODE* sfxhash_findnext(SFXHASH* t)
 {
-    SFXHASH_NODE* n;
-
-    n = t->cnode;
+    SFXHASH_NODE* n = t->cnode;
     if ( !n ) /* Done, no more entries */
     {
-        return NULL;
+        return nullptr;
     }
 
     /*
@@ -1219,9 +1164,9 @@ int sfxhash_add_return_data_ptr(SFXHASH* t, const void* key, void** data)
     if ( !t->datasize )
         return SFXHASH_ERR;
 
-    *data = NULL;
+    *data = nullptr;
 
-    return sfxhash_add_ex(t, key, NULL, data);
+    return sfxhash_add_ex(t, key, nullptr, data);
 }
 
 /*
index ec55c7d2d44ccea805c7cf9f4e58b36ef3850b00..7abfe8cf08b03e31d09e168cccd63d45c99779b4 100644 (file)
@@ -41,8 +41,10 @@ struct SFHASHFCN;
 
 struct SFXHASH_NODE
 {
-    struct SFXHASH_NODE* gnext, * gprev; // global node list - used for ageing nodes
-    struct SFXHASH_NODE* next,  * prev;  // row node list
+    struct SFXHASH_NODE* gnext; // global node list - used for ageing nodes
+    struct SFXHASH_NODE* gprev;
+    struct SFXHASH_NODE* next;  // row node list
+    struct SFXHASH_NODE* prev;
 
     int rindex;  // row index of table this node belongs to.
 
@@ -75,7 +77,6 @@ struct SFXHASH
     unsigned find_success;
 
     SFXHASH_NODE* ghead, * gtail;  // global - root of all nodes allocated in table
-
     SFXHASH_NODE* fhead, * ftail;  // list of free nodes, which are recyled
     SFXHASH_NODE* gnode;           // gfirst/gnext node ptr */
     int recycle_nodes;             // recycle nodes. Nodes are not freed, but are used for
index 916aa5dfa2e39132f58aee90de757a1362231a03..ae9af3d01342690aec6b56905deb3b833ab8081b 100644 (file)
@@ -217,7 +217,7 @@ void AppInfoManager::set_app_info_active(AppId appId)
     if (entry)
         entry->flags |= APPINFO_FLAG_ACTIVE;
     else
-        ErrorMessage("AppInfo: AppId %d has no entry in application info table\n", appId);
+        WarningMessage("AppInfo: AppId %d has no entry in application info table\n", appId);
 }
 
 void AppInfoManager::load_appid_config(const char* path)
index 3e8d9d73e759433b40c197060aa2f2ade6dab03a..de1bba309d7d3c194620049c16721e390dc46613 100644 (file)
@@ -23,7 +23,7 @@
 #define APP_INFO_TABLE_H
 
 #include <cstdint>
-#include <map>
+#include <unordered_map>
 #include <mutex>
 
 #include "application_ids.h"
@@ -90,8 +90,8 @@ public:
     char* app_name_key = nullptr;
 };
 
-typedef std::map<AppId, AppInfoTableEntry*> AppInfoTable;
-typedef std::map<std::string, AppInfoTableEntry*> AppInfoNameTable;
+typedef std::unordered_map<AppId, AppInfoTableEntry*> AppInfoTable;
+typedef std::unordered_map<std::string, AppInfoTableEntry*> AppInfoNameTable;
 
 class AppInfoManager
 {
index c2821a64b3441ca8c452aee1f4bd566b6a68719f..6bc0ab315da4a2d082fdf1d70d902f9c8538f0f6 100644 (file)
@@ -49,6 +49,12 @@ struct PortList
 
 static THREAD_LOCAL SF_LIST appid_custom_configs;
 
+AppIdModuleConfig::AppIdModuleConfig()
+{
+    session_log_filter.sip.clear();
+    session_log_filter.dip.clear();
+}
+
 AppIdModuleConfig::~AppIdModuleConfig()
 {
     snort_free((void*)conf_file);
index 1d51b78f1ef118376798b4276c8db062fd3fbb6d..ab015ecc934e83d4f03e9086f53b607bb72bd36a 100644 (file)
@@ -79,7 +79,7 @@ struct AppIdSessionLogFilter
 class AppIdModuleConfig
 {
 public:
-    AppIdModuleConfig() { }
+    AppIdModuleConfig();
     ~AppIdModuleConfig();
 
     const char* conf_file = nullptr;
index 34231978ca7fbdc4285bf701994af500321a90dc..fe5631d87fc2440111827b193cb5b7faea673fd3 100644 (file)
@@ -53,7 +53,7 @@ static void dump_appid_stats()
     if (thirdparty_appid_module)
         thirdparty_appid_module->print_stats();
     LogMessage("    Total packets ignored : %" PRIu64 "\n", appid_stats.ignored_packets);
-    dump_service_state_stats();
+    AppIdServiceState::dump_stats();
 }
 
 AppIdInspector::AppIdInspector(const AppIdModuleConfig* pc)
@@ -107,7 +107,7 @@ void AppIdInspector::show(SnortConfig*)
 void AppIdInspector::tinit()
 {
     init_appid_statistics(*config);
-    hostPortAppCacheInit();
+    HostPortCache::initialize();
     init_appid_forecast();
     init_http_detector();
     init_service_plugins();
@@ -124,16 +124,14 @@ void AppIdInspector::tinit()
     finalize_sip_ua();
     ssl_detector_process_patterns();
     dns_host_detector_process_patterns();
-
-    if (init_service_state(config->memcap))
-        exit(-1);
+       AppIdServiceState::initialize(config->memcap);
 }
 
 void AppIdInspector::tterm()
 {
     cleanup_appid_statistics();
 
-    hostPortAppCacheFini();
+    HostPortCache::terminate();
     clean_appid_forecast();
     service_dns_host_clean();
     service_ssl_clean();
@@ -145,7 +143,7 @@ void AppIdInspector::tterm()
 
     AppIdSession::release_free_list_flow_data();
     LuaDetectorManager::terminate();
-    clean_service_state();
+    AppIdServiceState::clean();
 }
 
 void AppIdInspector::eval(Packet* pkt)
index 104c188f55152d3607695973e91b09f11ac2031d..acc212bc6c5c0783c93125696ced9e087c3f0c57 100644 (file)
@@ -141,10 +141,9 @@ void AppIdSession::set_session_logging_state(const Packet* pkt, int direction)
 
 AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto, int direction)
 {
-    const sfip_t* ip;
     uint16_t port = 0;
 
-    ip = (direction == APP_ID_FROM_INITIATOR)
+    const sfip_t* ip = (direction == APP_ID_FROM_INITIATOR)
         ? p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
     if ( ( proto == IpProtocol::TCP || proto == IpProtocol::UDP ) && ( p->ptrs.sp != p->ptrs.dp ) )
         port = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp;
@@ -172,12 +171,25 @@ AppIdSession::AppIdSession(IpProtocol proto, const sfip_t* ip, uint16_t port)
     if (thirdparty_appid_module)
         if (!(tpsession = thirdparty_appid_module->session_create()))
             ErrorMessage("Could not allocate third party session data");
+
+    length_sequence.proto = IpProtocol::PROTO_NOT_SET;
+    length_sequence.sequence_cnt = 0;
+    memset(length_sequence.sequence, '\0', sizeof(length_sequence.sequence));
+    session_logging_id[0] = '\0';
 }
 
 AppIdSession::~AppIdSession()
 {
        if( !in_expected_cache)
-               delete_shared_data();
+       {
+           update_appid_statistics(this);
+           if (flow)
+               FailInProcessService(this, config);
+       }
+
+       delete_shared_data();
+
+    free_flow_data();
 }
 
 // FIXIT-L X Move this to somewhere more generally available/appropriate.
@@ -1236,7 +1248,7 @@ void AppIdSession::pickHttpXffAddress(Packet*, ThirdPartyAppIDAttributeData* att
 bool AppIdSession::do_service_discovery(IpProtocol protocol, int direction, AppId client_app_id,
         AppId payload_app_id, Packet* p)
 {
-    AppInfoTableEntry* entry;
+    AppInfoTableEntry* entry = nullptr;
     bool isTpAppidDiscoveryDone = false;
 
     if (rnaServiceState != RNA_STATE_FINISHED)
@@ -1466,14 +1478,12 @@ bool AppIdSession::do_client_discovery(int direction, Packet* p)
 
 void AppIdSession::do_application_discovery(Packet* p)
 {
-    IpProtocol protocol;
+    IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
     AppId client_app_id = 0;
     AppId payload_app_id = 0;
     bool isTpAppidDiscoveryDone = false;
-    uint64_t flow_flags;
-    int direction;
-    const sfip_t* ip;
-    uint16_t port;
+    int direction = 0;
+    const sfip_t* ip = nullptr;
 
     if( is_packet_ignored(p) )
         return;
@@ -1519,7 +1529,7 @@ void AppIdSession::do_application_discovery(Packet* p)
         direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
     }
 
-    flow_flags = AppIdSession::is_session_monitored(p, direction, asd);
+    uint64_t flow_flags = AppIdSession::is_session_monitored(p, direction, asd);
     if (!(flow_flags & (APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED)))
     {
         if (!asd)
@@ -1594,11 +1604,10 @@ void AppIdSession::do_application_discovery(Packet* p)
 
     else if ( p->is_tcp() && p->ptrs.tcph )
     {
+        uint16_t port = 0;
         const auto* tcph = p->ptrs.tcph;
         if ( tcph->is_rst() && asd->previous_tcp_flags == TH_SYN )
         {
-            AppIdServiceIDState* id_state;
-
             asd->set_session_flags(APPID_SESSION_SYN_RST);
             if (sfip_is_set(&asd->service_ip))
             {
@@ -1611,7 +1620,7 @@ void AppIdSession::do_application_discovery(Packet* p)
                 port = p->ptrs.sp;
             }
 
-            id_state = get_service_id_state(ip, IpProtocol::TCP, port,
+            AppIdServiceIDState* id_state = AppIdServiceState::get(ip, IpProtocol::TCP, port,
                 AppIdServiceDetectionLevel(asd));
 
             if (id_state)
@@ -1620,7 +1629,7 @@ void AppIdSession::do_application_discovery(Packet* p)
                     id_state->reset_time = packet_time();
                 else if ((packet_time() - id_state->reset_time) >= 60)
                 {
-                    remove_service_id_state(ip, IpProtocol::TCP, port,
+                    AppIdServiceState::remove(ip, IpProtocol::TCP, port,
                             AppIdServiceDetectionLevel(asd));
                     asd->set_session_flags(APPID_SESSION_SERVICE_DELETED);
                 }
@@ -1633,7 +1642,8 @@ void AppIdSession::do_application_discovery(Packet* p)
     /*HostPort based AppId.  */
     if (!(asd->scan_flags & SCAN_HOST_PORT_FLAG))
     {
-        HostPortVal* hv;
+        HostPortVal* hv = nullptr;
+        uint16_t port = 0;
 
         asd->scan_flags |= SCAN_HOST_PORT_FLAG;
         if (direction == APP_ID_FROM_INITIATOR)
@@ -1647,7 +1657,7 @@ void AppIdSession::do_application_discovery(Packet* p)
             port = p->ptrs.sp;
         }
 
-        if ((hv = hostPortAppCacheFind(ip, port, protocol)))
+        if ((hv = HostPortCache::find(ip, port, protocol)))
         {
             switch (hv->type)
             {
@@ -1877,7 +1887,6 @@ static inline int check_port_exclusion(const Packet* pkt, bool reversed)
     SF_LIST* pe_list;
     PortExclusion* pe;
     const sfip_t* s_ip;
-    uint16_t port;
     AppIdConfig* config = AppIdConfig::get_appid_config();
 
     if ( pkt->is_tcp() )
@@ -1894,7 +1903,7 @@ static inline int check_port_exclusion(const Packet* pkt, bool reversed)
         return 0;
 
     /* check the source port */
-    port = reversed ? pkt->ptrs.dp : pkt->ptrs.sp;
+    uint16_t port = reversed ? pkt->ptrs.dp : pkt->ptrs.sp;
     if ( port && (pe_list = src_port_exclusions[port]) != nullptr )
     {
         s_ip = reversed ? pkt->ptrs.ip_api.get_dst() : pkt->ptrs.ip_api.get_src();
@@ -1999,7 +2008,7 @@ bool AppIdSession::is_ssl_decryption_enabled()
 
 uint64_t AppIdSession::is_session_monitored(const Packet* p, int dir, AppIdSession* asd)
 {
-    uint64_t flags;
+    uint64_t flags = 0;
     uint64_t flow_flags = APPID_SESSION_DISCOVER_APP;
 
     flow_flags |= (dir == APP_ID_FROM_INITIATOR) ?
@@ -2711,22 +2720,15 @@ void AppIdSession::free_flow_data()
         flowData = tmp_fd->next;
         if (tmp_fd->fd_data && tmp_fd->fd_free)
             tmp_fd->fd_free(tmp_fd->fd_data);
-        tmp_fd->next = fd_free_list;
-        fd_free_list = tmp_fd;
+
+        snort_free( tmp_fd );
+        //tmp_fd->next = fd_free_list;
+        //fd_free_list = tmp_fd;
     }
 }
 
 void AppIdSession::delete_shared_data()
 {
-    RNAServiceSubtype* rna_service_subtype;
-
-    /*check daq flag */
-    update_appid_statistics(this);
-
-    if (flow)
-        FailInProcessService(this, config);
-    free_flow_data();
-
     if (thirdparty_appid_module)
     {
         thirdparty_appid_module->session_delete(tpsession, 0);
@@ -2737,14 +2739,18 @@ void AppIdSession::delete_shared_data()
     snort_free(serviceVendor);
     snort_free(serviceVersion);
     snort_free(netbios_name);
-    while ((rna_service_subtype = subtype))
+
+    RNAServiceSubtype* rna_ss = subtype;
+    while ( rna_ss )
     {
-        subtype = rna_service_subtype->next;
-        snort_free(*(void**)&rna_service_subtype->service);
-        snort_free(*(void**)&rna_service_subtype->vendor);
-        snort_free(*(void**)&rna_service_subtype->version);
-        snort_free(rna_service_subtype);
+        subtype = rna_ss->next;
+        snort_free(*(void**)&rna_ss->service);
+        snort_free(*(void**)&rna_ss->vendor);
+        snort_free(*(void**)&rna_ss->version);
+        snort_free(rna_ss);
+        rna_ss = subtype;
     }
+
     if (candidate_service_list)
     {
         sflist_free(candidate_service_list);
@@ -2812,6 +2818,7 @@ void AppIdSession::free_flow_data_by_id(unsigned id)
 
     for (pfd = &flowData; *pfd && (*pfd)->fd_id != id; pfd = &(*pfd)->next)
         ;
+
     if ((fd = *pfd))
     {
         *pfd = fd->next;
index 4eaa07d109b33d3c28544f096cf12212a27b6744..bd7587362c344e644047ac6bba0e9628f002a60c 100644 (file)
@@ -103,20 +103,25 @@ enum APPID_SESSION_DIRECTION
 
 struct AppIdFlowData
 {
-    AppIdFlowData* next;
-    unsigned fd_id;
-    void* fd_data;
-    AppIdFreeFCN fd_free;
+    AppIdFlowData* next = nullptr;
+    unsigned fd_id = 0;
+    void* fd_data = nullptr;
+    AppIdFreeFCN fd_free = nullptr;
 };
 
 struct CommonAppIdData
 {
-    APPID_FLOW_TYPE flow_type;
-    unsigned policyId;
+    CommonAppIdData()
+    {
+        initiator_ip.clear();
+    }
+
+    APPID_FLOW_TYPE flow_type = APPID_FLOW_TYPE_IGNORE;
+    unsigned policyId = 0;
     //flags shared with other preprocessor via session attributes.
-    uint64_t flags;
+    uint64_t flags = 0;
     sfip_t initiator_ip;
-    uint16_t initiator_port;
+    uint16_t initiator_port = 0;
 };
 
 #define SCAN_HTTP_VIA_FLAG          (1<<0)
@@ -130,95 +135,96 @@ struct CommonAppIdData
 
 struct fflow_info
 {
-    uint32_t sip;
-    uint32_t dip;
-    uint16_t sport;
-    uint16_t dport;
-    IpProtocol protocol;
-    AppId appId;
-    int flow_prepared;
+    uint32_t sip = 0;
+    uint32_t dip = 0;
+    uint16_t sport = 0;
+    uint16_t dport = 0;
+    IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
+    AppId appId = APP_ID_NONE;
+    int flow_prepared = 0;
 };
 
 #define RESPONSE_CODE_PACKET_THRESHHOLD 0
 
 struct httpSession
 {
-    char* host;
-    uint16_t host_buflen;
-    char* url;
-    char* uri;
-    uint16_t uri_buflen;
-    char* via;
-    char* useragent;
-    uint16_t useragent_buflen;
-    char* response_code;
-    uint16_t response_code_buflen;
-    char* referer;
-    uint16_t referer_buflen;
-    char* cookie;
-    uint16_t cookie_buflen;
-    char* content_type;
-    uint16_t content_type_buflen;
-    char* location;
-    uint16_t location_buflen;
-    char* body;
-    uint16_t body_buflen;
-    char* req_body;
-    uint16_t req_body_buflen;
-    char* server;
-    char* x_working_with;
-    char* new_field[HTTP_FIELD_MAX+1];
-    uint16_t new_field_len[HTTP_FIELD_MAX+1];
-    uint16_t fieldOffset[HTTP_FIELD_MAX+1];
-    uint16_t fieldEndOffset[HTTP_FIELD_MAX+1];
-    fflow_info* fflow;
-    bool new_field_contents;
-    int chp_finished;
-    AppId chp_candidate;
-    AppId chp_alt_candidate;
-    int chp_hold_flow;
-    int ptype_req_counts[NUMBER_OF_PTYPES];
-    int total_found;
-    unsigned app_type_flags;
-    int num_matches;
-    int num_scans;
-    int get_offsets_from_rebuilt;
-    bool skip_simple_detect;
-    sfip_t* xffAddr;
-    const char** xffPrecedence;
-    int numXffFields;
+    char* host = nullptr;
+    uint16_t host_buflen = 0;
+    char* url = nullptr;
+    char* uri = nullptr;
+    uint16_t uri_buflen = 0;
+    char* via = nullptr;
+    char* useragent = nullptr;
+    uint16_t useragent_buflen = 0;
+    char* response_code = nullptr;
+    uint16_t response_code_buflen = 0;
+    char* referer = nullptr;
+    uint16_t referer_buflen = 0;
+    char* cookie = nullptr;
+    uint16_t cookie_buflen = 0;
+    char* content_type = nullptr;
+    uint16_t content_type_buflen = 0;
+    char* location = nullptr;
+    uint16_t location_buflen = 0;
+    char* body = nullptr;
+    uint16_t body_buflen = 0;
+    char* req_body = nullptr;
+    uint16_t req_body_buflen = 0;
+    char* server = nullptr;
+    char* x_working_with = nullptr;
+    char* new_field[HTTP_FIELD_MAX+1] = { nullptr };
+    uint16_t new_field_len[HTTP_FIELD_MAX+1] = { 0 };
+    uint16_t fieldOffset[HTTP_FIELD_MAX+1] = { 0 };
+    uint16_t fieldEndOffset[HTTP_FIELD_MAX+1] = { 0 };
+    fflow_info* fflow = nullptr;
+    bool new_field_contents = false;
+    int chp_finished = 0;
+    AppId chp_candidate = APP_ID_NONE;
+    AppId chp_alt_candidate = APP_ID_NONE;
+    int chp_hold_flow = 0;
+    int ptype_req_counts[NUMBER_OF_PTYPES] = { 0 };
+    int total_found = 0;
+    unsigned app_type_flags = 0;
+    int num_matches = 0;
+    int num_scans = 0;
+    int get_offsets_from_rebuilt = 0;
+    bool skip_simple_detect = false;
+    sfip_t* xffAddr = nullptr;
+    const char** xffPrecedence = nullptr;
+    int numXffFields = 0;
 
 #if RESPONSE_CODE_PACKET_THRESHHOLD
-    unsigned response_code_packets;
+    unsigned response_code_packets = 0;
 #endif
 };
 
+
 // For dnsSession.state:
 #define DNS_GOT_QUERY    0x01
 #define DNS_GOT_RESPONSE 0x02
 
 struct dnsSession
 {
-    uint8_t state;              // state
-    uint8_t host_len;           // for host
-    uint8_t response_type;      // response: RCODE
-    uint16_t id;                // DNS msg ID
-    uint16_t host_offset;       // for host
-    uint16_t record_type;       // query: QTYPE
-    uint32_t ttl;               // response: TTL
-    char* host;                 // host (usually query, but could be response for reverse lookup)
+    uint8_t state = 0;              // state
+    uint8_t host_len = 0;           // for host
+    uint8_t response_type = 0;      // response: RCODE
+    uint16_t id = 0;                // DNS msg ID
+    uint16_t host_offset = 0;       // for host
+    uint16_t record_type = 0;       // query: QTYPE
+    uint32_t ttl = 0;               // response: TTL
+    char* host = nullptr;           // host (usually query, but could be response for reverse lookup)
 };
 
 struct _RNAServiceSubtype;
 
 struct tlsSession
 {
-    char* tls_host;
-    int tls_host_strlen;
-    char* tls_cname;
-    int tls_cname_strlen;
-    char* tls_orgUnit;
-    int tls_orgUnit_strlen;
+    char* tls_host = nullptr;
+    int tls_host_strlen = 0;
+    char* tls_cname = nullptr;
+    int tls_cname_strlen = 0;
+    char* tls_orgUnit = nullptr;
+    int tls_orgUnit_strlen = 0;
 };
 
 void map_app_names_to_snort_ids();
index 208e9ec5c853c79275948f5f1d72b6bbfd29b08e..5a9cd2a8adc73890314471ce476166355e26074f 100644 (file)
@@ -88,7 +88,7 @@ static THREAD_LOCAL time_t bucketStart;
 static THREAD_LOCAL time_t bucketInterval;
 static THREAD_LOCAL time_t bucketEnd;
 
-static const char appid_stats_file_suffix[] = "_appid_stats.log";
+static const char appid_stats_file_suffix[] = "appid_stats.log";
 static size_t rollSize;
 static time_t rollPeriod;
 static bool enableAppStats;
@@ -449,7 +449,6 @@ static void dump_statistics()
                     app_name = "__none";
                 else
                 {
-                    ErrorMessage("invalid appid in appStatRecord (%u)\n", record->app_id);
                     if (cooked_client)
                         snprintf(tmpBuff, MAX_EVENT_APPNAME_LEN, "_err_cl_%u",app_id);
                     else
index 3a0fb7abca043c1fb1f50b26c31d48fb3192e24e..0643877f757ab83a7c2b05bc1812eba8f421943a 100644 (file)
@@ -1719,54 +1719,51 @@ static inline int optionallyReplaceWithStrdup(char** optionalStr, const char* st
     return 0;
 }
 
+static inline uint8_t* continue_buffer_scan(const uint8_t* start, const uint8_t* end, MatchedPatterns* mp,
+    DetectorHTTPPattern* match)
+{
+    uint8_t* bp = (uint8_t*) (start) + mp->index + match->pattern_size;
+    if( (bp >= end) || (*bp != ' ' && *bp != 0x09 && *bp != '/') )
+        return nullptr;
+    else
+        return ++bp;
+}
+
 void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, AppId* ClientAppId,
     char** version)
 {
-    int skypeDetect;
-    int mobileDetect;
-    int safariDetect;
-    unsigned int appleEmailDetect;
-    int firefox_detected, android_browser_detected;
-    int dominant_pattern_detected;
-    int longest_misc_match;
-    const uint8_t* end;
+    char temp_ver[MAX_VERSION_SIZE] = { 0 };
     MatchedPatterns* mp = nullptr;
-    MatchedPatterns* tmp;
-    DetectorHTTPPattern* match;
-    uint8_t* buffPtr;
-    unsigned int i;
-    char temp_ver[MAX_VERSION_SIZE];
-    temp_ver[0] = 0;
+    uint8_t* buffPtr = nullptr;
 
     detectorHttpConfig->client_agent_matcher->find_all((const char*)start, size, &http_pattern_match, false, (void*)&mp);
-
     if (mp)
     {
-        end = start + size;
-        temp_ver[0] = 0;
-        skypeDetect = 0;
-        mobileDetect = 0;
-        safariDetect = 0;
-        firefox_detected = 0;
-        android_browser_detected = 0;
-        dominant_pattern_detected = 0;
-        longest_misc_match = 0;
-        i = 0;
+        const uint8_t* end = start + size;
+        int skypeDetect = 0;
+        int mobileDetect = 0;
+        int safariDetect = 0;
+        int firefox_detected = 0;
+        int android_browser_detected = 0;
+        int dominant_pattern_detected = 0;
+        bool appleEmailDetect = true;
+        int longest_misc_match = 0;
+        unsigned i = 0;
+
         *ClientAppId = APP_ID_NONE;
         *serviceAppId = APP_ID_HTTP;
-        for (tmp = mp; tmp; tmp = tmp->next)
+        for (MatchedPatterns* tmp = mp; tmp; tmp = tmp->next)
         {
-            match = (DetectorHTTPPattern*)tmp->mpattern;
+            DetectorHTTPPattern* match = (DetectorHTTPPattern*)tmp->mpattern;
             switch (match->client_app)
             {
             case APP_ID_INTERNET_EXPLORER:
             case APP_ID_FIREFOX:
                 if (dominant_pattern_detected)
                     break;
-                buffPtr = (uint8_t*)start + tmp->index + match->pattern_size;
-                if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != '/')
+                buffPtr = continue_buffer_scan(start, end, tmp, match);
+                if(!buffPtr)
                     break;
-                buffPtr++;
                 while (i < MAX_VERSION_SIZE-1 && buffPtr < end)
                 {
                     if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != ';' && *buffPtr != ')')
@@ -1798,10 +1795,9 @@ void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, Ap
             case APP_ID_CHROME:
                 if (dominant_pattern_detected)
                     break;
-                buffPtr = (uint8_t*)start + tmp->index + match->pattern_size;
-                if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != '/')
+                buffPtr = continue_buffer_scan(start, end, tmp, match);
+                if(!buffPtr)
                     break;
-                buffPtr++;
                 while (i < MAX_VERSION_SIZE-1 && buffPtr < end)
                 {
                     if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != ';' && *buffPtr != ')')
@@ -1821,10 +1817,9 @@ void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, Ap
             case APP_ID_ANDROID_BROWSER:
                 if (dominant_pattern_detected)
                     break;
-                buffPtr = (uint8_t*)start + tmp->index + match->pattern_size;
-                if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != '/')
+                buffPtr = continue_buffer_scan(start, end, tmp, match);
+                if(!buffPtr)
                     break;
-                buffPtr++;
                 while (i < MAX_VERSION_SIZE-1 && buffPtr < end)
                 {
                     if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != ';' && *buffPtr != ')')
@@ -1846,10 +1841,9 @@ void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, Ap
                     break;
             case APP_ID_WINDOWS_MEDIA_PLAYER:
             case APP_ID_BITTORRENT:
-                buffPtr = (uint8_t*)start + tmp->index + match->pattern_size;
-                if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != '/')
+                buffPtr = continue_buffer_scan(start, end, tmp, match);
+                if(!buffPtr)
                     break;
-                buffPtr++;
                 while (i < MAX_VERSION_SIZE-1 && buffPtr < end)
                 {
                     if (*buffPtr != ' ' && *buffPtr != 0x09 && *buffPtr != ';' && *buffPtr != ')')
@@ -1898,12 +1892,12 @@ void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, Ap
                 break;
 
             case APP_ID_APPLE_EMAIL:
-                appleEmailDetect = 1;
+                appleEmailDetect = true;
                 for (i = 0; i < 3 && appleEmailDetect; i++)
                 {
                     buffPtr = (uint8_t*)strstr((char*)start, (char*)APPLE_EMAIL_PATTERNS[i]);
-                    appleEmailDetect  = ((uint8_t*)buffPtr && (i != 0 || (i == 0 && buffPtr ==
-                        ((uint8_t*)start))));
+                    appleEmailDetect  = ((uint8_t*)buffPtr &&
+                                    (i != 0 || (i == 0 && buffPtr == ((uint8_t*)start))));
                 }
                 if (appleEmailDetect)
                 {
@@ -2014,6 +2008,7 @@ void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, Ap
                 }
             }
         }
+
         if (mobileDetect && safariDetect && !dominant_pattern_detected)
         {
             *serviceAppId = APP_ID_HTTP;
@@ -2043,7 +2038,7 @@ void identify_user_agent(const uint8_t* start, int size, AppId* serviceAppId, Ap
     }
 
 done:
-    optionallyReplaceWithStrdup(version,temp_ver);
+    optionallyReplaceWithStrdup(version, temp_ver);
     FreeMatchStructures(mp);
 }
 
index 1bffe77f62892bd9ac9784bf74f365045491514f..fcc5301ec83bda6c9bc66e65ac3a42d5207e8bf3 100644 (file)
 
 #include "host_port_app_cache.h"
 
+#include <map>
+
 #include "appid_config.h"
-#include "hash/sfxhash.h"
 #include "log/messages.h"
 #include "sfip/sf_ip.h"
 
-THREAD_LOCAL SFXHASH* hostPortCache = nullptr;
-
-void hostPortAppCacheInit()
+struct HostPortKey
 {
-    auto hash = sfxhash_new( 2048, sizeof(HostPortKey), sizeof(HostPortVal),
-            0, 0, nullptr, nullptr, 0);
+    HostPortKey()
+    {
+        ip.clear();
+        port = 0;
+        proto = IpProtocol::PROTO_NOT_SET;
+    }
 
-    if ( hash )
-        hostPortCache = hash;
-    else
-        ErrorMessage("failed to allocate HostPort map");
+       bool operator<(HostPortKey right) const
+       {
+               if( sfip_lesser(&ip, &right.ip) )
+                       return true;
+               else if( sfip_lesser(&right.ip, &ip) )
+                       return false;
+               else
+               {
+                       if( port < right.port)
+                               return true;
+                       else if( right.port < port )
+                               return false;
+                       else if( proto < right.proto)
+                               return true;
+                       else
+                               return false;
+               }
+       }
+
+    sfip_t ip;
+    uint16_t port;
+    IpProtocol proto;
+};
+
+THREAD_LOCAL std::map<HostPortKey, HostPortVal>* host_port_cache = nullptr;
+
+void HostPortCache::initialize()
+{
+       host_port_cache = new std::map<HostPortKey, HostPortVal>;
 }
 
-void hostPortAppCacheFini()
+void HostPortCache::terminate()
 {
-    if ( hostPortCache )
-    {
-        sfxhash_delete(hostPortCache);
-        hostPortCache = nullptr;
-    }
+       host_port_cache->empty();
+       delete host_port_cache;
+       host_port_cache = nullptr;
 }
 
-HostPortVal* hostPortAppCacheFind(const sfip_t* snort_ip, uint16_t port, IpProtocol protocol)
+HostPortVal* HostPortCache::find(const sfip_t* ip, uint16_t port, IpProtocol protocol)
 {
     HostPortKey hk;
-    sfip_set_ip(&hk.ip, snort_ip);
+
+    sfip_set_ip(&hk.ip, ip);
     hk.port = port;
     hk.proto = protocol;
 
-    return (HostPortVal*)sfxhash_find(hostPortCache, &hk);
+    std::map<HostPortKey, HostPortVal>::iterator it;
+    it = host_port_cache->find(hk);
+    if (it != host_port_cache->end())
+       return &it->second;
+    else
+       return nullptr;
 }
 
-int hostPortAppCacheAdd(const sfip_t* ip, uint16_t port, IpProtocol proto, unsigned type, AppId appId)
+bool HostPortCache::add(const sfip_t* ip, uint16_t port, IpProtocol proto, unsigned type, AppId appId)
 {
     HostPortKey hk;
     HostPortVal hv;
-    memcpy(&hk.ip, ip, sizeof(hk.ip));
+
+    sfip_set_ip(&hk.ip, ip);
     hk.port = port;
     hk.proto = proto;
     hv.appId = appId;
     hv.type = type;
 
-    return sfxhash_add(hostPortCache, &hk, &hv) ? 0 : 1;
+    (*host_port_cache)[ hk ] = hv;
+
+    return true;
 }
 
-void hostPortAppCacheDump()
+void HostPortCache::dump()
 {
-    for ( SFXHASH_NODE* node = sfxhash_findfirst(hostPortCache);
-        node;
-        node = sfxhash_findnext(hostPortCache))
+    for ( auto& kv : *host_port_cache )
     {
         char inet_buffer[INET6_ADDRSTRLEN];
-        HostPortKey* hk;
-        HostPortVal* hv;
 
-        hk = (HostPortKey*)node->key;
-        hv = (HostPortVal*)node->data;
+        HostPortKey hk = kv.first;
+        HostPortVal hv = kv.second;
 
-        inet_ntop(AF_INET6, &hk->ip, inet_buffer, sizeof(inet_buffer));
-        printf("\tip=%s, \tport %d, \tip_proto %d, \ttype=%u, \tappId=%d\n", inet_buffer, hk->port,
-            to_utype(hk->proto), hv->type, hv->appId);
+        inet_ntop(AF_INET6, &hk.ip, inet_buffer, sizeof(inet_buffer));
+        LogMessage("\tip=%s, \tport %d, \tip_proto %u, \ttype=%u, \tappId=%d\n",
+            inet_buffer, hk.port, (unsigned)hk.proto, hv.type, hv.appId);
     }
 }
 
index fbbe7198a8f2ddc823abc35bc2b6df0eca9de54c..40a3b61cfb6e3a7dde535d103978e0d988084844 100644 (file)
 #ifndef HOST_PORT_APP_CACHE_H
 #define HOST_PORT_APP_CACHE_H
 
+#include "protocols/protocol_ids.h"
 #include "sfip/sfip_t.h"
 #include "appid_api.h"
 
-class AppIdConfig;
-enum class IpProtocol : uint8_t;
-
-struct HostPortKey
+struct HostPortVal
 {
-    sfip_t ip;
-    uint16_t port;
-    IpProtocol proto;
+       AppId appId;
+       unsigned type;
 };
 
-struct HostPortVal
+class HostPortCache
 {
-    AppId appId;
-    unsigned type;
+public:
+       static void initialize();
+       static void terminate();
+       static HostPortVal* find(const sfip_t*, uint16_t port, IpProtocol proto);
+       static bool add(const sfip_t*, uint16_t port, IpProtocol proto, unsigned type, AppId);
+       static void dump();
 };
 
-void hostPortAppCacheInit();
-void hostPortAppCacheFini();
-HostPortVal* hostPortAppCacheFind(const sfip_t*, uint16_t port, IpProtocol proto);
-int hostPortAppCacheAdd(const sfip_t*, uint16_t port, IpProtocol proto, unsigned type, AppId);
-void hostPortAppCacheDump();
 
 #endif
 
index a7da99dbe024020106518be9138ff99af6aabd4e..2e87d42d8a69039d7e00b4cc610dbefa15ee01a7 100644 (file)
@@ -51,17 +51,11 @@ void free_length_app_cache()
 
 AppId find_length_app_cache(const LengthKey* key)
 {
-    AppId* val;
-
-    val = (AppId*)sfxhash_find(lengthCache, (void*)key);
+    AppId* val = (AppId*)sfxhash_find(lengthCache, (void*)key);
     if (val == nullptr)
-    {
         return APP_ID_NONE;    /* no match */
-    }
     else
-    {
         return *val;           /* match found */
-    }
 }
 
 bool add_length_app_cache(const LengthKey* key, AppId val)
index 171056371ec6c5fa24b39dbf556372cb808b39f0..5f415575ec8abd1d8b2afc4c75cd2544852c9633 100644 (file)
@@ -33,14 +33,14 @@ enum class IpProtocol : uint8_t;
 
 struct LengthSequenceEntry
 {
-    uint8_t direction;     /* APP_ID_FROM_INITIATOR or APP_ID_FROM_RESPONDER */
-    uint16_t length;       /* payload size (bytes) */
+    uint8_t direction = 0;     /* APP_ID_FROM_INITIATOR or APP_ID_FROM_RESPONDER */
+    uint16_t length = 0;       /* payload size (bytes) */
 };
 
 struct LengthKey
 {
-    IpProtocol proto;                        /* IpProtocol::TCP or IpProtocol::UDP */
-    uint8_t sequence_cnt;                 /* num valid entries in sequence */
+    IpProtocol proto = IpProtocol::PROTO_NOT_SET;  // IpProtocol::TCP or IpProtocol::UDP
+    uint8_t sequence_cnt = 0;                      // num valid entries in sequence
     LengthSequenceEntry sequence[LENGTH_SEQUENCE_CNT_MAX];
 };
 
index 5ca48274d33d47aa83d7e6a4b0e88fe95f716ca0..a9a0f6e132055cd6cd3faaecf827fa983f2e2373 100644 (file)
@@ -30,6 +30,7 @@
 #include "log/messages.h"
 #include "main/snort_debug.h"
 #include "profiler/profiler.h"
+#include "protocols/protocol_ids.h"
 #include "sfip/sf_ip.h"
 #include "utils/util.h"
 
@@ -196,10 +197,10 @@ static int service_register_pattern(lua_State* L)
     // FIXIT-M  none of these params check for signedness casting issues
     // FIXIT-M May want to create a lua_toipprotocol() so we can handle
     //          error checking in that function.
-    int protocol = lua_tonumber(L, index++);
-    if (protocol > UINT8_MAX)
+    unsigned protocol = lua_tonumber(L, index++);
+    if (protocol > (unsigned)IpProtocol::RESERVED)
     {
-        ErrorMessage("Invalid protocol value %d\n", protocol);
+        ErrorMessage("Invalid protocol value %u\n", protocol);
         return -1;
     }
 
@@ -1401,14 +1402,13 @@ static int detector_add_host_port_application(lua_State* L)
 
     unsigned port  = lua_tointeger(L, index++);
     unsigned proto  = lua_tointeger(L, index++);
-
-    if (proto > UINT8_MAX)
+    if (proto > (unsigned)IpProtocol::RESERVED)
     {
         ErrorMessage("%s:Invalid protocol value %u\n",__func__, proto);
         return 0;
     }
 
-    if (!hostPortAppCacheAdd(&ip_addr, (uint16_t)port, (IpProtocol)proto, type, app_id))
+    if (!HostPortCache::add(&ip_addr, (uint16_t)port, (IpProtocol)proto, type, app_id))
         ErrorMessage("%s:Failed to backend call\n",__func__);
 
     return 0;
index 2923e4dbcad40e6f9d52e3c997a8fd67985f8afb..26b94060555efbb29dbb3e13f16946a7a57efae6 100644 (file)
@@ -157,10 +157,6 @@ static int create_detector_flow(lua_State* L)
 {
     sfip_t saddr;
     sfip_t daddr;
-    IpProtocol proto;
-    uint16_t sport, dport;
-    char* pattern;
-    size_t patternLen;
 
     auto& detector_data = *UserData<Detector>::check(L, DETECTOR, 1);
 
@@ -168,8 +164,8 @@ static int create_detector_flow(lua_State* L)
     if ( !detector_data->validateParams.pkt )
         return 0;   /*number of results */
 
-    pattern = (char*)lua_tostring(L, 2);
-    patternLen = lua_strlen (L, 2);
+    char* pattern = (char*)lua_tostring(L, 2);
+    size_t patternLen = lua_strlen (L, 2);
 
     if (patternLen == 16)
     {
@@ -203,9 +199,9 @@ static int create_detector_flow(lua_State* L)
         return 0;
     }
 
-    sport = lua_tonumber(L, 4);
-    dport = lua_tonumber(L, 5);
-    proto = (IpProtocol)lua_tonumber(L, 6);
+    uint16_t sport = lua_tonumber(L, 4);
+    uint16_t dport = lua_tonumber(L, 5);
+    IpProtocol proto = (IpProtocol)lua_tonumber(L, 6);
 
     auto detector_flow = new DetectorFlow();
     UserData<DetectorFlow>::push(L, DETECTORFLOW, detector_flow);
index f3d6e1f9085a09b7f69a22e12c1610ecdeda7012..7a20ad6dea59e7bca746f35b2830a5cc479b77cd 100644 (file)
@@ -150,14 +150,6 @@ static void add_dns_response_info(AppIdSession*, uint16_t id, const uint8_t* hos
         uint16_t host_offset, uint8_t response_type, uint32_t ttl);
 static void reset_dns_info(AppIdSession*);
 
-struct ServiceMatch
-{
-    struct ServiceMatch* next;
-    unsigned count;
-    unsigned size;
-    RNAServiceElement* svc;
-};
-
 static const uint8_t zeromac[6] = { 0, 0, 0, 0, 0, 0 };
 static THREAD_LOCAL DHCPInfo* dhcp_info_free_list = nullptr;
 static THREAD_LOCAL FpSMBData* smb_data_free_list = nullptr;
@@ -278,17 +270,6 @@ static void appSetServiceValidator(RNAServiceValidationFCN fcn, AppId appId, uns
         ErrorMessage("AppId: failed to find a service element for AppId %d", appId);
 }
 
-void AppIdFreeServiceMatchList(ServiceMatch* sm)
-{
-    ServiceMatch* tmpSm;
-
-    while( sm )
-    {
-        tmpSm = sm;
-        sm = sm->next;
-        snort_free(tmpSm);
-    }
-}
 
 int AddFTPServiceState(AppIdSession* asd)
 {
@@ -900,6 +881,18 @@ static int AppIdPatternPrecedence(const void* a, const void* b)
         return (sm2->size - sm1->size);
 }
 
+void free_service_match_list(ServiceMatch* sm)
+{
+    ServiceMatch* tmpSm;
+
+    while( sm )
+    {
+        tmpSm = sm;
+        sm = sm->next;
+        snort_free(tmpSm);
+    }
+}
+
 /**Perform pattern match of a packet and construct a list of services sorted in order of
  * precedence criteria. Criteria is count and then size. The first service in the list is
  * returned. The list itself is saved in AppIdServiceIDState. If
@@ -947,14 +940,12 @@ static inline RNAServiceElement* AppIdGetServiceByPattern(const Packet* pkt, IpP
     if (id_state)
     {
         id_state->svc = service;
-        if (id_state->service_list != nullptr)
-            AppIdFreeServiceMatchList(id_state->service_list);
-
+        id_state->free_service_match_list();
         id_state->service_list = smOrderedList[0];
         id_state->current_service = smOrderedList[0];
     }
     else
-        AppIdFreeServiceMatchList(smOrderedList[0]);
+        free_service_match_list(smOrderedList[0]);
 
     APPID_LOG_FILTER_PORTS(pkt->ptrs.dp, pkt->ptrs.sp,
         "Pattern service for protocol %u (%u->%u), %s\n",
@@ -966,7 +957,7 @@ static inline RNAServiceElement* AppIdGetServiceByPattern(const Packet* pkt, IpP
 static inline RNAServiceElement* AppIdGetServiceByBruteForce(IpProtocol protocol,
     const RNAServiceElement* lasService)
 {
-    RNAServiceElement* service;
+    RNAServiceElement* service = nullptr;
 
     if (lasService)
         service = lasService->next;
@@ -1115,9 +1106,9 @@ static void add_smb_info(AppIdSession* asd, unsigned major, unsigned minor, uint
 static int AppIdServiceAddServiceEx(AppIdSession* asd, const Packet* pkt, int dir,
     const RNAServiceElement* svc_element, AppId appId, const char* vendor, const char* version)
 {
-    AppIdServiceIDState* id_state;
-    uint16_t port;
-    const sfip_t* ip;
+    AppIdServiceIDState* id_state = nullptr;
+    uint16_t port = 0;
+    const sfip_t* ip = nullptr;
 
     if (!asd || !pkt || !svc_element)
     {
@@ -1177,13 +1168,13 @@ static int AppIdServiceAddServiceEx(AppIdSession* asd, const Packet* pkt, int di
     // If UDP reversed, ensure we have the correct host tracker entry.
     if (asd->get_session_flags(APPID_SESSION_UDP_REVERSED))
     {
-        asd->id_state = get_service_id_state(ip, asd->protocol, port,
+        asd->id_state = AppIdServiceState::get(ip, asd->protocol, port,
             AppIdServiceDetectionLevel(asd));
     }
 
     if (!(id_state = asd->id_state))
     {
-        if (!(id_state = add_service_id_state(ip, asd->protocol, port,
+        if (!(id_state = AppIdServiceState::add(ip, asd->protocol, port,
             AppIdServiceDetectionLevel(asd))))
         {
             ErrorMessage("Add service failed to create state");
@@ -1198,8 +1189,7 @@ static int AppIdServiceAddServiceEx(AppIdSession* asd, const Packet* pkt, int di
     {
         if (id_state->service_list)
         {
-            AppIdFreeServiceMatchList(id_state->service_list);
-            id_state->service_list = nullptr;
+            id_state->free_service_match_list();
             id_state->current_service = nullptr;
         }
 
@@ -1322,7 +1312,7 @@ int AppIdServiceInProcess(AppIdSession* asd, const Packet* pkt, int dir,
         const sfip_t* ip = pkt->ptrs.ip_api.get_src();
         uint16_t port = asd->service_port ? asd->service_port : pkt->ptrs.sp;
 
-        if (!(id_state = add_service_id_state(ip, asd->protocol, port,
+        if (!(id_state = AppIdServiceState::add(ip, asd->protocol, port,
             AppIdServiceDetectionLevel(asd))))
         {
             ErrorMessage("In-process service failed to create state");
@@ -1415,7 +1405,7 @@ int AppIdServiceIncompatibleData(AppIdSession* asd, const Packet* pkt, int dir,
         const sfip_t* ip = pkt->ptrs.ip_api.get_src();
         uint16_t port = asd->service_port ? asd->service_port : pkt->ptrs.sp;
 
-        if (!(id_state = add_service_id_state(ip, asd->protocol, port,
+        if (!(id_state = AppIdServiceState::add(ip, asd->protocol, port,
                                               AppIdServiceDetectionLevel(asd))))
         {
             ErrorMessage("Incompatible service failed to create state");
@@ -1509,7 +1499,7 @@ int AppIdServiceFailService(AppIdSession* asd, const Packet* pkt, int dir,
         const sfip_t* ip = pkt->ptrs.ip_api.get_src();
         uint16_t port = asd->service_port ? asd->service_port : pkt->ptrs.sp;
 
-        if (!(id_state = add_service_id_state(ip, asd->protocol, port,
+        if (!(id_state = AppIdServiceState::add(ip, asd->protocol, port,
                 AppIdServiceDetectionLevel(asd))))
         {
             ErrorMessage("Fail service failed to create state");
@@ -1644,13 +1634,11 @@ static void HandleFailure(AppIdSession* asd, AppIdServiceIDState* id_state,
  */
 void FailInProcessService(AppIdSession* asd, const AppIdConfig*)
 {
-    AppIdServiceIDState* id_state;
-
     if (asd->get_session_flags(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_UDP_REVERSED))
         return;
 
-    id_state = get_service_id_state(&asd->service_ip, asd->protocol, asd->service_port,
-        AppIdServiceDetectionLevel(asd));
+    AppIdServiceIDState* id_state = AppIdServiceState::get(&asd->service_ip,
+               asd->protocol, asd->service_port, AppIdServiceDetectionLevel(asd));
 
     APPID_LOG_FILTER_SERVICE_PORT(asd->service_port,
             "FailInProcess %" PRIx64 ", %08X:%u proto %u\n", asd->common.flags,
@@ -1739,7 +1727,7 @@ static const RNAServiceElement* get_next_service(const Packet* p, const int dir,
                 const RNAServiceElement* reverse_service = nullptr;
                 const sfip_t* reverse_ip = p->ptrs.ip_api.get_src();
                 asd->tried_reverse_service = true;
-                if ((reverse_id_state = get_service_id_state(reverse_ip, proto, p->ptrs.sp,
+                if ((reverse_id_state = AppIdServiceState::get(reverse_ip, proto, p->ptrs.sp,
                         AppIdServiceDetectionLevel(asd))))
                 {
                     reverse_service = reverse_id_state->svc;
@@ -1785,11 +1773,10 @@ static const RNAServiceElement* get_next_service(const Packet* p, const int dir,
 
 int AppIdDiscoverService(Packet* p, const int dir, AppIdSession* asd)
 {
-    const sfip_t* ip;
+    const sfip_t* ip = nullptr;
     int ret = SERVICE_NOMATCH;
-    const RNAServiceElement* service;
-    AppIdServiceIDState* id_state;
-    uint16_t port;
+    const RNAServiceElement* service = nullptr;
+    uint16_t port = 0;
     ServiceValidationArgs args;
 
     /* Get packet info. */
@@ -1814,15 +1801,15 @@ int AppIdDiscoverService(Packet* p, const int dir, AppIdSession* asd)
     }
 
     /* Get host tracker state. */
-    id_state = asd->id_state;
+    AppIdServiceIDState* id_state = asd->id_state;
     if (id_state == nullptr)
     {
-        id_state = get_service_id_state(ip, proto, port, AppIdServiceDetectionLevel(asd));
+        id_state = AppIdServiceState::get(ip, proto, port, AppIdServiceDetectionLevel(asd));
 
         /* Create it if it doesn't exist yet. */
         if (id_state == nullptr)
         {
-            if (!(id_state = add_service_id_state(ip, proto, port,
+            if (!(id_state = AppIdServiceState::add(ip, proto, port,
                     AppIdServiceDetectionLevel(asd))))
             {
                 ErrorMessage("Discover service failed to create state");
@@ -2009,10 +1996,7 @@ int AppIdDiscoverService(Packet* p, const int dir, AppIdSession* asd)
     if (    (id_state->state == SERVICE_ID_BRUTE_FORCE)
         || (id_state->state == SERVICE_ID_VALID) )
     {
-        if (id_state->service_list != nullptr)
-            AppIdFreeServiceMatchList(id_state->service_list);
-
-        id_state->service_list    = nullptr;
+        id_state->free_service_match_list();
         id_state->current_service = nullptr;
     }
 
index c9e6c64a56825423ecdeeec3f581c9fade161908..d3f8070d8eae9b13481dd86588cd9d6df28759ff 100644 (file)
@@ -74,7 +74,7 @@ const RNAServiceElement* get_service_element(RNAServiceValidationFCN, Detector*)
 void add_service_to_active_list(RNAServiceValidationModule* service);
 extern uint32_t app_id_instance_id;
 
-void AppIdFreeServiceMatchList(ServiceMatch* sm);
+void free_service_match_list(ServiceMatch* sm);
 
 inline bool compareServiceElements(const RNAServiceElement* first,
         const RNAServiceElement* second)
index 6dfd871a241fe621cf0f258bda5a6c0f979be478..d4e5d590160b3305b53a63badcddd85533b324fb 100644 (file)
@@ -856,14 +856,14 @@ static int ftp_validate(ServiceValidationArgs* args)
     static const char FTP_EPSV_CMD[] = "EPSV";
     static const char FTP_PORT_CMD[] = "PORT ";
     static const char FTP_EPRT_CMD[] = "EPRT ";
-    ServiceFTPData* fd;
-    uint16_t offset;
-    uint16_t init_offset;
-    int code;
-    int code_index;
-    uint32_t address;
-    uint16_t port;
-    AppIdSession* fp;
+    ServiceFTPData* fd = nullptr;
+    uint16_t offset = 0;
+    uint16_t init_offset = 0;
+    int code = 0;
+    int code_index = 0;
+    uint32_t address = 0;
+    uint16_t port = 0;
+    AppIdSession* fp = nullptr;
     int retval = SERVICE_INPROCESS;
     AppIdSession* asd = args->asd;
     const uint8_t* data = args->data;
@@ -1206,8 +1206,7 @@ static int ftp_validate(ServiceValidationArgs* args)
             case 229:
             {
                 code = ftp_validate_epsv(data + init_offset,
-                    (uint16_t)(offset-init_offset),
-                    &port);
+                    (uint16_t)(offset-init_offset), &port);
 
                 if (!code)
                 {
index 1b80016f764de7767d6495e3ce4675abcb94b058..01f58265871b2c9639225240834298466560ec5f 100644 (file)
@@ -142,9 +142,9 @@ static void rexec_free_state(void* data)
 
 static int rexec_validate(ServiceValidationArgs* args)
 {
-    int i;
-    uint32_t port;
-    AppIdSession* pf;
+    int i = 0;
+    uint32_t port = 0;
+    AppIdSession* pf = nullptr;
     AppIdSession* asd = args->asd;
     const uint8_t* data = args->data;
     Packet* pkt = args->pkt;
index cdcdd4be19cccef454c17deacb52a75b9fa797bf..e25b37d1fe31e0f48df168e6689d8a9f6c59433a 100644 (file)
@@ -316,17 +316,17 @@ static const RPCProgram* FindRPCProgram(uint32_t program)
 static int validate_packet(const uint8_t* data, uint16_t size, int dir, AppIdSession* asd,
         Packet* pkt, ServiceRPCData* rd, const char** pname, uint32_t* program)
 {
-    const ServiceRPCCall* call;
-    const ServiceRPCReply* reply;
-    const ServiceRPC* rpc;
-    const ServiceRPCPortmap* pm;
-    const ServiceRPCAuth* a;
-    const ServiceRPCPortmapReply* pmr;
-    uint32_t tmp;
-    uint32_t val;
-    const uint8_t* end;
-    AppIdSession* pf;
-    const RPCProgram* rprog;
+    const ServiceRPCCall* call = nullptr;
+    const ServiceRPCReply* reply = nullptr;
+    const ServiceRPC* rpc = nullptr;
+    const ServiceRPCPortmap* pm = nullptr;
+    const ServiceRPCAuth* a = nullptr;
+    const ServiceRPCPortmapReply* pmr = nullptr;
+    uint32_t tmp = 0;
+    uint32_t val = 0;
+    const uint8_t* end = nullptr;
+    AppIdSession* pf = nullptr;
+    const RPCProgram* rprog = nullptr;
 
     if (!size)
         return SERVICE_INPROCESS;
@@ -439,11 +439,8 @@ static int validate_packet(const uint8_t* data, uint16_t size, int dir, AppIdSes
                     pmr = (ServiceRPCPortmapReply*)data;
                     if (pmr->port)
                     {
-                        const sfip_t* sip;
-                        const sfip_t* dip;
-
-                        dip = pkt->ptrs.ip_api.get_dst();
-                        sip = pkt->ptrs.ip_api.get_src();
+                        const sfip_t* dip = pkt->ptrs.ip_api.get_dst();
+                        const sfip_t* sip = pkt->ptrs.ip_api.get_src();
                         tmp = ntohl(pmr->port);
                         pf = AppIdSession::create_future_session(pkt, dip, 0, sip, (uint16_t)tmp,
                             (IpProtocol)ntohl((uint32_t)rd->proto), app_id, 0);
index 94f071fd80ad5d587dc4fbd0cb3d3eff0a28dfcc..d581da5948fb8154112fcfc88028b57948c503a9 100644 (file)
@@ -134,10 +134,10 @@ static void rshell_free_state(void* data)
 static int rshell_validate(ServiceValidationArgs* args)
 {
     ServiceRSHELLData* rd = nullptr;
-    ServiceRSHELLData* tmp_rd;
-    int i;
-    uint32_t port;
-    AppIdSession* pf;
+    ServiceRSHELLData* tmp_rd = nullptr;
+    int i = 0;
+    uint32_t port = 0;
+    AppIdSession* pf = nullptr;
     AppIdSession* asd = args->asd;
     const uint8_t* data = args->data;
     Packet* pkt = args->pkt;
@@ -180,14 +180,11 @@ static int rshell_validate(ServiceValidationArgs* args)
             goto bail;
         if (port)
         {
-            const sfip_t* sip;
-            const sfip_t* dip;
-
             tmp_rd = (ServiceRSHELLData*)snort_calloc(sizeof(ServiceRSHELLData));
             tmp_rd->state = RSHELL_STATE_STDERR_CONNECT_SYN;
             tmp_rd->parent = rd;
-            dip = pkt->ptrs.ip_api.get_dst();
-            sip = pkt->ptrs.ip_api.get_src();
+            const sfip_t* dip = pkt->ptrs.ip_api.get_dst();
+            const sfip_t* sip = pkt->ptrs.ip_api.get_src();
             pf = AppIdSession::create_future_session(pkt, dip, 0, sip, (uint16_t)port, IpProtocol::TCP, app_id,
                     APPID_EARLY_SESSION_FLAG_FW_RULE);
             if (pf)
index 83dcc8b8f218646a91b62f1dacd36bbd16610b31..a8f396c3c0ecd28bd4065325558fac76ff7a2949 100644 (file)
@@ -437,13 +437,11 @@ static int snmp_verify_packet(const uint8_t** const data,
 
 static int snmp_validate(ServiceValidationArgs* args)
 {
-    ServiceSNMPData* sd;
-    ServiceSNMPData* tmp_sd;
-    AppIdSession* pf;
-    uint8_t pdu;
-    const sfip_t* sip;
-    const sfip_t* dip;
-    uint8_t version;
+    ServiceSNMPData* sd = nullptr;
+    ServiceSNMPData* tmp_sd = nullptr;
+    AppIdSession* pf = nullptr;
+    uint8_t pdu = 0;
+    uint8_t version = 0;
     const char* version_str = nullptr;
     AppIdSession* asd = args->asd;
     const uint8_t* data = args->data;
@@ -488,6 +486,7 @@ static int snmp_validate(ServiceValidationArgs* args)
     switch (sd->state)
     {
     case SNMP_STATE_CONNECTION:
+    {
         if (pdu != SNMP_PDU_GET_RESPONSE && dir == APP_ID_FROM_RESPONDER)
         {
             sd->state = SNMP_STATE_R_RESPONSE;
@@ -517,8 +516,8 @@ static int snmp_validate(ServiceValidationArgs* args)
         sd->state = SNMP_STATE_RESPONSE;
 
         /*adding expected connection in case the server doesn't send from 161*/
-        dip = pkt->ptrs.ip_api.get_dst();
-        sip = pkt->ptrs.ip_api.get_src();
+        const sfip_t* dip = pkt->ptrs.ip_api.get_dst();
+        const sfip_t* sip = pkt->ptrs.ip_api.get_src();
         pf = AppIdSession::create_future_session(pkt, dip, 0, sip, pkt->ptrs.sp, asd->protocol, app_id, 0);
         if (pf)
         {
@@ -538,6 +537,7 @@ static int snmp_validate(ServiceValidationArgs* args)
             pf->scan_flags |= SCAN_HOST_PORT_FLAG;
             pf->common.initiator_ip = *sip;
         }
+    }
         break;
     case SNMP_STATE_RESPONSE:
         if (pdu == SNMP_PDU_GET_RESPONSE)
index 7ba7dd0fbcb8fc8eaa29f4c2cd0b21abb0319a5c..bd35d5be78b56b586358f2e59f31b8a2bc7d64d7 100644 (file)
@@ -1148,15 +1148,13 @@ void ssl_detector_free_patterns()
 
 bool setSSLSquelch(Packet* p, int type, AppId appId)
 {
-    const sfip_t* sip;
-    const sfip_t* dip;
-    AppIdSession* f;
+    AppIdSession* f = nullptr;
 
     if (!AppInfoManager::get_instance().get_app_info_flags(appId, APPINFO_FLAG_SSL_SQUELCH))
         return false;
 
-    dip = p->ptrs.ip_api.get_dst();
-    sip = p->ptrs.ip_api.get_src();
+    const sfip_t* dip = p->ptrs.ip_api.get_dst();
+    const sfip_t* sip = p->ptrs.ip_api.get_src();
 
     if (!(f = AppIdSession::create_future_session(p, sip, 0, dip, p->ptrs.dp, IpProtocol::TCP,
                appId, 0)))
index 1ac017f27b0fd44171a7c33e77367f4b26e56f0c..1d4e4bc45d3cf69bca6f40de29a2adcf551f1fec 100644 (file)
@@ -163,14 +163,14 @@ static int tftp_verify_header(const uint8_t* data, uint16_t size,
 
 static int tftp_validate(ServiceValidationArgs* args)
 {
-    ServiceTFTPData* td;
-    ServiceTFTPData* tmp_td;
-    int mode;
+    ServiceTFTPData* td = nullptr;
+    ServiceTFTPData* tmp_td = nullptr;
+    int mode = 0;
     uint16_t block = 0;
-    uint16_t tmp;
-    AppIdSession* pf;
-    const sfip_t* sip;
-    const sfip_t* dip;
+    uint16_t tmp = 0;
+    AppIdSession* pf = nullptr;
+    const sfip_t* sip = nullptr;
+    const sfip_t* dip = nullptr;
     AppIdSession* asd = args->asd;
     const uint8_t* data = args->data;
     Packet* pkt = args->pkt;
index 6c73e944b5235df118b8428746fc3a6c8a13dd8d..a19246aba97444c0fc842ab88f46eecff8818718 100644 (file)
@@ -21,7 +21,8 @@
 
 #include "service_state.h"
 
-#include "hash/sfxhash.h"
+#include <map>
+
 #include "log/messages.h"
 #include "service_plugins/service_base.h"
 #include "sfip/sf_ip.h"
 
 //#define DEBUG_SERVICE_STATE 1
 
-static THREAD_LOCAL SFXHASH* serviceStateCache4;
-static THREAD_LOCAL SFXHASH* serviceStateCache6;
-
-#define SERVICE_STATE_CACHE_ROWS    65536
-
-static int AppIdServiceStateFree(void*, void* data)
+class AppIdServiceStateKey
 {
-    AppIdServiceIDState* id_state = (AppIdServiceIDState*)data;
-
-    if (id_state->service_list)
-    {
-        AppIdFreeServiceMatchList(id_state->service_list);
-        id_state->service_list = nullptr;
-    }
-
-    return 0;
-}
-
-int init_service_state(unsigned long memcap)
+public:
+       AppIdServiceStateKey()
+    {
+        ip.clear();
+        port = 0;
+        proto = IpProtocol::PROTO_NOT_SET;
+        level = 0;
+    }
+
+       bool operator<(AppIdServiceStateKey right) const
+       {
+               if( sfip_lesser(&ip, &right.ip) )
+                       return true;
+               else if( sfip_lesser(&right.ip, &ip) )
+                       return false;
+               else
+               {
+                       if( port < right.port )
+                               return true;
+                       else if( right.port < port )
+                               return false;
+                       else if( proto < right.proto )
+                               return true;
+                       else if( right.proto < proto )
+                               return false;
+                       else if( level < right.level )
+                               return true;
+                       else
+                               return false;
+               }
+       }
+
+    sfip_t ip;
+    uint16_t port;
+    IpProtocol proto;
+    uint32_t level;
+};
+
+// FIXIT-L - no memcap on size of this table, do we need that?
+THREAD_LOCAL std::map<AppIdServiceStateKey, AppIdServiceIDState*>* service_state_cache = nullptr;
+
+void AppIdServiceState::initialize(unsigned long)
 {
-    serviceStateCache4 = sfxhash_new(SERVICE_STATE_CACHE_ROWS,
-        sizeof(AppIdServiceStateKey4), sizeof(AppIdServiceIDState), memcap >> 1, 1,
-        &AppIdServiceStateFree, &AppIdServiceStateFree, 1);
-    if (!serviceStateCache4)
-    {
-        ErrorMessage("Failed to allocate a hash table");
-        return -1;
-    }
-    serviceStateCache6 = sfxhash_new(SERVICE_STATE_CACHE_ROWS,
-        sizeof(AppIdServiceStateKey6), sizeof(AppIdServiceIDState), memcap >> 1, 1,
-        &AppIdServiceStateFree, &AppIdServiceStateFree, 1);
-    if (!serviceStateCache6)
-    {
-        ErrorMessage("Failed to allocate a hash table");
-        return -1;
-    }
-    return 0;
+       service_state_cache = new std::map<AppIdServiceStateKey, AppIdServiceIDState*>;
 }
 
-void clean_service_state(void)
+void AppIdServiceState::clean(void)
 {
-    if (serviceStateCache4)
-    {
-        sfxhash_delete(serviceStateCache4);
-        serviceStateCache4 = nullptr;
-    }
+       for( auto& kv : *service_state_cache )
+       delete kv.second;
 
-    if (serviceStateCache6)
-    {
-        sfxhash_delete(serviceStateCache6);
-        serviceStateCache6 = nullptr;
-    }
+       service_state_cache->empty();
+       delete service_state_cache;
+       service_state_cache = nullptr;
 }
 
-void remove_service_id_state(const sfip_t* ip, IpProtocol proto, uint16_t port, uint32_t level)
+AppIdServiceIDState* AppIdServiceState::add(const sfip_t* ip, IpProtocol proto, uint16_t port,
+    uint32_t level)
 {
-    AppIdServiceStateKey k;
-    SFXHASH* cache;
+    AppIdServiceStateKey ssk;
+    AppIdServiceIDState* ss = nullptr;
 
-    if (sfip_family(ip) == AF_INET6)
+    sfip_set_ip(&ssk.ip, ip);
+    ssk.proto = proto;
+    ssk.port = port;
+    ssk.level = level;
+
+    std::map<AppIdServiceStateKey, AppIdServiceIDState*>::iterator it;
+    it = service_state_cache->find(ssk);
+    if( it != service_state_cache->end())
     {
-        k.key6.proto = proto;
-        k.key6.port = port;
-        memcpy(k.key6.ip, ip->ip32, sizeof(k.key6.ip));
-        k.key6.level = level;
-        cache = serviceStateCache6;
+        ss = it->second;
     }
     else
     {
-        k.key4.proto = proto;
-        k.key4.port = port;
-        k.key4.ip = ip->ip32[0];
-        k.key4.level = level;
-        cache = serviceStateCache4;
+        ss = new AppIdServiceIDState;
+        (*service_state_cache)[ssk] = ss;
     }
-    if (sfxhash_remove(cache, &k) != SFXHASH_OK)
-    {
-        char ipstr[INET6_ADDRSTRLEN];
 
-        ipstr[0] = 0;
-        sfip_ntop(ip, ipstr, sizeof(ipstr));
-        ErrorMessage("Failed to remove from hash: %s:%u:%u\n", ipstr, (unsigned)proto,
-            (unsigned)port);
-    }
+#ifdef DEBUG_SERVICE_STATE
+    char ipstr[INET6_ADDRSTRLEN];
+
+    ipstr[0] = 0;
+    sfip_ntop(ip, ipstr, sizeof(ipstr));
+    DebugFormat(DEBUG_APPID, "ServiceState: Added to hash: %s:%u:%u:%u %p\n", ipstr, (unsigned)proto,
+        (unsigned)port, level, (void*)ss);
+#endif
+
+    return ss;
 }
 
-AppIdServiceIDState* get_service_id_state(const sfip_t* ip, IpProtocol proto, uint16_t port,
+AppIdServiceIDState* AppIdServiceState::get(const sfip_t* ip, IpProtocol proto, uint16_t port,
         uint32_t level)
 {
-    SFXHASH* cache;
-    AppIdServiceStateKey k;
+    AppIdServiceStateKey ssk;
+    AppIdServiceIDState* ss = nullptr;
     char ipstr[INET6_ADDRSTRLEN];   // FIXIT-M ASAN reports mem leak on ServiceMatch* objects if this is not defined
                                     //  which makes no sense, need to investigate further
 
-    if (sfip_family(ip) == AF_INET6)
-    {
-        k.key6.proto = proto;
-        k.key6.port = port;
-        memcpy(k.key6.ip, ip->ip32, sizeof(k.key6.ip));
-        k.key6.level = level;
-        cache = serviceStateCache6;
-    }
-    else
+    sfip_set_ip(&ssk.ip, ip);
+    ssk.proto = proto;
+    ssk.port = port;
+    ssk.level = level;
+
+    std::map<AppIdServiceStateKey, AppIdServiceIDState*>::iterator it;
+    it = service_state_cache->find(ssk);
+    if( it != service_state_cache->end())
     {
-        k.key4.proto = proto;
-        k.key4.port = port;
-        k.key4.ip = ip->ip32[0];
-        k.key4.level = level;
-        cache = serviceStateCache4;
+       ss = it->second;
+        if (ss->svc && !ss->svc->ref_count)
+        {
+            ss->svc = nullptr;
+            ss->state = SERVICE_ID_NEW;
+        }
     }
-    AppIdServiceIDState* ss = (AppIdServiceIDState*)sfxhash_find(cache, &k);
 
 #ifdef DEBUG_SERVICE_STATE
     ipstr[0] = 0;
@@ -150,63 +157,39 @@ AppIdServiceIDState* get_service_id_state(const sfip_t* ip, IpProtocol proto, ui
     UNUSED(ipstr);
 #endif
 
-    if (ss && ss->svc && !ss->svc->ref_count)
-    {
-        ss->svc = nullptr;
-        ss->state = SERVICE_ID_NEW;
-    }
-
     return ss;
 }
 
-AppIdServiceIDState* add_service_id_state(const sfip_t* ip, IpProtocol proto, uint16_t port,
-    uint32_t level)
+void AppIdServiceState::remove(const sfip_t* ip, IpProtocol proto, uint16_t port, uint32_t level)
 {
-    AppIdServiceStateKey k;
-    AppIdServiceIDState* ss;
-    SFXHASH* cache;
+    AppIdServiceStateKey ssk;
+
+    sfip_set_ip(&ssk.ip, ip);
+    ssk.proto = proto;
+    ssk.port = port;
+    ssk.level = level;
 
-    if (sfip_family(ip) == AF_INET6)
+    std::map<AppIdServiceStateKey, AppIdServiceIDState*>::iterator it;
+    it = service_state_cache->find(ssk);
+    if( it != service_state_cache->end())
     {
-        k.key6.proto = proto;
-        k.key6.port = port;
-        memcpy(k.key6.ip, ip->ip32, sizeof(k.key6.ip));
-        k.key6.level = level;
-        cache = serviceStateCache6;
+        delete it->second;
+        service_state_cache->erase(it);
     }
     else
-    {
-        k.key4.proto = proto;
-        k.key4.port = port;
-        k.key4.ip = ip->ip32[0];
-        k.key4.level = level;
-        cache = serviceStateCache4;
-    }
-
-    if ((sfxhash_add_return_data_ptr(cache, &k, (void**)&ss) < 0) || !ss)
     {
         char ipstr[INET6_ADDRSTRLEN];
 
+        ipstr[0] = 0;
         sfip_ntop(ip, ipstr, sizeof(ipstr));
-        ErrorMessage("ServiceState: Failed to add to hash: %s:%u:%u:%u\n", ipstr, (unsigned)proto,
-            (unsigned)port, level);
-        return nullptr;
+        ErrorMessage("Failed to remove from hash: %s:%u:%u\n", ipstr, (unsigned)proto, port);
     }
-
-#ifdef DEBUG_SERVICE_STATE
-    char ipstr[INET6_ADDRSTRLEN];
-
-    ipstr[0] = 0;
-    sfip_ntop(ip, ipstr, sizeof(ipstr));
-    DebugFormat(DEBUG_APPID, "ServiceState: Added to hash: %s:%u:%u:%u %p\n", ipstr, (unsigned)proto,
-        (unsigned)port, level, (void*)ss);
-#endif
-
-    return ss;
 }
 
-void dump_service_state_stats(void)
+void AppIdServiceState::dump_stats(void)
 {
+       // FIXIT-L - do we need to keep ipv4 and ipv6 separate?
+#if 0
     LogMessage("Service State:\n");
     if (serviceStateCache4)
     {
@@ -220,5 +203,6 @@ void dump_service_state_stats(void)
         LogMessage("    IPv6 Memory Limit: %lu\n", serviceStateCache6->mc.memcap);
         LogMessage("     IPv6 Memory Used: %lu\n", serviceStateCache6->mc.memused);
     }
+#endif
 }
 
index 6b8832af8d775bd4022c08d7b66cb7b670317473..101fb006ab3c7b1f249c4c5a0fdf365da34cbf56 100644 (file)
 #define SERVICE_STATE_H
 
 #include "sfip/sfip_t.h"
+#include "protocols/protocol_ids.h"
+#include "utils/util.h"
 
 struct RNAServiceElement;
-struct ServiceMatch;
 enum class IpProtocol : uint8_t;
 
 // Service state stored in hosttracker for maintaining service matching states.
 enum SERVICE_ID_STATE
 {
-    /**first search of service. The matching criteria is coded in ProtocolID funtion.
-     */
-    SERVICE_ID_NEW = 0,
-
-    /**service is already detected and valid.
-     */
-    SERVICE_ID_VALID,
-
-    /**match based on source or destination port in first packet in flow.
-     */
-    SERVICE_ID_PORT,
-
-    /**match based on pattern in first response from server or client in
-     * case of client_services.
-     */
-    SERVICE_ID_PATTERN,
-
-    /**match based on round-robin through tcpServiceList or UdpServiceList. RNA walks
-     * the list from first element to last. In a detector declares a flow incompatible
-     * or the flow closes earlier than expected by detector, then the next detector is
-     * tried. This can obviously delay detection under some scenarios.
-     */
-    SERVICE_ID_BRUTE_FORCE,
+    SERVICE_ID_NEW = 0,     // service search starting
+    SERVICE_ID_VALID,       // service detected
+    SERVICE_ID_PORT,        // matched based on src/dest port of first packet
+    SERVICE_ID_PATTERN,     // match based on pattern in first response packet
+    SERVICE_ID_BRUTE_FORCE, // match based on round-robin through tcp/udp service lists
+                            // the lists are walked from first element to last. In a detector
+                            // declares a flow incompatible or the flow closes earlier than
+                            // expected by detector, then the next detector is tried. This can
+                            //  obviously delay detection under some scenarios.
 };
 
 #define DETECTOR_TYPE_PASSIVE   0
@@ -64,21 +51,52 @@ enum SERVICE_ID_STATE
 #define DETECTOR_TYPE_CONFLICT  4
 #define DETECTOR_TYPE_PATTERN   5
 
+struct ServiceMatch
+{
+    struct ServiceMatch* next;
+    unsigned count;
+    unsigned size;
+    RNAServiceElement* svc;
+};
+
 // Service state saved in hosttracker, for identifying a service across multiple flow instances.
 struct AppIdServiceIDState
 {
-    const RNAServiceElement* svc;
+       AppIdServiceIDState()
+       {
+               last_detract.clear();
+               last_invalid_client.clear();
+               reset_time = 0;
+       }
+
+       ~AppIdServiceIDState()
+       {
+           free_service_match_list();
+       }
+
+       void free_service_match_list()
+       {
+           ServiceMatch* sm;
+
+           while( (sm = service_list) )
+           {
+               service_list = sm->next;
+               snort_free(sm);
+           }
+       }
+
+    const RNAServiceElement* svc = nullptr;
 
     /**State of service identification.*/
-    SERVICE_ID_STATE state;
-    unsigned valid_count;
-    unsigned detract_count;
+    SERVICE_ID_STATE state = SERVICE_ID_NEW;
+    unsigned valid_count = 0;
+    unsigned detract_count = 0;
     sfip_t last_detract;
 
     /**Number of consequetive flows that were declared incompatible by detectors. Incompatibility
      * means client packet did not match.
      */
-    unsigned invalid_client_count;
+    unsigned invalid_client_count = 0;
 
     /**IP address of client in last flow that was declared incompatible. If client IP address is
      * different everytime, then consequetive incompatible status indicate that flow is not using
@@ -88,7 +106,7 @@ struct AppIdServiceIDState
 
     /** Count for number of unknown sessions saved
      */
-    unsigned unknowns_logged;
+    unsigned unknowns_logged = 0;
     time_t reset_time;
 
     /**List of ServiceMatch nodes which are sorted in order of pattern match. The list is contructed
@@ -96,40 +114,23 @@ struct AppIdServiceIDState
      * matching, but has the disadvantage of making one flow match dependent on first instance of the
      * same flow.
      */
-    ServiceMatch* service_list;
-    ServiceMatch* current_service;
+    ServiceMatch* service_list = nullptr;
+    ServiceMatch* current_service = nullptr;
 
     /** Is this entry currently being used in an active session? */
-    bool searching;
+    bool searching = false;
 };
 
-struct AppIdServiceStateKey4
-{
-    uint16_t port;
-    IpProtocol proto;
-    uint32_t ip;
-    uint32_t level;
-};
 
-struct AppIdServiceStateKey6
+class AppIdServiceState
 {
-    uint16_t port;
-    IpProtocol proto;
-    uint8_t ip[16];
-    uint32_t level;
+public:
+       static void initialize(unsigned long);
+       static void clean();
+       static AppIdServiceIDState* add( const sfip_t*, IpProtocol proto, uint16_t port, uint32_t level);
+    static AppIdServiceIDState* get( const sfip_t*, IpProtocol proto, uint16_t port, uint32_t level);
+    static void remove(const sfip_t*, IpProtocol proto, uint16_t port, uint32_t level);
+    static void dump_stats();
 };
 
-union AppIdServiceStateKey
-{
-    AppIdServiceStateKey4 key4;
-    AppIdServiceStateKey6 key6;
-};
-
-int init_service_state(unsigned long memcap);
-void clean_service_state();
-void remove_service_id_state(const sfip_t*, IpProtocol proto, uint16_t port, uint32_t level);
-AppIdServiceIDState* get_service_id_state( const sfip_t*, IpProtocol proto, uint16_t port, uint32_t level);
-AppIdServiceIDState* add_service_id_state( const sfip_t*, IpProtocol proto, uint16_t port, uint32_t level);
-void dump_service_state_stats();
-
 #endif
index bc02109ef2fcc20c24aebba6f45e8e2dac53ee01..3e136f6234e345c9d289e9424fb3359777366cfa 100644 (file)
@@ -28,6 +28,8 @@ void IpApi::reset()
 {
     type = IAT_NONE;
     iph = nullptr;
+    src.clear();
+    dst.clear();
 }
 
 void IpApi::set(const IP4Hdr* h4)