+113
+-- initial FlushBucket implementation
+
112
-- initial action plugin - reject
-- added total to StreamSplitter::reassemble()
)
add_library( stream STATIC
+ flush_bucket.cc
+ flush_bucket.h
stream.h
stream_api.cc
stream_inspectors.cc
stream_splitter.h
libstream_a_SOURCES = \
+flush_bucket.cc \
+flush_bucket.h \
stream.h \
stream_api.cc \
stream_inspectors.cc \
--- /dev/null
+/*
+** 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);
+ }
+}
+
--- /dev/null
+/*
+** 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
+
*/
// 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];
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() { }
bytes += len;
segs++;
- if ( segs >= 2 && bytes >= 192 )
+ if ( segs >= 2 && bytes >= min )
{
*fp = len;
return PAF_FLUSH;
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
) {
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
void update();
private:
+ uint16_t base;
uint16_t min;
uint16_t segs;
uint16_t bytes;
#include "tcp_module.h"
#include "tcp_session.h"
+#include "main/snort.h"
+#include "stream/flush_bucket.h"
+
//-------------------------------------------------------------------------
// inspector stuff
//-------------------------------------------------------------------------
int verify_config(SnortConfig*);
void show(SnortConfig*);
+ void tinit();
+ void tterm();
+
void eval(Packet*);
public:
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*)
}
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;
}
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;