]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2540 in SNORT/snort3 from ~KATHARVE/snort3:h2i_pp1 to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 16 Oct 2020 13:27:27 +0000 (13:27 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 16 Oct 2020 13:27:27 +0000 (13:27 +0000)
Squashed commit of the following:

commit 27d03d91f9629cd4565cfb17ebaf3b85fac978d0
Author: Katura Harvey <katharve@cisco.com>
Date:   Fri Oct 9 10:00:19 2020 -0400

    http2_inspect: handle stream creation for push promise frames

16 files changed:
src/service_inspectors/http2_inspect/CMakeLists.txt
src/service_inspectors/http2_inspect/http2_enum.h
src/service_inspectors/http2_inspect/http2_flow_data.cc
src/service_inspectors/http2_inspect/http2_flow_data.h
src/service_inspectors/http2_inspect/http2_frame.cc
src/service_inspectors/http2_inspect/http2_headers_frame_trailer.cc
src/service_inspectors/http2_inspect/http2_hpack_table.cc
src/service_inspectors/http2_inspect/http2_inspect.cc
src/service_inspectors/http2_inspect/http2_push_promise_frame.cc [new file with mode: 0644]
src/service_inspectors/http2_inspect/http2_push_promise_frame.h [new file with mode: 0644]
src/service_inspectors/http2_inspect/http2_settings_frame.cc
src/service_inspectors/http2_inspect/http2_settings_frame.h
src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc
src/service_inspectors/http2_inspect/http2_tables.cc
src/service_inspectors/http2_inspect/http2_utils.cc
src/service_inspectors/http2_inspect/http2_utils.h

index c44b395ea37b3b9251ff8644835b49c404f41f0d..8ac11eef373de05c97f90378efda99374ff3fa35 100644 (file)
@@ -33,6 +33,8 @@ set (FILE_LIST
     http2_inspect.h
     http2_module.cc
     http2_module.h
+    http2_push_promise_frame.cc
+    http2_push_promise_frame.h
     http2_request_line.cc
     http2_request_line.h
     http2_settings_frame.cc
index d30ab3771a5f41a98ffab2e2becbdab6d996a9b3..6ee57d3eda24a25a4bd1751bc86447a4320052b6 100644 (file)
@@ -75,6 +75,14 @@ enum EventSid
     EVENT_TRAILERS_NOT_END = 20,
     EVENT_PADDING_ON_INVALID_FRAME = 21,
     EVENT_PADDING_ON_EMPTY_FRAME = 22,
+    EVENT_C2S_PUSH = 23,
+    EVENT_INVALID_PUSH_FRAME = 24,
+    EVENT_BAD_PUSH_SEQUENCE = 25,
+    EVENT_BAD_SETTINGS_VALUE = 26,
+    EVENT_PUSH_WHEN_PROHIBITED = 27,
+    EVENT_INVALID_PROMISED_STREAM = 28,
+    EVENT_INVALID_STREAM_ID = 29,
+    EVENT_INVALID_FLAG = 30,
     EVENT__MAX_VALUE
 };
 
@@ -94,7 +102,7 @@ enum Infraction
     INF_HUFFMAN_INCOMPLETE_CODE_PADDING = 9,
     INF_MISSING_CONTINUATION = 10,
     INF_UNEXPECTED_CONTINUATION = 11,
-    INF_UNUSED_1 = 12,
+    INF_C2S_PUSH = 12,
     INF_INVALID_PSEUDO_HEADER = 13,
     INF_PSEUDO_HEADER_AFTER_REGULAR_HEADER = 14,
     INF_PSEUDO_HEADER_URI_FORM_MISMATCH = 15,
@@ -110,11 +118,17 @@ enum Infraction
     INF_INVALID_STARTLINE = 25,
     INF_INVALID_HEADER = 26,
     INF_PADDING_LEN = 27,
-    INF_UNUSED_2 = 28,
+    INF_PUSH_FRAME_TOO_SHORT = 28,
     INF_PSEUDO_HEADER_IN_TRAILERS = 29,
     INF_TRAILERS_NOT_END = 30,
     INF_PADDING_ON_INVALID_FRAME = 31,
     INF_PADDING_ON_EMPTY_FRAME = 32,
+    INF_BAD_PUSH_SEQUENCE = 33,
+    INF_BAD_SETTINGS_PUSH_VALUE = 34,
+    INF_PUSH_WHEN_PROHIBITED = 35,
+    INF_INVALID_PROMISED_STREAM = 36,
+    INF_INVALID_STREAM_ID = 37,
+    INF_INVALID_FLAG = 38,
     INF__MAX_VALUE
 };
 
