From: Mike Stepanek (mstepane) Date: Mon, 6 Apr 2020 12:46:05 +0000 (+0000) Subject: Merge pull request #2123 in SNORT/snort3 from ~MDAGON/snort3:pt5 to master X-Git-Tag: 3.0.1-2~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=819b41d6ae646a035075ee7dd770591e94b7c001;p=thirdparty%2Fsnort3.git Merge pull request #2123 in SNORT/snort3 from ~MDAGON/snort3:pt5 to master Squashed commit of the following: commit 8bd4bd1239e961dba3287e9ec05fff34990ceb8c Author: mdagon Date: Wed Mar 25 16:19:22 2020 -0400 http2_inspect: flush pending data when a non-data frame is received --- diff --git a/src/service_inspectors/http2_inspect/http2_data_cutter.cc b/src/service_inspectors/http2_inspect/http2_data_cutter.cc index c98bc7d6a..6cbba9668 100644 --- a/src/service_inspectors/http2_inspect/http2_data_cutter.cc +++ b/src/service_inspectors/http2_inspect/http2_data_cutter.cc @@ -115,13 +115,13 @@ bool Http2DataCutter::http2_scan(const uint8_t* data, uint32_t length, StreamSplitter::Status Http2DataCutter::http_scan(const uint8_t* data, uint32_t* flush_offset) { StreamSplitter::Status scan_result = StreamSplitter::SEARCH; - uint32_t http_flush_offset = 0; - Http2DummyPacket dummy_pkt; - dummy_pkt.flow = session_data->flow; - uint32_t unused = 0; if (cur_data || leftover_bytes) { + uint32_t http_flush_offset = 0; + Http2DummyPacket dummy_pkt; + dummy_pkt.flow = session_data->flow; + uint32_t unused = 0; scan_result = session_data->hi_ss[source_id]->scan(&dummy_pkt, data + cur_data_offset, cur_data + leftover_bytes, unused, &http_flush_offset); @@ -153,11 +153,8 @@ StreamSplitter::Status Http2DataCutter::http_scan(const uint8_t* data, uint32_t* if (frame_flags & END_STREAM) { - session_data->get_current_stream(source_id)->get_hi_flow_data()-> - finish_h2_body(source_id); - scan_result = session_data->hi_ss[source_id]->scan(&dummy_pkt, nullptr, 0, unused, - &http_flush_offset); - assert(scan_result == StreamSplitter::FLUSH); + finish_msg_body(session_data, source_id); + return StreamSplitter::FLUSH; } else session_data->data_processing[source_id] = true; diff --git a/src/service_inspectors/http2_inspect/http2_flow_data.h b/src/service_inspectors/http2_inspect/http2_flow_data.h index d57677758..79f6c32fc 100644 --- a/src/service_inspectors/http2_inspect/http2_flow_data.h +++ b/src/service_inspectors/http2_inspect/http2_flow_data.h @@ -73,16 +73,7 @@ public: friend class Http2StatusLine; friend class Http2Stream; friend class Http2StreamSplitter; - friend snort::StreamSplitter::Status data_scan(Http2FlowData* session_data, const - uint8_t* data, uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id, - uint32_t frame_length, uint8_t frame_flags, uint32_t& data_offset); - 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, - uint32_t*, HttpCommon::SourceId); - friend snort::StreamSplitter::Status non_data_scan(Http2FlowData* session_data, - uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id, - uint32_t frame_length, uint8_t type, uint8_t frame_flags, uint32_t& data_offset); + friend void finish_msg_body(Http2FlowData* session_data, HttpCommon::SourceId source_id); size_t size_of() override { return sizeof(*this); } @@ -143,7 +134,11 @@ protected: bool payload_discard[2] = { false, false }; uint32_t num_frame_headers[2] = { 0, 0 }; uint32_t total_bytes_in_split[2] = { 0, 0 }; - uint32_t octets_before_first_header[2] = { 0, 0 }; + bool use_leftover_hdr[2] = { false, false }; + uint8_t leftover_hdr[2][Http2Enums::FRAME_HEADER_LENGTH]; + + // Used by scan, reassemble + bool flushing_data[2] = { false, false }; // Used by scan, reassemble and eval to communicate uint8_t frame_type[2] = { Http2Enums::FT__NONE, Http2Enums::FT__NONE }; diff --git a/src/service_inspectors/http2_inspect/http2_stream.h b/src/service_inspectors/http2_inspect/http2_stream.h index e026ae97c..3d635f3d3 100644 --- a/src/service_inspectors/http2_inspect/http2_stream.h +++ b/src/service_inspectors/http2_inspect/http2_stream.h @@ -55,6 +55,8 @@ public: void set_end_stream(HttpCommon::SourceId source_id) { end_stream_set[source_id] = true; } bool end_stream_is_set(HttpCommon::SourceId source_id) { return end_stream_set[source_id]; } + void set_abort_on_data(HttpCommon::SourceId source_id) { abort_on_data[source_id] = true; } + bool abort_on_data_is_set(HttpCommon::SourceId source_id) { return abort_on_data[source_id]; } #ifdef REG_TEST void print_frame(FILE* output); #endif @@ -67,6 +69,7 @@ private: HttpMsgSection* hi_msg_section = nullptr; Http2DataCutter* data_cutter[2] = { nullptr, nullptr}; bool end_stream_set[2] = { false, false }; + bool abort_on_data[2] = { false, false}; }; #endif diff --git a/src/service_inspectors/http2_inspect/http2_stream_splitter.h b/src/service_inspectors/http2_inspect/http2_stream_splitter.h index 1b7d13af4..d001e1bc3 100644 --- a/src/service_inspectors/http2_inspect/http2_stream_splitter.h +++ b/src/service_inspectors/http2_inspect/http2_stream_splitter.h @@ -48,17 +48,23 @@ public: private: const HttpCommon::SourceId source_id; -}; - -snort::StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t* data, - uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id); -const snort::StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned total, - unsigned offset, const uint8_t* data, unsigned len, uint32_t flags, - HttpCommon::SourceId source_id); -enum ValidationResult { V_GOOD, V_BAD, V_TBD }; + static StreamSplitter::Status data_scan(Http2FlowData* session_data, const uint8_t* data, + uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id, + uint32_t frame_length, uint8_t frame_flags, uint32_t& data_offset); + static void flush_data(Http2FlowData* session_data, HttpCommon::SourceId source_id, + uint32_t* flush_offset, uint32_t old_stream); + static StreamSplitter::Status non_data_scan(Http2FlowData* session_data, + uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id, + uint32_t frame_length, uint8_t type, uint8_t frame_flags, uint32_t& data_offset); + static snort::StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t* data, + uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id); + static const snort::StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned total, + unsigned offset, const uint8_t* data, unsigned len, uint32_t flags, + HttpCommon::SourceId source_id); + static bool read_frame_hdr(Http2FlowData* session_data, const uint8_t* data, + uint32_t length, HttpCommon::SourceId source_id, uint32_t& data_offset); +}; -ValidationResult validate_preface(const uint8_t* data, const uint32_t length, - const uint32_t octets_seen); #endif diff --git a/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc b/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc index 16f7a064a..d515988df 100644 --- a/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc +++ b/src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc @@ -39,11 +39,39 @@ using namespace snort; using namespace HttpCommon; using namespace Http2Enums; -StreamSplitter::Status data_scan(Http2FlowData* session_data, const uint8_t* data, - uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id, - uint32_t frame_length, uint8_t frame_flags, uint32_t& data_offset) +enum ValidationResult { V_GOOD, V_BAD, V_TBD }; + +static ValidationResult validate_preface(const uint8_t* data, const uint32_t length, + const uint32_t octets_seen) +{ + const uint32_t preface_length = 24; + + static const uint8_t connection_prefix[] = { 'P', 'R', 'I', ' ', '*', ' ', 'H', 'T', 'T', 'P', + '/', '2', '.', '0', '\r', '\n', '\r', '\n', 'S', 'M', '\r', '\n', '\r', '\n' }; + + assert(octets_seen < preface_length); + + const uint32_t count = (octets_seen + length) < preface_length ? length : + (preface_length - octets_seen); + + if (memcmp(data, connection_prefix + octets_seen, count)) + return V_BAD; + + if ((octets_seen + length) < preface_length) + return V_TBD; + + return V_GOOD; +} + +StreamSplitter::Status Http2StreamSplitter::data_scan(Http2FlowData* session_data, + const uint8_t* data, uint32_t length, uint32_t* flush_offset, + HttpCommon::SourceId source_id, uint32_t frame_length, uint8_t frame_flags, + uint32_t& data_offset) { Http2Stream* const stream = session_data->find_stream(session_data->current_stream[source_id]); + if (stream && stream->abort_on_data_is_set(source_id)) + return StreamSplitter::ABORT; + HttpFlowData* http_flow = nullptr; if (stream) http_flow = (HttpFlowData*)stream->get_hi_flow_data(); @@ -63,14 +91,10 @@ StreamSplitter::Status data_scan(Http2FlowData* session_data, const uint8_t* dat return data_cutter->scan(data, length, flush_offset, data_offset, frame_length, frame_flags); } -StreamSplitter::Status non_data_scan(Http2FlowData* session_data, +StreamSplitter::Status Http2StreamSplitter::non_data_scan(Http2FlowData* session_data, uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id, uint32_t frame_length, uint8_t type, uint8_t frame_flags, uint32_t& data_offset) { - // FIXIT-E - temporary. Will force data frame flush instead - if (session_data->data_processing[source_id]) - return StreamSplitter::ABORT; - // Compute frame section length once per frame if (session_data->scan_remaining_frame_octets[source_id] == 0) { @@ -152,7 +176,62 @@ StreamSplitter::Status non_data_scan(Http2FlowData* session_data, return status; } -StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t* data, +// Flush pending data. Save current non-data header for the next scan/reassemble. +void Http2StreamSplitter::flush_data(Http2FlowData* session_data, HttpCommon::SourceId source_id, + uint32_t* flush_offset, uint32_t old_stream) +{ + session_data->current_stream[source_id] = old_stream; + session_data->frame_type[source_id] = FT_DATA; + finish_msg_body(session_data, source_id); + *flush_offset = FRAME_HEADER_LENGTH; + session_data->flushing_data[source_id] = true; + memcpy(session_data->leftover_hdr[source_id], + session_data->scan_frame_header[source_id], FRAME_HEADER_LENGTH); + session_data->num_frame_headers[source_id] -= 1; + Http2Stream* const stream = session_data->find_stream( + session_data->current_stream[source_id]); + stream->set_abort_on_data(source_id); +} + +bool Http2StreamSplitter::read_frame_hdr(Http2FlowData* session_data, const uint8_t* data, + uint32_t length, HttpCommon::SourceId source_id, uint32_t& data_offset) +{ + if (!session_data->flushing_data[source_id]) + { + // Frame with header + if (session_data->scan_octets_seen[source_id] == 0) + { + // Scanning a new frame + session_data->num_frame_headers[source_id] += 1; + } + + // The first nine bytes are the frame header. But all nine might not all be + // present in the first TCP segment we receive. + const uint32_t remaining_header = FRAME_HEADER_LENGTH - + session_data->scan_octets_seen[source_id]; + const uint32_t remaining_header_in_data = remaining_header > length - data_offset ? + length - data_offset : remaining_header; + memcpy(session_data->scan_frame_header[source_id] + + session_data->scan_octets_seen[source_id], data + data_offset, + remaining_header_in_data); + session_data->scan_octets_seen[source_id] += remaining_header_in_data; + data_offset += remaining_header_in_data; + + if (session_data->scan_octets_seen[source_id] < FRAME_HEADER_LENGTH) + return false; + } + else + { + // Just finished flushing data. Use saved header. + session_data->num_frame_headers[source_id] = 1; + session_data->flushing_data[source_id] = false; + session_data->use_leftover_hdr[source_id] = true; + } + + return true; +} + +StreamSplitter::Status Http2StreamSplitter::implement_scan(Http2FlowData* session_data, const uint8_t* data, uint32_t length, uint32_t* flush_offset, HttpCommon::SourceId source_id) { StreamSplitter::Status status = StreamSplitter::FLUSH; @@ -180,10 +259,9 @@ StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t { *flush_offset = 0; uint32_t data_offset = 0; - session_data->octets_before_first_header[source_id] = 0; - // If there is a header frame followed by a continuation frame in the same tcp segment or - // several data frames need to process multiple frames in a single scan + // Need to process multiple frames in a single scan() if a single TCP segment has + // 1) multiple header and continuation frames or 2) multiple data frames. do { if (session_data->mid_data_frame[source_id]) @@ -196,27 +274,7 @@ StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t } else { - // Frame with header - if (session_data->scan_octets_seen[source_id] == 0) - { - // Scanning a new frame - session_data->num_frame_headers[source_id] += 1; - } - - // The first nine bytes are the frame header. But all nine might not all be present - // in - // the first TCP segment we receive. - const uint32_t remaining_header = FRAME_HEADER_LENGTH - - session_data->scan_octets_seen[source_id]; - const uint32_t remaining_header_in_data = remaining_header > length - data_offset ? - length - data_offset : remaining_header; - memcpy(session_data->scan_frame_header[source_id] + - session_data->scan_octets_seen[source_id], data + data_offset, - remaining_header_in_data); - session_data->scan_octets_seen[source_id] += remaining_header_in_data; - data_offset += remaining_header_in_data; - - if (session_data->scan_octets_seen[source_id] < FRAME_HEADER_LENGTH) + if (!read_frame_hdr(session_data, data, length, source_id, data_offset)) return StreamSplitter::SEARCH; // We have the full frame header, compute some variables @@ -226,9 +284,23 @@ StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t session_data->scan_frame_header[source_id]); const uint8_t frame_flags = get_frame_flags(session_data-> 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]); + if ((old_stream != session_data->current_stream[source_id]) && + session_data->data_processing[source_id] && type == FT_DATA) + { + // FIXIT-E split by stream multiplexing not supported yet + return StreamSplitter::ABORT; + } + + if (session_data->data_processing[source_id] && type != FT_DATA) + { + flush_data(session_data, source_id, flush_offset, old_stream); + return StreamSplitter::FLUSH; + } + if (type == FT_DATA) status = data_scan(session_data, data, length, flush_offset, source_id, frame_length, frame_flags, data_offset); @@ -245,7 +317,7 @@ StreamSplitter::Status implement_scan(Http2FlowData* session_data, const uint8_t // FIXIT-M If there are any errors in header decoding, this currently tells stream not to send // headers to detection. This behavior may need to be changed. -const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned total, +const StreamBuffer Http2StreamSplitter::implement_reassemble(Http2FlowData* session_data, unsigned total, unsigned offset, const uint8_t* data, unsigned len, uint32_t flags, HttpCommon::SourceId source_id) { @@ -268,33 +340,39 @@ const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned to if (session_data->frame_type[source_id] == FT_DATA) { - Http2Stream* const stream = session_data->find_stream( - session_data->current_stream[source_id]); - Http2DataCutter* data_cutter = stream->get_data_cutter(source_id); - StreamBuffer http_frame_buf = data_cutter->reassemble(data, len); - if (http_frame_buf.data) + if (session_data->flushing_data[source_id] && (flags & PKT_PDU_TAIL)) + len -= FRAME_HEADER_LENGTH; + + if (len != 0) { - session_data->frame_data[source_id] = const_cast(http_frame_buf.data); - session_data->frame_data_size[source_id] = http_frame_buf.length; + Http2Stream* const stream = session_data->find_stream( + session_data->current_stream[source_id]); + Http2DataCutter* data_cutter = stream->get_data_cutter(source_id); + StreamBuffer http_frame_buf = data_cutter->reassemble(data, len); + if (http_frame_buf.data) + { + session_data->frame_data[source_id] = const_cast(http_frame_buf.data); + session_data->frame_data_size[source_id] = http_frame_buf.length; + } } } else { - assert(total >= FRAME_HEADER_LENGTH); uint32_t data_offset = 0; if (offset == 0) { // This is the first reassemble() for this frame - allocate data buffer - session_data->frame_data_size[source_id]= total - - session_data->frame_header_size[source_id]; + session_data->frame_data_size[source_id] = total; + if (!session_data->use_leftover_hdr[source_id]) + session_data->frame_data_size[source_id] -= + session_data->frame_header_size[source_id]; if (session_data->frame_data_size[source_id] > 0) session_data->frame_data[source_id] = new uint8_t[ session_data->frame_data_size[source_id]]; session_data->frame_data_offset[source_id] = 0; - session_data->remaining_frame_octets[source_id] = - session_data->octets_before_first_header[source_id]; + session_data->remaining_frame_octets[source_id] = 0; session_data->padding_octets_in_frame[source_id] = 0; } @@ -315,8 +393,7 @@ const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned to } // Copy data into the frame buffer until we run out of data or reach the end of the - // current - // frame's data + // current frame's data const uint32_t remaining_frame_payload = session_data->remaining_frame_octets[source_id] - session_data->padding_octets_in_frame[source_id]; @@ -346,26 +423,36 @@ const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned to break; // Copy headers - const uint32_t remaining_frame_header = FRAME_HEADER_LENGTH - - (session_data->frame_header_offset[source_id] % FRAME_HEADER_LENGTH); - octets_to_copy = remaining_frame_header > len - data_offset ? len - data_offset : - remaining_frame_header; - memcpy(session_data->frame_header[source_id] + - session_data->frame_header_offset[source_id], - data + data_offset, octets_to_copy); - session_data->frame_header_offset[source_id] += octets_to_copy; - data_offset += octets_to_copy; + if (session_data->use_leftover_hdr[source_id]) + { + memcpy(session_data->frame_header[source_id], + session_data->leftover_hdr[source_id], FRAME_HEADER_LENGTH); + session_data->frame_header_offset[source_id] += FRAME_HEADER_LENGTH; + session_data->use_leftover_hdr[source_id] = false; + } + else + { + const uint32_t remaining_frame_header = FRAME_HEADER_LENGTH - + (session_data->frame_header_offset[source_id] % FRAME_HEADER_LENGTH); + octets_to_copy = remaining_frame_header > len - data_offset ? len - data_offset : + remaining_frame_header; + memcpy(session_data->frame_header[source_id] + + session_data->frame_header_offset[source_id], + data + data_offset, octets_to_copy); + session_data->frame_header_offset[source_id] += octets_to_copy; + data_offset += octets_to_copy; - if (session_data->frame_header_offset[source_id] % FRAME_HEADER_LENGTH != 0) - break; + if (session_data->frame_header_offset[source_id] % FRAME_HEADER_LENGTH != 0) + break; + } // If we just finished copying a header, parse and update frame variables session_data->remaining_frame_octets[source_id] = get_frame_length(session_data->frame_header[source_id] + session_data->frame_header_offset[source_id] - FRAME_HEADER_LENGTH); - uint8_t frame_flags = get_frame_flags(session_data-> - scan_frame_header[source_id]); + uint8_t frame_flags = get_frame_flags(session_data->frame_header[source_id] + + session_data->frame_header_offset[source_id] - FRAME_HEADER_LENGTH); if (frame_flags & PADDED) session_data->get_padding_len[source_id] = true; } @@ -373,6 +460,7 @@ const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned to session_data->frame_type[source_id] = get_frame_type( session_data->frame_header[source_id]); } + if (flags & PKT_PDU_TAIL) { session_data->total_bytes_in_split[source_id] = 0; @@ -387,25 +475,3 @@ const StreamBuffer implement_reassemble(Http2FlowData* session_data, unsigned to return frame_buf; } -ValidationResult validate_preface(const uint8_t* data, const uint32_t length, - const uint32_t octets_seen) -{ - const uint32_t preface_length = 24; - - static const uint8_t connection_prefix[] = { 'P', 'R', 'I', ' ', '*', ' ', 'H', 'T', 'T', 'P', - '/', '2', '.', '0', '\r', '\n', '\r', '\n', 'S', 'M', '\r', '\n', '\r', '\n' }; - - assert(octets_seen < preface_length); - - const uint32_t count = (octets_seen + length) < preface_length ? length : - (preface_length - octets_seen); - - if (memcmp(data, connection_prefix + octets_seen, count)) - return V_BAD; - - if ((octets_seen + length) < preface_length) - return V_TBD; - - return V_GOOD; -} - diff --git a/src/service_inspectors/http2_inspect/http2_tables.cc b/src/service_inspectors/http2_inspect/http2_tables.cc index b558c107c..76b8d5998 100644 --- a/src/service_inspectors/http2_inspect/http2_tables.cc +++ b/src/service_inspectors/http2_inspect/http2_tables.cc @@ -40,7 +40,7 @@ const RuleMap Http2Module::http2_events[] = { EVENT_PREFACE_MATCH_FAILURE, "HTTP/2 connection preface does not match" }, { EVENT_REQUEST_WITHOUT_REQUIRED_FIELD, "HTTP/2 request missing required header field" }, { EVENT_RESPONSE_WITHOUT_STATUS, "HTTP/2 response has no status code" }, - { EVENT_INVALID_HEADER, "invalid HTTP/2 header field" }, + { EVENT_INVALID_HEADER, "HTTP/2 invalid header field" }, { EVENT_SETTINGS_FRAME_ERROR, "error in HTTP/2 settings frame" }, { EVENT_SETTINGS_FRAME_UNKN_PARAM, "unknown parameter in HTTP/2 settings frame" }, { EVENT_FRAME_SEQUENCE, "invalid HTTP/2 frame sequence" }, diff --git a/src/service_inspectors/http2_inspect/http2_utils.cc b/src/service_inspectors/http2_inspect/http2_utils.cc index 620803cb0..eb603bb47 100644 --- a/src/service_inspectors/http2_inspect/http2_utils.cc +++ b/src/service_inspectors/http2_inspect/http2_utils.cc @@ -21,6 +21,10 @@ #include +#include "service_inspectors/http_inspect/http_flow_data.h" +#include "service_inspectors/http_inspect/http_stream_splitter.h" + +#include "http2_dummy_packet.h" #include "http2_enum.h" using namespace Http2Enums; @@ -58,3 +62,19 @@ uint8_t get_stream_id(const uint8_t* frame_header_buffer) (frame_header_buffer[stream_id_index + 2] << 8) + frame_header_buffer[stream_id_index + 3]; } + +void finish_msg_body(Http2FlowData* session_data, HttpCommon::SourceId source_id) +{ + uint32_t http_flush_offset = 0; + Http2DummyPacket dummy_pkt; + dummy_pkt.flow = session_data->flow; + uint32_t unused = 0; + session_data->get_current_stream(source_id)->get_hi_flow_data()-> + finish_h2_body(source_id); + const snort::StreamSplitter::Status scan_result = session_data->hi_ss[source_id]->scan( + &dummy_pkt, nullptr, 0, unused, &http_flush_offset); + assert(scan_result == snort::StreamSplitter::FLUSH); + UNUSED(scan_result); + session_data->data_processing[source_id] = false; +} + diff --git a/src/service_inspectors/http2_inspect/http2_utils.h b/src/service_inspectors/http2_inspect/http2_utils.h index 6a88f1e90..3954f69fd 100644 --- a/src/service_inspectors/http2_inspect/http2_utils.h +++ b/src/service_inspectors/http2_inspect/http2_utils.h @@ -25,6 +25,9 @@ #endif #include "main/snort_types.h" +#include "service_inspectors/http_inspect/http_common.h" + +#include "http2_flow_data.h" // Frame header parsing utils. // Assumption is that if input isn't null, it contains full frame header @@ -34,4 +37,7 @@ 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); + +void finish_msg_body(Http2FlowData* session_data, HttpCommon::SourceId source_id); + #endif