suricata
util-streaming-buffer.h
Go to the documentation of this file.
1/* Copyright (C) 2015-2016 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/*
19 * This API is meant to be used with streaming data. A single memory
20 * block is used to store the data. StreamingBufferSegment points to
21 * chunk of data in the single StreamingBuffer. It points by offset
22 * and length, so no pointers. The buffer is resized on demand and
23 * slides forward, either automatically or manually.
24 *
25 * When a segment needs it's data it uses StreamingBufferSegmentGetData
26 * which takes care of checking if the segment still has a valid offset
27 * and length.
28 *
29 * The StreamingBuffer::stream_offset is an absolute offset since the
30 * start of the data streaming.
31 *
32 * Similarly, StreamingBufferSegment::stream_offset is also an absolute
33 * offset.
34 *
35 * Using the segments is optional.
36 *
37 *
38 * stream_offset buf_offset stream_offset + buf_size
39 * ^ ^ ^
40 * | | |
41 * | | |
42 * +--------------------------------------------+
43 * | data | empty |
44 * | xxxxxxxxxx | |
45 * +------^--------^--------+-------------------+
46 * | |
47 * | |
48 * | |
49 * | |
50 * | |
51 * +------+--------+-------+
52 * | StreamingBufferSegment|
53 * +-----------+-----------+
54 * | offset | len |
55 * +-----------+-----------+
56 */
57
58#ifndef SURICATA_UTIL_STREAMING_BUFFER_H
59#define SURICATA_UTIL_STREAMING_BUFFER_H
60
61#include "tree.h"
62
63#define STREAMING_BUFFER_REGION_GAP_DEFAULT 262144
64
65typedef struct StreamingBufferConfig_ {
66 uint32_t buf_size;
67 uint16_t max_regions; /**< max concurrent memory regions. 0 means no limit. */
68 uint32_t region_gap; /**< max gap size before a new region will be created. */
69 void *(*Calloc)(size_t n, size_t size);
70 void *(*Realloc)(void *ptr, size_t orig_size, size_t size);
71 void (*Free)(void *ptr, size_t size);
73
74#define STREAMING_BUFFER_CONFIG_INITIALIZER \
75 { \
76 2048, 8, STREAMING_BUFFER_REGION_GAP_DEFAULT, NULL, NULL, NULL, \
77 }
78
79#define STREAMING_BUFFER_REGION_INIT \
80 { \
81 NULL, 0, 0, 0ULL, NULL, \
82 }
83
84typedef struct StreamingBufferRegion_ {
85 uint8_t *buf; /**< memory block for reassembly */
86 uint32_t buf_size; /**< size of memory block */
87 uint32_t buf_offset; /**< how far we are in buf_size */
88 uint64_t stream_offset; /**< stream offset of this region */
91
92/**
93 * \brief block of continues data
94 */
95typedef struct StreamingBufferBlock {
96 uint64_t offset;
98 uint32_t len;
100
102
103/* red-black tree prototype for SACK records */
107
108typedef struct StreamingBuffer_ {
110 struct SBB sbb_tree; /**< red black tree of Stream Buffer Blocks */
111 StreamingBufferBlock *head; /**< head, should always be the same as RB_MIN */
112 uint32_t sbb_size; /**< data size covered by sbbs */
113 uint16_t regions;
114 uint16_t max_regions;
115#ifdef DEBUG
116 uint32_t buf_size_max;
117#endif
119
120static inline bool StreamingBufferHasData(const StreamingBuffer *sb)
121{
122 return (sb->region.stream_offset || sb->region.buf_offset || sb->region.next != NULL ||
123 !RB_EMPTY(&sb->sbb_tree));
124}
125
126static inline uint64_t StreamingBufferGetConsecutiveDataRightEdge(const StreamingBuffer *sb)
127{
128 return sb->region.stream_offset + sb->region.buf_offset;
129}
130
131static inline uint64_t StreamingBufferGetOffset(const StreamingBuffer *sb)
132{
133 return sb->region.stream_offset;
134}
135
136#ifndef DEBUG
137#define STREAMING_BUFFER_INITIALIZER \
138 { \
139 STREAMING_BUFFER_REGION_INIT, \
140 { NULL }, \
141 NULL, \
142 0, \
143 1, \
144 1, \
145 };
146#else
147#define STREAMING_BUFFER_INITIALIZER { STREAMING_BUFFER_REGION_INIT, { NULL }, NULL, 0, 1, 1, 0 };
148#endif
149
151 uint32_t segment_len;
153} __attribute__((__packed__)) StreamingBufferSegment;
154
158
160 StreamingBuffer *sb, const StreamingBufferConfig *cfg, uint64_t offset);
161
163 StreamingBufferSegment *seg, const uint8_t *data, uint32_t data_len) WARN_UNUSED;
165 const uint8_t *data, uint32_t data_len) WARN_UNUSED;
167 StreamingBufferSegment *seg, const uint8_t *data, uint32_t data_len,
168 uint64_t offset) WARN_UNUSED;
169
171 const StreamingBufferSegment *seg,
172 const uint8_t **data, uint32_t *data_len);
173
175 const StreamingBufferBlock *sbb,
176 const uint8_t **data, uint32_t *data_len);
177
179 const StreamingBufferBlock *sbb,
180 const uint8_t **data, uint32_t *data_len,
181 uint64_t offset);
182
184 const StreamingBufferSegment *seg,
185 const uint8_t *rawdata, uint32_t rawdata_len);
187 const uint8_t *rawdata, uint32_t rawdata_len);
188
190 const uint8_t **data, uint32_t *data_len,
191 uint64_t *stream_offset);
192
194 const uint8_t **data, uint32_t *data_len,
195 uint64_t offset);
196
198 const StreamingBufferSegment *seg);
199
201
202#endif /* SURICATA_UTIL_STREAMING_BUFFER_H */
#define WARN_UNUSED
Definition bindgen.h:32
struct PrefilterEngineFlowbits __attribute__
DNP3 application header.
Flow * head
Definition flow-hash.h:1
block of continues data
RB_ENTRY(StreamingBufferBlock) rb
void(* Free)(void *ptr, size_t size)
struct StreamingBufferRegion_ * next
StreamingBufferRegion region
StreamingBufferBlock * head
#define RB_EMPTY(head)
Definition tree.h:327
#define RB_PROTOTYPE(name, type, field, cmp)
Definition tree.h:385
#define RB_HEAD(name, type)
Definition tree.h:300
uint64_t stream_offset
int StreamingBufferAppend(StreamingBuffer *sb, const StreamingBufferConfig *cfg, StreamingBufferSegment *seg, const uint8_t *data, uint32_t data_len) WARN_UNUSED
void StreamingBufferSegmentGetData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t **data, uint32_t *data_len)
int StreamingBufferAppendNoTrack(StreamingBuffer *sb, const StreamingBufferConfig *cfg, const uint8_t *data, uint32_t data_len) WARN_UNUSED
add data w/o tracking a segment
void StreamingBufferSBBGetDataAtOffset(const StreamingBuffer *sb, const StreamingBufferBlock *sbb, const uint8_t **data, uint32_t *data_len, uint64_t offset)
get the data for one SBB
struct StreamingBufferRegion_ StreamingBufferRegion
int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb, const StreamingBufferSegment *seg, const uint8_t *rawdata, uint32_t rawdata_len)
struct StreamingBuffer_ StreamingBuffer
StreamingBuffer * StreamingBufferInit(const StreamingBufferConfig *cfg)
int StreamingBufferGetDataAtOffset(const StreamingBuffer *sb, const uint8_t **data, uint32_t *data_len, uint64_t offset)
void StreamingBufferSlideToOffset(StreamingBuffer *sb, const StreamingBufferConfig *cfg, uint64_t offset)
slide to absolute offset
uint64_t offset
StreamingBufferBlock * SBB_RB_FIND_INCLUSIVE(struct SBB *head, StreamingBufferBlock *elm)
int StreamingBufferInsertAt(StreamingBuffer *sb, const StreamingBufferConfig *cfg, StreamingBufferSegment *seg, const uint8_t *data, uint32_t data_len, uint64_t offset) WARN_UNUSED
void StreamingBufferRegisterTests(void)
int StreamingBufferCompareRawData(const StreamingBuffer *sb, const uint8_t *rawdata, uint32_t rawdata_len)
void StreamingBufferFree(StreamingBuffer *sb, const StreamingBufferConfig *cfg)
struct StreamingBufferConfig_ StreamingBufferConfig
void StreamingBufferSBBGetData(const StreamingBuffer *sb, const StreamingBufferBlock *sbb, const uint8_t **data, uint32_t *data_len)
get the data for one SBB
void StreamingBufferClear(StreamingBuffer *sb, const StreamingBufferConfig *cfg)
int SBBCompare(struct StreamingBufferBlock *a, struct StreamingBufferBlock *b)
int StreamingBufferSegmentIsBeforeWindow(const StreamingBuffer *sb, const StreamingBufferSegment *seg)
int StreamingBufferGetData(const StreamingBuffer *sb, const uint8_t **data, uint32_t *data_len, uint64_t *stream_offset)