index 89d8d055127530d86e301c6654c1dee684fed60b..e8cbd0d8841acb908ae8c9a374227baa3f5cb498 100644 (file)
@@ -29,6 +29,7 @@
 #include "http2_enum.h"
 #include "http2_frame.h"
 #include "http2_module.h"
+#include "http2_push_promise_frame.h"
 #include "http2_start_line.h"
 #include "http2_stream.h"
 
@@ -156,6 +157,22 @@ class Http2Stream* Http2FlowData::get_current_stream(const HttpCommon::SourceId
     return get_stream(current_stream[source_id]);
 }
 
+// processing stream is the current stream except for push promise frames with properly formatted
+// promised stream IDs
+class Http2Stream* Http2FlowData::get_processing_stream(const HttpCommon::SourceId source_id)
+{
+    if (processing_stream_id[source_id] == NO_STREAM_ID)
+    {
+        if (frame_type[source_id] == FT_PUSH_PROMISE)
+            processing_stream_id[source_id] = Http2PushPromiseFrame::get_promised_stream_id(
+                events[source_id], infractions[source_id], frame_data[source_id],
+                frame_data_size[source_id]);
+        if (processing_stream_id[source_id] == NO_STREAM_ID)
+            processing_stream_id[source_id] = current_stream[source_id];
+    }
+    return get_stream(processing_stream_id[source_id]);
+}
+
 uint32_t Http2FlowData::get_current_stream_id(const HttpCommon::SourceId source_id)
 {
     return current_stream[source_id];
index f3e5f49729137c6291c23ed52d04196b44e19cca..b38e354d1ebd9f5bc39a3fbc37e47fa13f01fcce 100644 (file)
@@ -69,6 +69,7 @@ public:
     friend class Http2HeadersFrameTrailer;
     friend class Http2Hpack;
     friend class Http2Inspect;
+    friend class Http2PushPromiseFrame;
     friend class Http2RequestLine;
     friend class Http2SettingsFrame;
     friend class Http2StartLine;
@@ -92,11 +93,14 @@ public:
     };
     class Http2Stream* get_current_stream(const HttpCommon::SourceId source_id);
     uint32_t get_current_stream_id(const HttpCommon::SourceId source_id);
+    class Http2Stream* get_processing_stream(const HttpCommon::SourceId source_id);
 
     Http2HpackDecoder* get_hpack_decoder(const HttpCommon::SourceId source_id)
     { return &hpack_decoder[source_id]; }
-    Http2ConnectionSettings* get_connection_settings(const HttpCommon::SourceId source_id)
+    Http2ConnectionSettings* get_my_connection_settings(const HttpCommon::SourceId source_id)
     { return &connection_settings[source_id]; }
+    Http2ConnectionSettings* get_recipient_connection_settings(const HttpCommon::SourceId source_id)
+    { return &connection_settings[1 - source_id]; }
 
     bool is_mid_frame(const HttpCommon::SourceId source_id = HttpCommon::SRC_SERVER)
     { return (continuation_expected[source_id] || reading_frame[source_id]); }
@@ -120,8 +124,12 @@ protected:
     Http2Infractions* const infractions[2] = { new Http2Infractions, new Http2Infractions };
     Http2EventGen* const events[2] = { new Http2EventGen, new Http2EventGen };
 
-    // Stream ID of the frame currently being read in and processed
+    // Stream ID of the frame currently being processed was sent on (i.e. the stream in the frame
+    // header). This is set in scan().
     uint32_t current_stream[2] = { Http2Enums::NO_STREAM_ID, Http2Enums::NO_STREAM_ID };
+    // Stream ID of the stream responsible for processing the current frame. This will be the same
+    // as current_stream except when processing a push_promise frame. This is set in eval().
+    uint32_t processing_stream_id[2] = { Http2Enums::NO_STREAM_ID, Http2Enums::NO_STREAM_ID };
     // At any given time there may be different streams going in each direction. But only one of
     // them is the stream that http_inspect is actually processing at the moment.
     uint32_t stream_in_hi = Http2Enums::NO_STREAM_ID;
