]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
initial FlushBucket implementation
authorRuss Combs <rucombs@cisco.com>
Wed, 13 Aug 2014 19:02:20 +0000 (15:02 -0400)
committerRuss Combs <rucombs@cisco.com>
Wed, 13 Aug 2014 19:02:20 +0000 (15:02 -0400)
ChangeLog
src/stream/CMakeLists.txt
src/stream/Makefile.am
src/stream/flush_bucket.cc [new file with mode: 0644]
src/stream/flush_bucket.h [new file with mode: 0644]
src/stream/stream_splitter.cc
src/stream/stream_splitter.h
src/stream/tcp/stream_tcp.cc
src/stream/tcp/tcp_session.cc

index 4329f095990bdae0ada2f2b6adeace5fc14344b2..185fe4cdb0341b104bce25806a967bb4fe391244 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,6 @@
+113
+-- initial FlushBucket implementation
+
 112
 -- initial action plugin - reject
 -- added total to StreamSplitter::reassemble()
index e284e28aa042982c55cccf9ea329d0968955686e..68b59c0789e9bb54584365004bcd034a6233254d 100644 (file)
@@ -11,6 +11,8 @@ set (STREAM_INCLUDES
 )
 
 add_library( stream STATIC
+    flush_bucket.cc
+    flush_bucket.h
     stream.h
     stream_api.cc
     stream_inspectors.cc
index ed95879b283ae44af0a8f5f99cd3139856702c4b..e5a7b13b6cedd112a897ba63d4ac2dc177e1ff52 100644 (file)
@@ -10,6 +10,8 @@ stream_api.h \
 stream_splitter.h
 
 libstream_a_SOURCES = \
+flush_bucket.cc \
+flush_bucket.h \
 stream.h \
 stream_api.cc \
 stream_inspectors.cc \
diff --git a/src/stream/flush_bucket.cc b/src/stream/flush_bucket.cc
new file mode 100644 (file)
index 0000000..9289e25
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+** Copyright (C) 2014 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.
+*/
+// flush_bucket.cc author Russ Combs <rucombs@cisco.com>
+
+#include "flush_bucket.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <random>
+
+#include "protocols/packet.h"
+
+//-------------------------------------------------------------------------
+// static base members
+//-------------------------------------------------------------------------
+
+static THREAD_LOCAL FlushBucket* s_flush_bucket = nullptr;
+
+void FlushBucket::set(FlushBucket* fb)
+{
+    s_flush_bucket = fb;
+}
+
+void FlushBucket::clear()
+{
+    delete s_flush_bucket;
+    s_flush_bucket = nullptr;
+}
+
+uint16_t FlushBucket::get_size()
+{
+    return s_flush_bucket->get_next();
+}
+
+//-------------------------------------------------------------------------
+// thread local data
+//-------------------------------------------------------------------------
+
+#define RAND_FLUSH_POINTS 64
+
+static THREAD_LOCAL uint8_t flush_points[RAND_FLUSH_POINTS] =
+{
+    128, 217, 189, 130, 240, 221, 134, 129,
+    250, 232, 141, 131, 144, 177, 201, 130,
+    230, 190, 177, 142, 130, 200, 173, 129,
+    250, 244, 174, 151, 201, 190, 180, 198,
+    220, 201, 142, 185, 219, 129, 194, 140,
+    145, 191, 197, 183, 199, 220, 231, 245,
+    233, 135, 143, 158, 174, 194, 200, 180,
+    201, 142, 153, 187, 173, 199, 143, 201
+};
+
+//-------------------------------------------------------------------------
+// sub classes
+//-------------------------------------------------------------------------
+
+StaticFlushBucket::StaticFlushBucket()
+{
+    idx = 0;
+}
+
+uint16_t StaticFlushBucket::get_next()
+{
+    return flush_points[idx++];
+}
+
+RandomFlushBucket::RandomFlushBucket()
+{
+    std::default_random_engine generator;
+    std::uniform_int_distribution<int> distribution(128, 255);
+
+    for ( int i = 0; i < RAND_FLUSH_POINTS; i++ )
+    {
+        flush_points[i] = (uint8_t)distribution(generator);
+    }
+}
+
diff --git a/src/stream/flush_bucket.h b/src/stream/flush_bucket.h
new file mode 100644 (file)
index 0000000..58b31cb
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+** Copyright (C) 2014 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.
+*/
+// flush_bucket.h author Russ Combs <rucombs@cisco.com>
+
+#ifndef FLUSH_BUCKET_H
+#define FLUSH_BUCKET_H
+
+#include "main/snort_types.h"
+#include "main/thread.h"
+
+class FlushBucket
+{
+public:
+    virtual ~FlushBucket() { };
+    virtual uint16_t get_next() = 0;
+
+    static uint16_t get_size();
+    static void set(FlushBucket*);
+    static void clear();
+
+protected:
+    FlushBucket() { };
+    static FlushBucket* flush_bucket;
+};
+
+class ConstFlushBucket : public FlushBucket
+{
+public:
+    ConstFlushBucket(uint16_t sz)
+    { size = sz; };
+
+    uint16_t get_next()
+    { return size; };
+
+private:
+    uint16_t size;
+};
+
+class StaticFlushBucket : public FlushBucket
+{
+public:
+    StaticFlushBucket();
+    uint16_t get_next();
+
+private:
+    unsigned idx;
+};
+
+class RandomFlushBucket : public StaticFlushBucket
+{
+public:
+    RandomFlushBucket();
+};
+
+#endif
+
index 78bef421df4b42180ac9352735b91ebb363af6ea..d9857f9aef8179e91cf5e673711ca745a3f29dba 100644 (file)
 */
 // stream_splitter.cc author Russ Combs <rucombs@cisco.com>
 
-#include "stream/stream_splitter.h"
+#include "stream_splitter.h"
 
 #include <assert.h>
 #include <string.h>
 
+#include "flush_bucket.h"
 #include "protocols/packet.h"
 
 static THREAD_LOCAL uint8_t pdu_buf[65536];
@@ -51,8 +52,8 @@ const StreamBuffer* StreamSplitter::reassemble(
 AtomSplitter::AtomSplitter(bool b, uint32_t sz) : StreamSplitter(b)
 {
     reset();
-    // FIXIT get next random flush point unless set explicitly here
-    min = sz ? sz : 192;
+    base = sz;
+    min = base + FlushBucket::get_size();
 }
 
 AtomSplitter::~AtomSplitter() { }
@@ -63,7 +64,7 @@ PAF_Status AtomSplitter::scan(
     bytes += len;
     segs++;
     
-    if ( segs >= 2 && bytes >= 192 )
+    if ( segs >= 2 && bytes >= min )
     {
         *fp = len;
         return PAF_FLUSH;
@@ -79,97 +80,11 @@ void AtomSplitter::reset()
 void AtomSplitter::update()
 {
     reset();
-    // FIXIT get next random flush point unless set explicitly in ctor
-    //min = 192;
+    min = base + FlushBucket::get_size();
 }
 
 #if 0
-// FIXIT PAF atom splitter must implement old-schoold flush criteria
-// 2 or more segments totaling at least N bytes where N is uniform 
-// over 128 to 255
-//
-// ideally it would be a little more flexible too
-
-#define RAND_FLUSH_POINTS 64
-
-static const uint32_t g_static_points[RAND_FLUSH_POINTS] =
-{
-    128, 217, 189, 130, 240, 221, 134, 129,
-    250, 232, 141, 131, 144, 177, 201, 130,
-    230, 190, 177, 142, 130, 200, 173, 129,
-    250, 244, 174, 151, 201, 190, 180, 198,
-    220, 201, 142, 185, 219, 129, 194, 140,
-    145, 191, 197, 183, 199, 220, 231, 245,
-    233, 135, 143, 158, 174, 194, 200, 180,
-    201, 142, 153, 187, 173, 199, 143, 201
-};
-
-#ifndef DYNAMIC_RANDOM_FLUSH_POINTS
-struct FlushPointList
-{
-    uint8_t    current;
-
-    uint32_t   flush_range;
-    uint32_t   flush_base;  /* Set as value - range/2 */
-    /* flush_pt is split evently on either side of flush_value, within
-     * the flush_range.  flush_pt can be from:
-     * (flush_value - flush_range/2) to (flush_value + flush_range/2)
-     *
-     * For example:
-     * flush_value = 192
-     * flush_range = 128
-     * flush_pt will vary from 128 to 256
-     */
-    uint32_t *flush_points;
-};
-#endif
-
-static inline uint32_t GenerateFlushPoint(FlushPointList *flush_point_list)
-{
-    return (rand() % flush_point_list->flush_range) + flush_point_list->flush_base;
-}
-
-static void InitFlushPointList(
-    FlushPointList *flush_point_list, uint32_t value, uint32_t range, int footprint)
-{
-    uint32_t i;
-    uint32_t flush_range = range;
-    uint32_t flush_base = value - range/2;
-
-    const uint32_t cfp = footprint ? footprint : 192;
-
-    flush_point_list->flush_range = flush_range;
-    flush_point_list->flush_base = flush_base;
-
-#ifndef DYNAMIC_RANDOM_FLUSH_POINTS
-    flush_point_list->current = 0;
-
-    flush_point_list->flush_points =
-        (uint32_t*)SnortAlloc(sizeof(uint32_t) * RAND_FLUSH_POINTS);
-
-    for (i=0;i<RAND_FLUSH_POINTS;i++)
-    {
-        if (snort_conf->run_flags & RUN_FLAG__STATIC_HASH)
-        {
-            if ( i == 0 )
-                LogMessage("WARNING:  using constant flush point = %u!\n", cfp);
-
-            flush_point_list->flush_points[i] = cfp;
-        }
-        else if ( !footprint )
-        {
-            if ( i == 0 )
-                LogMessage("WARNING: using static flush points.\n");
-            flush_point_list->flush_points[i] = g_static_points[i];
-        }
-        else
-        {
-            flush_point_list->flush_points[i] = GenerateFlushPoint(flush_point_list);
-        }
-    }
-#endif
-}
-
+// FIXIT this should be part of a new splitter
 static inline int CheckFlushCoercion (
     Packet* p, FlushMgr* fm, uint16_t flush_factor
 ) {
@@ -191,13 +106,5 @@ static inline int CheckFlushCoercion (
     fm->last_count++;
     return 0;
 }
-
-static void Stream5TcpInitFlushPoints(void)
-{
-    int i;
-
-    /* Seed the flushpoint random generator */
-    srand( (unsigned int) sizeof(TcpSession) + (unsigned int) time(NULL) );
-}
 #endif
 
index f1f44d2703380d5cfa3360abf871266fd9cd5c5d..dc8ef8943ee6c6d6afa7749a70cd9cd27cc2f982 100644 (file)
@@ -103,6 +103,7 @@ public:
     void update();
 
 private:
+    uint16_t base;
     uint16_t min;
     uint16_t segs;
     uint16_t bytes;
index 43c43b4ce54b5196023d0841d33064004c34fc59..6a7b52fed21cfcae11f688297da4f0b1e202828c 100644 (file)
@@ -29,6 +29,9 @@
 #include "tcp_module.h"
 #include "tcp_session.h"
 
+#include "main/snort.h"
+#include "stream/flush_bucket.h"
+
 //-------------------------------------------------------------------------
 // inspector stuff
 //-------------------------------------------------------------------------
@@ -42,6 +45,9 @@ public:
     int verify_config(SnortConfig*);
     void show(SnortConfig*);
 
+    void tinit();
+    void tterm();
+
     void eval(Packet*);
 
 public:
@@ -65,8 +71,28 @@ int StreamTcp::verify_config(SnortConfig* sc)
 
 void StreamTcp::show(SnortConfig*)
 {
-    if ( config )
-        tcp_show(config);
+    tcp_show(config);
+}
+
+void StreamTcp::tinit()
+{
+    FlushBucket* fb;
+
+    if ( config->footprint )
+        fb = new ConstFlushBucket(config->footprint);
+
+    else if ( ScStaticHash() )
+        fb = new StaticFlushBucket;
+
+    else
+        fb = new RandomFlushBucket;
+
+    FlushBucket::set(fb);
+}
+
+void StreamTcp::tterm()
+{
+    FlushBucket::clear();
 }
 
 void StreamTcp::eval(Packet*)
index 156eb55121ef3a8957fc94ed9a86e881e6e14540..66639f35de4d3047fad2e879846a47736e51bcde 100644 (file)
@@ -5982,7 +5982,7 @@ static inline int CheckFlushPolicyOnData(
             }
             if ( !flags && listener->splitter->is_paf() )
             {
-                // FIXIT PAF auto disable with multipe splitters?
+                // FIXIT PAF auto disable with multiple splitters?
                 //if ( AutoDisable(listener, talker) )
                 //    return 0;
 
@@ -6114,7 +6114,7 @@ int CheckFlushPolicyOnAck(
             }
             if ( !flags && talker->splitter->is_paf() )
             {
-                // FIXIT PAF auto disable with multipe splitters?
+                // FIXIT PAF auto disable with multiple splitters?
                 //if ( AutoDisable(talker, listener) )
                 //    return 0;