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 
59 #ifndef __UTIL_STREAMING_BUFFER_H__
60 #define __UTIL_STREAMING_BUFFER_H__
61 
62 #include "tree.h"
63 
64 #define STREAMING_BUFFER_NOFLAGS     0
65 #define STREAMING_BUFFER_AUTOSLIDE  (1<<0)
66 
67 typedef struct StreamingBufferConfig_ {
68     uint32_t flags;
69     uint32_t buf_slide;
70     uint32_t buf_size;
71     void *(*Malloc)(size_t size);
72     void *(*Calloc)(size_t n, size_t size);
73     void *(*Realloc)(void *ptr, size_t orig_size, size_t size);
74     void (*Free)(void *ptr, size_t size);
75 } StreamingBufferConfig;
76 
77 #define STREAMING_BUFFER_CONFIG_INITIALIZER { 0, 0, 0, NULL, NULL, NULL, NULL, }
78 
79 /**
80  *  \brief block of continues data
81  */
82 typedef struct StreamingBufferBlock {
83     uint64_t offset;
84     RB_ENTRY(StreamingBufferBlock) rb;
85     uint32_t len;
86 } __attribute__((__packed__)) StreamingBufferBlock;
87 
88 int SBBCompare(struct StreamingBufferBlock *a, struct StreamingBufferBlock *b);
89 
90 /* red-black tree prototype for SACK records */
91 RB_HEAD(SBB, StreamingBufferBlock);
92 RB_PROTOTYPE(SBB, StreamingBufferBlock, rb, SBBCompare);
93 StreamingBufferBlock *SBB_RB_FIND_INCLUSIVE(struct SBB *head, StreamingBufferBlock *elm);
94 
95 typedef struct StreamingBuffer_ {
96     const StreamingBufferConfig *cfg;
97     uint64_t stream_offset; /**< offset of the start of the memory block */
98 
99     uint8_t *buf;           /**< memory block for reassembly */
100     uint32_t buf_size;      /**< size of memory block */
101     uint32_t buf_offset;    /**< how far we are in buf_size */
102 
103     struct SBB sbb_tree;    /**< red black tree of Stream Buffer Blocks */
104     StreamingBufferBlock *head; /**< head, should always be the same as RB_MIN */
105     uint32_t sbb_size;          /**< data size covered by sbbs */
106 #ifdef DEBUG
107     uint32_t buf_size_max;
108 #endif
109 } StreamingBuffer;
110 
111 #ifndef DEBUG
112 #define STREAMING_BUFFER_INITIALIZER(cfg)                                                          \
113     {                                                                                              \
114         (cfg),                                                                                     \
115         0,                                                                                         \
116         NULL,                                                                                      \
117         0,                                                                                         \
118         0,                                                                                         \
119         { NULL },                                                                                  \
120         NULL,                                                                                      \
121         0,                                                                                         \
122     };
123 #else
124 #define STREAMING_BUFFER_INITIALIZER(cfg) { (cfg), 0, NULL, 0, 0, { NULL }, NULL, 0, 0 };
125 #endif
126 
127 typedef struct StreamingBufferSegment_ {
128     uint32_t segment_len;
129     uint64_t stream_offset;
130 } __attribute__((__packed__)) StreamingBufferSegment;
131 
132 StreamingBuffer *StreamingBufferInit(const StreamingBufferConfig *cfg);
133 void StreamingBufferClear(StreamingBuffer *sb);
134 void StreamingBufferFree(StreamingBuffer *sb);
135 
136 void StreamingBufferSlide(StreamingBuffer *sb, uint32_t slide);
137 void StreamingBufferSlideToOffset(StreamingBuffer *sb, uint64_t offset);
138 
139 StreamingBufferSegment *StreamingBufferAppendRaw(StreamingBuffer *sb,
140         const uint8_t *data, uint32_t data_len) WARN_UNUSED;
141 int StreamingBufferAppend(StreamingBuffer *sb, StreamingBufferSegment *seg,
142         const uint8_t *data, uint32_t data_len) WARN_UNUSED;
143 int StreamingBufferAppendNoTrack(StreamingBuffer *sb,
144         const uint8_t *data, uint32_t data_len) WARN_UNUSED;
145 int StreamingBufferInsertAt(StreamingBuffer *sb, StreamingBufferSegment *seg,
146                              const uint8_t *data, uint32_t data_len,
147                              uint64_t offset) WARN_UNUSED;
148 
149 void StreamingBufferSegmentGetData(const StreamingBuffer *sb,
150                                    const StreamingBufferSegment *seg,
151                                    const uint8_t **data, uint32_t *data_len);
152 
153 void StreamingBufferSBBGetData(const StreamingBuffer *sb,
154                                const StreamingBufferBlock *sbb,
155                                const uint8_t **data, uint32_t *data_len);
156 
157 void StreamingBufferSBBGetDataAtOffset(const StreamingBuffer *sb,
158                                        const StreamingBufferBlock *sbb,
159                                        const uint8_t **data, uint32_t *data_len,
160                                        uint64_t offset);
161 
162 int StreamingBufferSegmentCompareRawData(const StreamingBuffer *sb,
163                                          const StreamingBufferSegment *seg,
164                                          const uint8_t *rawdata, uint32_t rawdata_len);
165 int StreamingBufferCompareRawData(const StreamingBuffer *sb,
166                                   const uint8_t *rawdata, uint32_t rawdata_len);
167 
168 int StreamingBufferGetData(const StreamingBuffer *sb,
169         const uint8_t **data, uint32_t *data_len,
170         uint64_t *stream_offset);
171 
172 int StreamingBufferGetDataAtOffset (const StreamingBuffer *sb,
173         const uint8_t **data, uint32_t *data_len,
174         uint64_t offset);
175 
176 int StreamingBufferSegmentIsBeforeWindow(const StreamingBuffer *sb,
177                                          const StreamingBufferSegment *seg);
178 
179 void StreamingBufferRegisterTests(void);
180 
181 #endif /* __UTIL_STREAMING_BUFFER_H__ */
182