index fd1ec4159e3ad2be9c680ffb15a9dd30f0a77be3..eb6cfea3d7ec2bf1912a4981e1f9f12bdcbcc0fd 100644 (file)
@@ -28,6 +28,7 @@
 #include "http2_flow_data.h"
 #include "http2_headers_frame_header.h"
 #include "http2_headers_frame_trailer.h"
+#include "http2_push_promise_frame.h"
 #include "http2_settings_frame.h"
 #include "http2_stream.h"
 #include "service_inspectors/http_inspect/http_field.h"
@@ -67,6 +68,9 @@ Http2Frame* Http2Frame::new_frame(const uint8_t* header, const uint32_t header_l
         case FT_DATA:
             return new Http2DataFrame(header, header_len, data, data_len, session_data, source_id,
                 stream);
+        case FT_PUSH_PROMISE:
+            return new Http2PushPromiseFrame(header, header_len, data, data_len, session_data,
+                source_id, stream);
         default:
             return new Http2Frame(header, header_len, data, data_len, session_data, source_id,
                 stream);
index 4739e65a35da8fa8506208120cd7ef9f7c3b91fe..442a59e7a1e36d39118b9de2f4ebbe341b62cf4a 100644 (file)
@@ -66,7 +66,14 @@ Http2HeadersFrameTrailer::Http2HeadersFrameTrailer(const uint8_t* header_buffer,
 
 bool Http2HeadersFrameTrailer::valid_sequence(Http2Enums::StreamState state)
 {
-    return (state == Http2Enums::STREAM_EXPECT_BODY) || (state == Http2Enums::STREAM_BODY);
+    if ((state == STREAM_EXPECT_BODY) || (state == STREAM_BODY))
+        return true;
+    if (state == STREAM_COMPLETE)
+    {
+        *session_data->infractions[source_id] += INF_FRAME_SEQUENCE;
+        session_data->events[source_id]->create_event(EVENT_FRAME_SEQUENCE);
+    }
+    return false;
 }
 
 void Http2HeadersFrameTrailer::analyze_http1()
index e5b03d0d05e0e9c477c3d55341a699bf4c655388..93e33682ade8f83c1086b85a3d66aeaf9c884c8f 100644 (file)
@@ -138,7 +138,7 @@ void HpackIndexTable::settings_table_size_update(uint32_t new_size)
 bool HpackIndexTable::hpack_table_size_update(uint32_t new_size)
 {
     encoder_set_max_size = true;
-    if (new_size <= session_data->get_connection_settings((HttpCommon::SourceId)(1 - source_id))->
+    if (new_size <= session_data->get_recipient_connection_settings(source_id)->
         get_param(HEADER_TABLE_SIZE))
     {
        dynamic_table.update_size(new_size);
index cdd35e94c4f5d874088798c5a831ec79f8043d9f..fb8508782a4e18bd9313c0edf5b59ca658c677e1 100644 (file)
@@ -130,7 +130,9 @@ void Http2Inspect::eval(Packet* p)
         return;
     }
 
-    Http2Stream* stream = session_data->get_current_stream(source_id);
+    Http2Stream* stream = session_data->get_processing_stream(source_id);
+    assert(session_data->processing_stream_id[source_id] != NO_STREAM_ID);
+    assert(stream);
     session_data->stream_in_hi = stream->get_stream_id();
 
     stream->eval_frame(session_data->frame_header[source_id],
@@ -183,9 +185,10 @@ void Http2Inspect::clear(Packet* p)
 
     const SourceId source_id = p->is_from_client() ? SRC_CLIENT : SRC_SERVER;
 
-    Http2Stream* stream = session_data->get_current_stream(source_id);
+    Http2Stream* stream = session_data->get_processing_stream(source_id);
     stream->clear_frame();
     session_data->stream_in_hi = NO_STREAM_ID;
+    session_data->processing_stream_id[source_id] = NO_STREAM_ID;
 }
 
 #ifdef REG_TEST
diff --git a/src/service_inspectors/http2_inspect/http2_push_promise_frame.cc b/src/service_inspectors/http2_inspect/http2_push_promise_frame.cc
new file mode 100644 (file)
index 0000000..e1b994e
--- /dev/null
@@ -0,0 +1,130 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 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_push_promise_frame.cc author Katura Harvey <katharve@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "http2_push_promise_frame.h"
+
+#include "http2_flow_data.h"
+#include "http2_stream.h"
+#include "http2_utils.h"
+
+using namespace HttpCommon;
+using namespace Http2Enums;
+
+Http2PushPromiseFrame::Http2PushPromiseFrame(const uint8_t* header_buffer,
+    const uint32_t header_len, const uint8_t* data_buffer, const uint32_t data_len,
+    Http2FlowData* session_data_, HttpCommon::SourceId source_id_, Http2Stream* stream_) :
+    Http2Frame(header_buffer, header_len, data_buffer, data_len, session_data_, source_id_, stream_)
+{
+    // If this was a short frame, it's being processed by the stream that sent it. We've already
+    // alerted
+    if (data_len < PROMISED_ID_LENGTH)
+        return;
+
+    // Server-initiated streams must be even
+    if (source_id == SRC_SERVER and stream->get_stream_id() % 2 != 0)
+    {
+        *session_data->infractions[source_id] += INF_INVALID_STREAM_ID;
+        session_data->events[source_id]->create_event(EVENT_INVALID_STREAM_ID);
+    }
+
+    if (session_data->get_recipient_connection_settings(source_id)->get_param(ENABLE_PUSH) == 0)
+    {
+        session_data->events[source_id]->create_event(EVENT_PUSH_WHEN_PROHIBITED);
+        *session_data->infractions[source_id] += INF_PUSH_WHEN_PROHIBITED;
+    }
+
+    // Push_promise frames only define the padded and end_headers flags
+    if (get_flags() & ~PADDED & ~END_HEADERS)
+    {
+        session_data->events[source_id]->create_event(EVENT_INVALID_FLAG);
+        *session_data->infractions[source_id] += INF_INVALID_FLAG;
+    }
+}
+
+bool Http2PushPromiseFrame::valid_sequence(Http2Enums::StreamState)
+{
+    if (data.length() < PROMISED_ID_LENGTH)
+        return false;
+
+    if (source_id == SRC_CLIENT)
+    {
+        *session_data->infractions[source_id] += INF_C2S_PUSH;
+        session_data->events[source_id]->create_event(EVENT_C2S_PUSH);
+        return false;
+    }
+
+    // Promised stream must not be already in use
+    if (stream->get_state(SRC_CLIENT) != STREAM_EXPECT_HEADERS or
+        stream->get_state(SRC_SERVER) != STREAM_EXPECT_HEADERS)
+    {
+        *session_data->infractions[source_id] += INF_INVALID_PROMISED_STREAM;
+        session_data->events[source_id]->create_event(EVENT_INVALID_PROMISED_STREAM);
+        return false;
+    }
+
+    // Alert but continue processing if invalid sequence on stream push_promise was sent on
+    Http2Stream* const stream_sent_on = session_data->get_current_stream(source_id);
+    if (stream_sent_on->get_state(SRC_CLIENT) == STREAM_EXPECT_HEADERS or
+        stream_sent_on->get_state(SRC_SERVER) >= STREAM_COMPLETE)
+    {
+        *session_data->infractions[source_id] += INF_BAD_PUSH_SEQUENCE;
+        session_data->events[source_id]->create_event(EVENT_BAD_PUSH_SEQUENCE);
+    }
+    return true;
+}
+
+void Http2PushPromiseFrame::update_stream_state()
+{
+    switch (stream->get_state(source_id))
+    {
+        case STREAM_EXPECT_HEADERS:
+            stream->set_state(SRC_CLIENT, STREAM_COMPLETE);
+            break;
+        default:
+            //only STREAM_EXPECT_HEADERS is valid so should never get here
+            assert(false);
+            stream->set_state(source_id, STREAM_ERROR);
+    }
+}
+
+uint32_t Http2PushPromiseFrame::get_promised_stream_id(Http2EventGen* const events,
+    Http2Infractions* const infractions, const uint8_t* data_buffer, uint32_t data_len)
+{
+    if (data_len < PROMISED_ID_LENGTH)
+    {
+        events->create_event(EVENT_INVALID_PUSH_FRAME);
+        *infractions += INF_PUSH_FRAME_TOO_SHORT;
+        return NO_STREAM_ID;
+    }
+
+    // the first four bytes of the push_promise frame are the pushed stream ID
+    return get_stream_id_from_buffer(data_buffer);
+}
+
+#ifdef REG_TEST
+void Http2PushPromiseFrame::print_frame(FILE* output)
+{
+    fprintf(output, "Push_Promise frame\n");
+    Http2Frame::print_frame(output);
+}
+#endif
diff --git a/src/service_inspectors/http2_inspect/http2_push_promise_frame.h b/src/service_inspectors/http2_inspect/http2_push_promise_frame.h
new file mode 100644 (file)
index 0000000..8b3f962
--- /dev/null
@@ -0,0 +1,60 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2020-2020 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_push_promise_frame.h author Katura Harvey <katharve@cisco.com>
+
+#ifndef HTTP2_PUSH_PROMISE_FRAME_H
+#define HTTP2_PUSH_PROMISE_FRAME_H
+
+#include "service_inspectors/http_inspect/http_common.h"
+#include "utils/event_gen.h"
+#include "utils/infractions.h"
+
+#include "http2_enum.h"
+#include "http2_frame.h"
+
+class Field;
+class Http2Frame;
+class Http2Stream;
+class HttpFlowData;
+
+using Http2Infractions = Infractions<Http2Enums::INF__MAX_VALUE, Http2Enums::INF__NONE>;
+using Http2EventGen = EventGen<Http2Enums::EVENT__MAX_VALUE, Http2Enums::EVENT__NONE,
+    Http2Enums::HTTP2_GID>;
+
+class Http2PushPromiseFrame : public Http2Frame
+{
+public:
+    bool valid_sequence(Http2Enums::StreamState state) override;
+    void update_stream_state() override;
+    static uint32_t get_promised_stream_id(Http2EventGen* const events,
+        Http2Infractions* const infractions, const uint8_t* data_buffer, uint32_t data_len);
+
+    friend Http2Frame* Http2Frame::new_frame(const uint8_t*, const uint32_t, const uint8_t*,
+        const uint32_t, Http2FlowData*, HttpCommon::SourceId, Http2Stream* stream);
+
+#ifdef REG_TEST
+    void print_frame(FILE* output) override;
+#endif
+
+private:
+    Http2PushPromiseFrame(const uint8_t* header_buffer, const uint32_t header_len,
+        const uint8_t* data_buffer, const uint32_t data_len, Http2FlowData* ssn_data,
+        HttpCommon::SourceId src_id, Http2Stream* stream);
+    static const int32_t PROMISED_ID_LENGTH = 4;
+};
+#endif
index c8409ae9b238d161ea670ba753a5e9b484d37ed4..8d794de18d58f8c414794bd5c96b74bddbadafd0 100644 (file)
@@ -82,8 +82,8 @@ void Http2SettingsFrame::parse_settings_frame()
             continue;
         }
 
-        handle_update(parameter_id, parameter_value);
-        session_data->connection_settings[source_id].set_param(parameter_id, parameter_value);
+        if (handle_update(parameter_id, parameter_value))
+            session_data->connection_settings[source_id].set_param(parameter_id, parameter_value);
     }
 }
 
@@ -102,7 +102,7 @@ bool Http2SettingsFrame::sanity_check()
     return !(bad_frame);
 }
 
