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