From: Russ Combs Date: Wed, 13 Aug 2014 19:02:20 +0000 (-0400) Subject: initial FlushBucket implementation X-Git-Tag: 3.0.0-233~1426^2~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d690d3e6d9864d538405541b62450ffa8533bca7;p=thirdparty%2Fsnort3.git initial FlushBucket implementation --- diff --git a/ChangeLog b/ChangeLog index 4329f0959..185fe4cdb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,6 @@ +113 +-- initial FlushBucket implementation + 112 -- initial action plugin - reject -- added total to StreamSplitter::reassemble() diff --git a/src/stream/CMakeLists.txt b/src/stream/CMakeLists.txt index e284e28aa..68b59c078 100644 --- a/src/stream/CMakeLists.txt +++ b/src/stream/CMakeLists.txt @@ -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 diff --git a/src/stream/Makefile.am b/src/stream/Makefile.am index ed95879b2..e5a7b13b6 100644 --- a/src/stream/Makefile.am +++ b/src/stream/Makefile.am @@ -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 index 000000000..9289e2525 --- /dev/null +++ b/src/stream/flush_bucket.cc @@ -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 + +#include "flush_bucket.h" + +#include +#include + +#include + +#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 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 index 000000000..58b31cbcf --- /dev/null +++ b/src/stream/flush_bucket.h @@ -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 + +#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 + diff --git a/src/stream/stream_splitter.cc b/src/stream/stream_splitter.cc index 78bef421d..d9857f9ae 100644 --- a/src/stream/stream_splitter.cc +++ b/src/stream/stream_splitter.cc @@ -18,11 +18,12 @@ */ // stream_splitter.cc author Russ Combs -#include "stream/stream_splitter.h" +#include "stream_splitter.h" #include #include +#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;irun_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 diff --git a/src/stream/stream_splitter.h b/src/stream/stream_splitter.h index f1f44d270..dc8ef8943 100644 --- a/src/stream/stream_splitter.h +++ b/src/stream/stream_splitter.h @@ -103,6 +103,7 @@ public: void update(); private: + uint16_t base; uint16_t min; uint16_t segs; uint16_t bytes; diff --git a/src/stream/tcp/stream_tcp.cc b/src/stream/tcp/stream_tcp.cc index 43c43b4ce..6a7b52fed 100644 --- a/src/stream/tcp/stream_tcp.cc +++ b/src/stream/tcp/stream_tcp.cc @@ -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*) diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index 156eb5512..66639f35d 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -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;