-void Http2SettingsFrame::handle_update(uint16_t id, uint32_t value)
+bool Http2SettingsFrame::handle_update(uint16_t id, uint32_t value)
 {
     switch (id)
     {
@@ -112,9 +112,19 @@ void Http2SettingsFrame::handle_update(uint16_t id, uint32_t value)
             session_data->get_hpack_decoder((HttpCommon::SourceId) (1 - source_id))->
                 get_decode_table()->settings_table_size_update(value);
             break;
+        case ENABLE_PUSH:
+            // Only values of 0 or 1 are allowed
+            if (!(value == 0 or value == 1))
+            {
+                session_data->events[source_id]->create_event(EVENT_BAD_SETTINGS_VALUE);
+                *session_data->infractions[source_id] += INF_BAD_SETTINGS_PUSH_VALUE;
+                return false;
+            }
+            break;
         default:
             break;
     }
+    return true;
 }
 
 #ifdef REG_TEST
index 544d91f7549f2b7b85e1f1970451594ec1e3da82..8ebecff11d20f1c51fc60bb0c695cb97ae42592c 100644 (file)
@@ -44,7 +44,7 @@ private:
 
     void parse_settings_frame();
     bool sanity_check();
-    void handle_update(uint16_t id, uint32_t value);
+    bool handle_update(uint16_t id, uint32_t value);
 
     bool bad_frame = false;
     static const uint8_t SfAck = 0x01;
