http2_huffman_state_machine.cc
http2_huffman_state_machine.h
http2_inspect.cc
- http2_inspect_impl.cc
http2_inspect.h
http2_module.cc
http2_module.h
http2_start_line.h
http2_status_line.cc
http2_status_line.h
+ http2_stream.cc
+ http2_stream.h
http2_stream_splitter.cc
http2_stream_splitter_impl.cc
http2_stream_splitter.h
#include "http2_frame.h"
#include "http2_module.h"
#include "http2_start_line.h"
+#include "http2_stream.h"
using namespace snort;
using namespace Http2Enums;
uint64_t Http2FlowData::instance_count = 0;
#endif
-Http2FlowData::Http2FlowData() : FlowData(inspector_id)
+Http2FlowData::Http2FlowData() : FlowData(inspector_id), stream(new Http2Stream(this))
{
#ifdef REG_TEST
seq_num = ++instance_count;
{
delete infractions[k];
delete events[k];
- delete current_frame[k];
}
-}
-void Http2FlowData::clear_frame_data(HttpCommon::SourceId source_id)
-{
- frame_in_detection = false;
- continuation_expected[source_id] = false;
- num_frame_headers[source_id] = 0;
- scan_octets_seen[source_id] = 0;
- total_bytes_in_split[source_id] = 0;
- delete current_frame[source_id];
- current_frame[source_id] = nullptr;
+ delete stream;
}
+
friend class Http2SettingsFrame;
friend class Http2StartLine;
friend class Http2StatusLine;
+ friend class Http2Stream;
friend class Http2StreamSplitter;
- friend void implement_eval(Http2FlowData* session_data, HttpCommon::SourceId source_id);
- friend bool implement_get_buf(unsigned id, Http2FlowData*, HttpCommon::SourceId,
- snort::InspectionBuffer&);
friend const snort::StreamBuffer implement_reassemble(Http2FlowData*, unsigned, unsigned,
const uint8_t*, unsigned, uint32_t, HttpCommon::SourceId);
friend snort::StreamSplitter::Status implement_scan(Http2FlowData*, const uint8_t*, uint32_t,
protected:
// 0 element refers to client frame, 1 element refers to server frame
- // Reassemble() signals to eval()
+ // Reassemble() data to eval()
uint8_t* frame_header[2] = { nullptr, nullptr };
uint32_t frame_header_size[2] = { 0, 0 };
uint8_t* frame_data[2] = { nullptr, nullptr };
// Used in eval()
bool frame_in_detection = false;
- class Http2Frame* current_frame[2] = { nullptr, nullptr };
Http2ConnectionSettings connection_settings[2];
Http2HpackDecoder hpack_decoder[2];
+ class Http2Stream* stream;
// Internal to scan()
bool preface[2] = { true, false };
Http2Infractions* infractions[2] = { new Http2Infractions, new Http2Infractions };
Http2EventGen* events[2] = { new Http2EventGen, new Http2EventGen };
- void clear_frame_data(HttpCommon::SourceId source_id);
-
#ifdef REG_TEST
static uint64_t instance_count;
uint64_t seq_num;
#endif
#include "http2_inspect.h"
+
#include "detection/detection_engine.h"
#include "protocols/packet.h"
#include "service_inspectors/http_inspect/http_common.h"
#include "stream/stream.h"
#include "http2_frame.h"
+#include "http2_stream.h"
using namespace snort;
using namespace HttpCommon;
if (!session_data->frame_in_detection)
return false;
- const SourceId source_id = p->is_from_client() ? SRC_CLIENT : SRC_SERVER;
+ const Field& buffer = session_data->stream->get_buf(id);
+ if (buffer.length() <= 0)
+ return false;
- return implement_get_buf(id, session_data, source_id, b);
+ b.data = buffer.start();
+ b.len = buffer.length();
+ return true;
}
bool Http2Inspect::get_fp_buf(InspectionBuffer::Type /*ibt*/, Packet* /*p*/,
if (session_data->frame_type[source_id] == FT__NONE)
return;
- implement_eval(session_data, source_id);
+ session_data->stream->eval_frame(session_data->frame_header[source_id],
+ session_data->frame_header_size[source_id], session_data->frame_data[source_id],
+ session_data->frame_data_size[source_id], source_id);
+
+ // The current frame now owns these buffers, clear them from the flow data
+ session_data->frame_header[source_id] = nullptr;
+ session_data->frame_data[source_id] = nullptr;
session_data->frame_in_detection = true;
#ifdef REG_TEST
if (HttpTestManager::use_test_output(HttpTestManager::IN_HTTP2))
{
- session_data->current_frame[source_id]->print_frame(HttpTestManager::get_output_file());
+ session_data->stream->print_frame(HttpTestManager::get_output_file());
if (HttpTestManager::use_test_input(HttpTestManager::IN_HTTP2))
{
printf("Finished processing section from test %" PRIi64 "\n",
if (session_data == nullptr)
return;
- const SourceId source_id = (p->is_from_client()) ? SRC_CLIENT : SRC_SERVER;
-
- session_data->clear_frame_data(source_id);
+ session_data->frame_in_detection = false;
+ session_data->stream->clear_frame();
}
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2018-2019 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.
-//--------------------------------------------------------------------------
-// http2_inspect_impl.cc author Tom Peters <thopeter@cisco.com>
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "http2_inspect.h"
-#include "http2_enum.h"
-#include "http2_flow_data.h"
-#include "http2_frame.h"
-#include "service_inspectors/http_inspect/http_common.h"
-
-using namespace snort;
-using namespace HttpCommon;
-using namespace Http2Enums;
-
-bool implement_get_buf(unsigned id, Http2FlowData* session_data, SourceId source_id,
- InspectionBuffer& b)
-{
- const Field& buffer = session_data->current_frame[source_id]->get_buf(id);
- if (buffer.length() <= 0)
- return false;
- b.data = buffer.start();
- b.len = buffer.length();
- return true;
-}
-
-void implement_eval(Http2FlowData* session_data, SourceId source_id)
-{
- // Construct the appropriate frame class
- session_data->current_frame[source_id] = Http2Frame::new_frame(
- session_data->frame_header[source_id], session_data->frame_header_size[source_id],
- session_data->frame_data[source_id], session_data->frame_data_size[source_id],
- session_data, source_id);
- // The current frame now owns these buffers, clear them from the flow data
- session_data->frame_header[source_id] = nullptr;
- session_data->frame_data[source_id] = nullptr;
-}
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2019 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.
+//--------------------------------------------------------------------------
+// http2_stream.cc author Tom Peters <thopeter@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "http2_stream.h"
+
+using namespace HttpCommon;
+
+Http2Stream::Http2Stream(Http2FlowData* session_data_) : session_data(session_data_)
+{
+}
+
+Http2Stream::~Http2Stream()
+{
+ delete current_frame;
+}
+
+void Http2Stream::eval_frame(const uint8_t* header_buffer, int32_t header_len,
+ const uint8_t* data_buffer, int32_t data_len, SourceId source_id)
+{
+ delete current_frame;
+ current_frame = Http2Frame::new_frame(header_buffer, header_len, data_buffer,
+ data_len, session_data, source_id);
+}
+
+void Http2Stream::clear_frame()
+{
+ delete current_frame;
+ current_frame = nullptr;
+}
+
+const Field& Http2Stream::get_buf(unsigned id)
+{
+ if (current_frame != nullptr)
+ return current_frame->get_buf(id);
+ return Field::FIELD_NULL;
+}
+
+#ifdef REG_TEST
+void Http2Stream::print_frame(FILE* output)
+{
+ if (current_frame != nullptr)
+ current_frame->print_frame(output);
+}
+#endif
+
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2019-2019 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.
+//--------------------------------------------------------------------------
+// http2_stream.h author Tom Peters <thopeter@cisco.com>
+
+#ifndef HTTP2_STREAM_H
+#define HTTP2_STREAM_H
+
+#include "service_inspectors/http_inspect/http_common.h"
+#include "service_inspectors/http_inspect/http_field.h"
+
+#include "http2_flow_data.h"
+#include "http2_frame.h"
+
+class Http2Stream
+{
+public:
+ Http2Stream(Http2FlowData* session_data_);
+ ~Http2Stream();
+ void eval_frame(const uint8_t* header_buffer, int32_t header_len, const uint8_t* data_buffer,
+ int32_t data_len, HttpCommon::SourceId source_id);
+ void clear_frame();
+ const Field& get_buf(unsigned id);
+#ifdef REG_TEST
+ void print_frame(FILE* output);
+#endif
+
+private:
+ Http2FlowData* const session_data;
+ Http2Frame* current_frame = nullptr;
+};
+
+#endif
}
else
{
- // FIXIT-M CONTINUATION frames can also follow PUSH_PROMISE frames, which is
- // not currently supported
+ // FIXIT-M CONTINUATION frames can also follow PUSH_PROMISE frames, which
+ // are not currently supported
*session_data->infractions[source_id] += INF_UNEXPECTED_CONTINUATION;
session_data->events[source_id]->create_event(
EVENT_UNEXPECTED_CONTINUATION);
if (flags & PKT_PDU_TAIL)
{
+ session_data->total_bytes_in_split[source_id] = 0;
+ session_data->num_frame_headers[source_id] = 0;
+ session_data->scan_octets_seen[source_id] = 0;
+
// Return 0-length non-null buffer to stream which signals detection required, but don't
// create pkt_data buffer
frame_buf.data = (const uint8_t*)"";
}
session_data->frame_type[source_id] = get_frame_type(session_data->frame_header[source_id]);
+
return frame_buf;
}
-add_cpputest( http2_stream_splitter_impl_test
- SOURCES
- ../http2_flow_data.cc
- ../http2_hpack_dynamic_table.cc
- ../http2_hpack_table.cc
- ../http2_stream_splitter_impl.cc
- ../http2_module.cc
- ../http2_tables.cc
- ../../../framework/module.cc
-)
add_cpputest( http2_hpack_int_decode_test
SOURCES
../http2_hpack_int_decode.cc
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2018-2019 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.
-//--------------------------------------------------------------------------
-
-// http2_flow_data_test.h author Tom Peters <thopeter@cisco.com>
-
-#ifndef HTTP2_FLOW_DATA_TEST_H
-#define HTTP2_FLOW_DATA_TEST_H
-
-#include "service_inspectors/http_inspect/http_common.h"
-//#include "service_inspectors/http2_inspect/http2_enum.h"
-#include "service_inspectors/http2_inspect/http2_flow_data.h"
-#include "service_inspectors/http2_inspect/http2_module.h"
-
-// Stubs whose sole purpose is to make the test code link
-snort::FlowData::FlowData(unsigned u, Inspector* ph) : next(nullptr), prev(nullptr), handler(ph), id(u) {}
-snort::FlowData::~FlowData() = default;
-unsigned snort::FlowData::flow_data_id = 0;
-void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
-void show_stats(PegCount*, const PegInfo*, const IndexVec&, const char*, FILE*) { }
-
-class Http2FlowDataTest : public Http2FlowData
-{
-public:
- bool get_preface(HttpCommon::SourceId source_id) { return preface[source_id]; }
- void set_preface(bool value, HttpCommon::SourceId source_id) { preface[source_id] = value; }
- bool get_num_frame_headers(HttpCommon::SourceId source_id) { return num_frame_headers[source_id]; }
- void set_num_frame_headers(bool value, HttpCommon::SourceId source_id)
- { num_frame_headers[source_id] = value; }
- uint8_t* get_frame_header(HttpCommon::SourceId source_id) { return frame_header[source_id]; }
- void set_frame_header(uint8_t* value, uint32_t length, HttpCommon::SourceId source_id)
- { frame_header[source_id] = value; frame_header_size[source_id] = length; }
- uint8_t* get_scan_frame_header(HttpCommon::SourceId source_id)
- { return scan_frame_header[source_id]; }
- uint8_t* get_frame_data(HttpCommon::SourceId source_id) { return frame_data[source_id]; }
- void set_frame_data(uint8_t* value, HttpCommon::SourceId source_id)
- { frame_data[source_id] = value; }
- uint32_t get_frame_data_size(HttpCommon::SourceId source_id)
- { return frame_data_offset[source_id]; }
- void set_frame_data_size(uint32_t value, HttpCommon::SourceId source_id)
- { frame_data_size[source_id] = value; }
- uint32_t get_leftover_data(HttpCommon::SourceId source_id) { return leftover_data[source_id]; }
- void set_leftover_data(uint32_t value, HttpCommon::SourceId source_id)
- { leftover_data[source_id] = value; }
- void set_total_bytes_in_split(uint32_t value, HttpCommon::SourceId source_id)
- { total_bytes_in_split[source_id] = value; }
- void set_octets_before_first_header(uint32_t value, HttpCommon::SourceId source_id)
- { octets_before_first_header[source_id] = value; }
- void cleanup()
- {
- for (int k = 0; k < 2; k++)
- {
- delete[] frame_header[k];
- delete[] frame_data[k];
- }
- }
-};
-
-#endif
-
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2018-2019 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.
-//--------------------------------------------------------------------------
-
-// http2_stream_splitter_test.cc author Tom Peters <thopeter@cisco.com>
-// unit test main
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-
-#include "protocols/packet.h"
-#include "service_inspectors/http_inspect/http_common.h"
-#include "service_inspectors/http_inspect/http_test_manager.h"
-#include "service_inspectors/http2_inspect/http2_enum.h"
-#include "service_inspectors/http2_inspect/http2_flow_data.h"
-#include "service_inspectors/http2_inspect/http2_stream_splitter.h"
-
-#include "http2_flow_data_test.h"
-
-#include <CppUTest/CommandLineTestRunner.h>
-#include <CppUTest/TestHarness.h>
-#include <CppUTestExt/MockSupport.h>
-
-using namespace snort;
-using namespace HttpCommon;
-using namespace Http2Enums;
-
-// Stubs whose sole purpose is to make the test code link
-unsigned HttpTestManager::test_input = IN_NONE;
-unsigned HttpTestManager::test_output = IN_NONE;
-FILE* HttpTestManager::test_out = nullptr ;
-int DetectionEngine::queue_event(unsigned int, unsigned int, Actions::Type) { return 0; }
-void Field::set(int, unsigned char const*, bool) {}
-
-#ifdef REG_TEST
-void Field::print(_IO_FILE*, char const*) const {}
-#endif
-
-TEST_GROUP(http2_scan_test)
-{
- Http2FlowDataTest* session_data = nullptr;
- uint32_t flush_offset = 0;
-
- void setup() override
- {
- session_data = new Http2FlowDataTest();
- CHECK(session_data != nullptr);
- }
-
- void teardown() override
- {
- delete session_data;
- }
-};
-
-TEST(http2_scan_test, basic_with_header)
-{
- session_data->set_preface(false, SRC_CLIENT);
- const StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"\x00\x00\x0A\x02\x00\x00\x00\x00\x00" "0123456789ABCDEFG",
- 26, &flush_offset, SRC_CLIENT);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 19);
- CHECK(session_data->get_num_frame_headers(SRC_CLIENT) == 1);
-}
-
-TEST(http2_scan_test, basic_with_header_s2c)
-{
- const StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"\x00\x00\x0A\x02\x00\x00\x00\x00\x00" "0123456789ABCDEFG",
- 26, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 19);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 1);
-}
-
-TEST(http2_scan_test, header_without_data)
-{
- session_data->set_preface(false, SRC_CLIENT);
- const StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"\x00\x00\x0A\x02\x00\x00\x00\x00\x00",
- 9, &flush_offset, SRC_CLIENT);
- CHECK(result == StreamSplitter::SEARCH);
- CHECK(flush_offset == 0);
- CHECK(session_data->get_num_frame_headers(SRC_CLIENT) == 1);
-}
-
-TEST(http2_scan_test, preface_and_more)
-{
- const StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\nABCDEFGHIJKLMNOPQRSTUVWXYZ",
- 50, &flush_offset, SRC_CLIENT);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 24);
- CHECK(session_data->get_num_frame_headers(SRC_CLIENT) == 0);
-}
-
-TEST(http2_scan_test, preface_exactly)
-{
- const StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n",
- 24, &flush_offset, SRC_CLIENT);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 24);
- CHECK(session_data->get_num_frame_headers(SRC_CLIENT) == 0);
-}
-
-TEST(http2_scan_test, short_input)
-{
- session_data->set_preface(false, SRC_SERVER);
- StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"\x00\x00\x10",
- 3, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::SEARCH);
- result = implement_scan(session_data, (const uint8_t*)"\x04\x05\x06", 3, &flush_offset,
- SRC_SERVER);
- CHECK(result == StreamSplitter::SEARCH);
- result = implement_scan(session_data, (const uint8_t*)"\x07\x08\x09" "0123456789ABCDEF", 19, &flush_offset,
- SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 19);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 1);
- CHECK(memcmp(session_data->get_scan_frame_header(SRC_SERVER),
- "\x00\x00\x10\x04\x05\x06\x07\x08\x09", 9) == 0);
-}
-
-TEST(http2_scan_test, oversize_non_data_frame)
-{
- session_data->set_preface(false, SRC_CLIENT);
- const StreamSplitter::Status result = implement_scan(session_data,
- (const uint8_t*)"\x00\xF9\x1C\x01" "12345678901234567",
- 21, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::ABORT);
-}
-
-TEST(http2_scan_test, maximum_frame)
-{
- uint8_t data[63870] = { 'A' };
- memcpy(data,"\x00\xF9\x1B\x04", 4);
- const StreamSplitter::Status result = implement_scan(session_data,
- data, 63780, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 63780);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 1);
-}
-
-TEST(http2_scan_test, data_sections)
-{
- uint8_t data[DATA_SECTION_SIZE+9] ={ 'A' };
- memcpy(data,"\x01\x21\x3C\x00\x00\x00\x00\x00\x00", 9);
- StreamSplitter::Status result = implement_scan(session_data,
- data, DATA_SECTION_SIZE + 9, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == DATA_SECTION_SIZE + 9);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 1);
- CHECK(session_data->get_leftover_data(SRC_SERVER) == 0xE13C);
- result = implement_scan(session_data,
- data, DATA_SECTION_SIZE, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == DATA_SECTION_SIZE);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 0);
- result = implement_scan(session_data,
- data, DATA_SECTION_SIZE, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == DATA_SECTION_SIZE);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 0);
- result = implement_scan(session_data,
- data, DATA_SECTION_SIZE, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == DATA_SECTION_SIZE);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 0);
- result = implement_scan(session_data,
- data, 8508, &flush_offset, SRC_SERVER);
- CHECK(result == StreamSplitter::FLUSH);
- CHECK(flush_offset == 8508);
- CHECK(session_data->get_num_frame_headers(SRC_SERVER) == 0);
- CHECK(session_data->get_leftover_data(SRC_SERVER) == 0);
-}
-
-TEST_GROUP(http2_reassemble_test)
-{
- Http2FlowDataTest* session_data = nullptr;
-
- void setup() override
- {
- session_data = new Http2FlowDataTest();
- CHECK(session_data != nullptr);
- }
-
- void teardown() override
- {
- session_data->cleanup();
- delete session_data;
- }
-};
-
-TEST(http2_reassemble_test, basic_with_header)
-{
- session_data->set_num_frame_headers(1, SRC_CLIENT);
- session_data->set_total_bytes_in_split(19, SRC_CLIENT);
- implement_reassemble(session_data, 19, 0,
- (const uint8_t*)"\x00\x00\x0A\x02\x00\x00\x00\x00\x00" "0123456789",
- 19, PKT_PDU_TAIL, SRC_CLIENT);
- CHECK(session_data->get_frame_data_size(SRC_CLIENT) == 10);
- CHECK(memcmp(session_data->get_frame_data(SRC_CLIENT), "0123456789", 10) == 0);
-}
-
-TEST(http2_reassemble_test, basic_with_header_s2c)
-{
- session_data->set_num_frame_headers(1, SRC_SERVER);
- session_data->set_total_bytes_in_split(19, SRC_SERVER);
- implement_reassemble(session_data, 19, 0,
- (const uint8_t*)"\x00\x00\x0A\x02\x00\x00\x00\x00\x00" "0123456789",
- 19, PKT_PDU_TAIL, SRC_SERVER);
- CHECK(session_data->get_frame_data_size(SRC_SERVER) == 10);
- CHECK(memcmp(session_data->get_frame_data(SRC_SERVER), "0123456789", 10) == 0);
-}
-
-TEST(http2_reassemble_test, basic_without_header)
-{
- session_data->set_num_frame_headers(0, SRC_CLIENT);
- session_data->set_octets_before_first_header(24, SRC_CLIENT);
- session_data->set_total_bytes_in_split(24, SRC_CLIENT);
- implement_reassemble(session_data, 24, 0,
- (const uint8_t*)"PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n",
- 24, PKT_PDU_TAIL, SRC_CLIENT);
- CHECK(session_data->get_frame_data_size(SRC_CLIENT) == 24);
- CHECK(memcmp(session_data->get_frame_data(SRC_CLIENT), "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", 24) == 0);
-}
-
-TEST(http2_reassemble_test, basic_three_pieces)
-{
- session_data->set_num_frame_headers(1, SRC_CLIENT);
- session_data->set_total_bytes_in_split(19, SRC_CLIENT);
- StreamBuffer buffer = implement_reassemble(session_data, 19, 0,
- (const uint8_t*)"\x00\x00\x0A\x02\x00\x00",
- 6, 0, SRC_CLIENT);
- CHECK(buffer.length == 0);
- CHECK(session_data->get_frame_data_size(SRC_CLIENT) == 0);
- implement_reassemble(session_data, 19, 6,
- (const uint8_t*)"\x00\x00\x00" "01234",
- 8, 0, SRC_CLIENT);
- buffer = implement_reassemble(session_data, 19, 14,
- (const uint8_t*)"56789",
- 5, PKT_PDU_TAIL, SRC_CLIENT);
- CHECK(buffer.length == 0);
- CHECK(session_data->get_frame_data_size(SRC_CLIENT) == 10);
- CHECK(memcmp(session_data->get_frame_data(SRC_CLIENT), "0123456789", 10) == 0);
-}
-
-TEST(http2_reassemble_test, basic_without_header_two_pieces)
-{
- session_data->set_num_frame_headers(0, SRC_CLIENT);
- session_data->set_octets_before_first_header(24, SRC_CLIENT);
- session_data->set_total_bytes_in_split(24, SRC_CLIENT);
- implement_reassemble(session_data, 24, 0,
- (const uint8_t*)"P",
- 1, 0, SRC_CLIENT);
- CHECK(session_data->get_frame_data_size(SRC_CLIENT) == 1);
- CHECK(memcmp(session_data->get_frame_data(SRC_CLIENT), "P", 1) == 0);
- implement_reassemble(session_data, 24, 1,
- (const uint8_t*)"RI * HTTP/2.0\r\n\r\nSM\r\n\r\n",
- 23, PKT_PDU_TAIL, SRC_CLIENT);
- CHECK(session_data->get_frame_data_size(SRC_CLIENT) == 24);
- CHECK(memcmp(session_data->get_frame_data(SRC_CLIENT), "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", 24) == 0);
-}
-
-int main(int argc, char** argv)
-{
- return CommandLineTestRunner::RunAllTests(argc, argv);
-}
-