index b2e7abec8011a8595fec7fd5bc9e2bde54af21d0..9162d3a06111a6e83bf23a14a021ab1643bbed34 100644 (file)
@@ -120,8 +120,6 @@ StreamSplitter::Status Http2StreamSplitter::non_data_frame_header_checks(
     
     if (type == FT_CONTINUATION and !session_data->continuation_expected[source_id])
     {
-        // FIXIT-E 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);
@@ -153,6 +151,7 @@ StreamSplitter::Status Http2StreamSplitter::non_data_scan(Http2FlowData* session
     switch (type)
     {
     case FT_HEADERS:
+    case FT_PUSH_PROMISE:
         if (!(frame_flags & END_HEADERS))
         {
             session_data->continuation_expected[source_id] = true;
@@ -294,7 +293,7 @@ StreamSplitter::Status Http2StreamSplitter::implement_scan(Http2FlowData* sessio
                         scan_frame_header[source_id]);
                     const uint32_t old_stream = session_data->current_stream[source_id];
                     session_data->current_stream[source_id] =
-                        get_stream_id(session_data->scan_frame_header[source_id]);
+                        get_stream_id_from_header(session_data->scan_frame_header[source_id]);
 
                     if (session_data->continuation_expected[source_id] && type != FT_CONTINUATION)
                     {
index 4574cb114faae72614af33c1efd9920ae250c951..e3265a1c2b6d8ccc2ea076dcf0d1c4267dd8789a 100644 (file)
@@ -53,6 +53,14 @@ const RuleMap Http2Module::http2_events[] =
     { EVENT_TRAILERS_NOT_END, "HTTP/2 trailers without END_STREAM bit" },
     { EVENT_PADDING_ON_INVALID_FRAME, "padding flag set on invalid HTTP/2 frame type" },
     { EVENT_PADDING_ON_EMPTY_FRAME, "padding flag set on HTTP/2 frame with zero length" },
+    { EVENT_C2S_PUSH, "HTTP/2 push promise frame in c2s direction" },
+    { EVENT_INVALID_PUSH_FRAME, "invalid HTTP/2 push promise frame" },
+    { EVENT_BAD_PUSH_SEQUENCE, "HTTP/2 push promise frame sent at invalid time" },
+    { EVENT_BAD_SETTINGS_VALUE, "invalid parameter value sent in HTTP/2 settings frame" },
+    { EVENT_PUSH_WHEN_PROHIBITED, "HTTP/2 push promise frame sent when prohibited by receiver" },
+    { EVENT_INVALID_PROMISED_STREAM, "HTTP/2 push promise frame with invalid promised stream id" },
+    { EVENT_INVALID_STREAM_ID, "HTTP/2 stream initiated with invalid stream id" },
+    { EVENT_INVALID_FLAG, "invalid flag set on HTTP/2 frame" },
     { 0, nullptr }
 };
 
index f8cb32ae98d4952f2bfd1aba7c66c21c57455c82..bfad7ab9836c5e5376def20213e8acc56ea7e3da 100644 (file)
@@ -50,13 +50,15 @@ uint8_t get_frame_flags(const uint8_t* frame_header_buffer)
         return NO_HEADER;
 }
 
-uint8_t get_stream_id(const uint8_t* frame_header_buffer)
+uint32_t get_stream_id_from_header(const uint8_t* frame_header_buffer)
 {
     const uint8_t stream_id_index = 5;
     assert(frame_header_buffer != nullptr);
-    return ((frame_header_buffer[stream_id_index] & 0x7f) << 24) +
-           (frame_header_buffer[stream_id_index + 1] << 16) +
-           (frame_header_buffer[stream_id_index + 2] << 8) +
-           frame_header_buffer[stream_id_index + 3];
+    return get_stream_id_from_buffer(frame_header_buffer + stream_id_index);
+
 }
 
+uint32_t get_stream_id_from_buffer(const uint8_t* buffer)
+{
+    return ((buffer[0] & 0x7f) << 24) + (buffer[1] << 16) + (buffer[2] << 8) + buffer[3];
+}
index 351682c7f559e99b769872a95778b4db91daa6cc..0657dc89629af1e2b0dcb42e575695b77c2cbbcb 100644 (file)
@@ -35,6 +35,7 @@
 uint32_t get_frame_length(const uint8_t* frame_header_buffer);
 uint8_t get_frame_type(const uint8_t* frame_header_buffer);
 uint8_t get_frame_flags(const uint8_t* frame_header_buffer);
-uint8_t get_stream_id(const uint8_t* frame_header_buffer);
+uint32_t get_stream_id_from_header(const uint8_t* frame_header_buffer);
+uint32_t get_stream_id_from_buffer(const uint8_t* buffer);
 
 #endif