From bbf1f78ffef1e1ecbbada9155afc04f400247df3 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 29 Aug 2018 15:13:31 +0200 Subject: [PATCH] streaming: keep track of tree 'head' --- src/util-streaming-buffer.c | 65 +++++++++++++++++++++++++++++++++++-- src/util-streaming-buffer.h | 5 +-- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/src/util-streaming-buffer.c b/src/util-streaming-buffer.c index dc5d08e741..e02e7a8db4 100644 --- a/src/util-streaming-buffer.c +++ b/src/util-streaming-buffer.c @@ -193,6 +193,7 @@ static void SBBInit(StreamingBuffer *sb, sbb2->offset = sb->stream_offset + rel_offset; sbb2->len = data_len; + sb->head = sbb; SBB_RB_INSERT(&sb->sbb_tree, sbb); SBB_RB_INSERT(&sb->sbb_tree, sbb2); @@ -219,6 +220,7 @@ static void SBBInitLeadingGap(StreamingBuffer *sb, sbb->offset = offset; sbb->len = data_len; + sb->head = sbb; SBB_RB_INSERT(&sb->sbb_tree, sbb); SCLogDebug("sbb %"PRIu64", len %u", @@ -309,6 +311,8 @@ static inline void ConsolidateBackward(StreamingBuffer *sb, sa->offset = tr->offset; sa_re = sa->offset + sa->len; SCLogDebug("-> (bwd) tr %p %"PRIu64"/%u REMOVED ECLIPSED2", tr, tr->offset, tr->len); + if (sb->head == tr) + sb->head = sa; SBB_RB_REMOVE(tree, tr); FREE(sb->cfg, tr, sizeof(StreamingBufferBlock)); /* @@ -321,6 +325,8 @@ static inline void ConsolidateBackward(StreamingBuffer *sb, */ } else if (sa->offset <= tr->offset && sa_re >= tr_re) { SCLogDebug("-> (bwd) tr %p %"PRIu64"/%u REMOVED ECLIPSED", tr, tr->offset, tr->len); + if (sb->head == tr) + sb->head = sa; SBB_RB_REMOVE(tree, tr); FREE(sb->cfg, tr, sizeof(StreamingBufferBlock)); /* @@ -335,6 +341,8 @@ static inline void ConsolidateBackward(StreamingBuffer *sb, sa->offset = tr->offset; sa_re = sa->offset + sa->len; SCLogDebug("-> (bwd) tr %p %"PRIu64"/%u REMOVED MERGED", tr, tr->offset, tr->len); + if (sb->head == tr) + sb->head = sa; SBB_RB_REMOVE(tree, tr); FREE(sb->cfg, tr, sizeof(StreamingBufferBlock)); } @@ -358,7 +366,11 @@ static int Insert(StreamingBuffer *sb, struct SBB *tree, FREE(sb->cfg, sbb, sizeof(StreamingBufferBlock)); return 0; } - ConsolidateBackward(sb, tree, sbb); + if (SBB_RB_PREV(sbb) == NULL) { + sb->head = sbb; + } else { + ConsolidateBackward(sb, tree, sbb); + } ConsolidateFwd(sb, tree, sbb); #ifdef DEBUG SBBPrintList(sb); @@ -379,6 +391,7 @@ static void SBBFree(StreamingBuffer *sb) SBB_RB_REMOVE(&sb->sbb_tree, sbb); FREE(sb->cfg, sbb, sizeof(StreamingBufferBlock)); } + sb->head = NULL; } static void SBBPrune(StreamingBuffer *sb) @@ -387,8 +400,10 @@ static void SBBPrune(StreamingBuffer *sb) StreamingBufferBlock *sbb = NULL, *safe = NULL; RB_FOREACH_SAFE(sbb, SBB, &sb->sbb_tree, safe) { /* completely beyond window, we're done */ - if (sbb->offset > sb->stream_offset) + if (sbb->offset > sb->stream_offset) { + sb->head = sbb; break; + } /* partly before, partly beyond. Adjust */ if (sbb->offset < sb->stream_offset && @@ -400,10 +415,13 @@ static void SBBPrune(StreamingBuffer *sb) sbb->offset += shrink_by; DEBUG_VALIDATE_BUG_ON(sbb->offset != sb->stream_offset); } + sb->head = sbb; break; } SBB_RB_REMOVE(&sb->sbb_tree, sbb); + /* either we set it again for the next sbb, or there isn't any */ + sb->head = NULL; SCLogDebug("sb %p removed %p %"PRIu64", %u", sb, sbb, sbb->offset, sbb->len); FREE(sb->cfg, sbb, sizeof(StreamingBufferBlock)); } @@ -923,6 +941,7 @@ static int StreamingBufferTest01(void) FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,seg1,(const uint8_t *)"ABCDEFGH", 8)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,seg2,(const uint8_t *)"01234567", 8)); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment *seg3 = StreamingBufferAppendRaw(sb, (const uint8_t *)"QWERTY", 6); FAIL_IF(sb->stream_offset != 8); @@ -933,6 +952,7 @@ static int StreamingBufferTest01(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,seg3)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,seg3,(const uint8_t *)"QWERTY", 6)); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment *seg4 = StreamingBufferAppendRaw(sb, (const uint8_t *)"KLM", 3); FAIL_IF(sb->stream_offset != 14); @@ -944,6 +964,7 @@ static int StreamingBufferTest01(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,seg4)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,seg4,(const uint8_t *)"KLM", 3)); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment *seg5 = StreamingBufferAppendRaw(sb, (const uint8_t *)"!@#$%^&*()_+<>?/,.;:'[]{}-=", 27); FAIL_IF(sb->stream_offset != 17); @@ -956,6 +977,7 @@ static int StreamingBufferTest01(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,seg5)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,seg5,(const uint8_t *)"!@#$%^&*()_+<>?/,.;:'[]{}-=", 27)); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment *seg6 = StreamingBufferAppendRaw(sb, (const uint8_t *)"UVWXYZ", 6); FAIL_IF(sb->stream_offset != 17); @@ -969,6 +991,7 @@ static int StreamingBufferTest01(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,seg6)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,seg6,(const uint8_t *)"UVWXYZ", 6)); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); SCFree(seg1); SCFree(seg2); @@ -999,8 +1022,10 @@ static int StreamingBufferTest02(void) Dump(sb); DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSlide(sb, 6); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferAppend(sb, &seg3, (const uint8_t *)"QWERTY", 6) != 0); @@ -1014,6 +1039,7 @@ static int StreamingBufferTest02(void) DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); DumpSegment(sb, &seg3); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSlide(sb, 6); FAIL_IF(!StreamingBufferSegmentIsBeforeWindow(sb,&seg1)); @@ -1023,6 +1049,7 @@ static int StreamingBufferTest02(void) DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); DumpSegment(sb, &seg3); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferFree(sb); PASS; @@ -1047,6 +1074,7 @@ static int StreamingBufferTest03(void) Dump(sb); DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferInsertAt(sb, &seg3, (const uint8_t *)"QWERTY", 6, 8) != 0); @@ -1060,6 +1088,7 @@ static int StreamingBufferTest03(void) DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); DumpSegment(sb, &seg3); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSlide(sb, 10); FAIL_IF(!StreamingBufferSegmentIsBeforeWindow(sb,&seg1)); @@ -1069,6 +1098,7 @@ static int StreamingBufferTest03(void) DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); DumpSegment(sb, &seg3); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferFree(sb); PASS; @@ -1093,16 +1123,19 @@ static int StreamingBufferTest04(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,&seg2)); FAIL_IF(RB_EMPTY(&sb->sbb_tree)); StreamingBufferBlock *sbb1 = RB_MIN(SBB, &sb->sbb_tree); + FAIL_IF(sbb1 != sb->head); FAIL_IF_NULL(sbb1); FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 8); StreamingBufferBlock *sbb2 = SBB_RB_NEXT(sbb1); FAIL_IF_NULL(sbb2); + FAIL_IF(sbb2 == sb->head); FAIL_IF(sbb2->offset != 14); FAIL_IF(sbb2->len != 8); Dump(sb); DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferInsertAt(sb, &seg3, (const uint8_t *)"QWERTY", 6, 8) != 0); @@ -1114,6 +1147,7 @@ static int StreamingBufferTest04(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,&seg3)); sbb1 = RB_MIN(SBB, &sb->sbb_tree); FAIL_IF_NULL(sbb1); + FAIL_IF(sbb1 != sb->head); FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 22); FAIL_IF(SBB_RB_NEXT(sbb1)); @@ -1121,6 +1155,7 @@ static int StreamingBufferTest04(void) DumpSegment(sb, &seg1); DumpSegment(sb, &seg2); DumpSegment(sb, &seg3); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); /* far ahead of curve: */ StreamingBufferSegment seg4; @@ -1135,6 +1170,7 @@ static int StreamingBufferTest04(void) FAIL_IF(StreamingBufferSegmentIsBeforeWindow(sb,&seg4)); sbb1 = RB_MIN(SBB, &sb->sbb_tree); FAIL_IF_NULL(sbb1); + FAIL_IF(sbb1 != sb->head); FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 22); FAIL_IF(!SBB_RB_NEXT(sbb1)); @@ -1143,6 +1179,7 @@ static int StreamingBufferTest04(void) DumpSegment(sb, &seg2); DumpSegment(sb, &seg3); DumpSegment(sb, &seg4); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,&seg1,(const uint8_t *)"ABCDEFGH", 8)); FAIL_IF(!StreamingBufferSegmentCompareRawData(sb,&seg2,(const uint8_t *)"01234567", 8)); @@ -1177,9 +1214,11 @@ static int StreamingBufferTest05(void) FAIL_IF(!StreamingBufferSegmentCompareRawData(&sb,seg3,(const uint8_t *)"CCCCCCCC", 8)); FAIL_IF(!StreamingBufferSegmentCompareRawData(&sb,seg4,(const uint8_t *)"DDDDDDDD", 8)); Dump(&sb); + FAIL_IF_NOT(sb.head == RB_MIN(SBB, &sb.sbb_tree)); StreamingBufferSegment *seg5 = StreamingBufferAppendRaw(&sb, (const uint8_t *)"EEEEEEEE", 8); FAIL_IF(!StreamingBufferSegmentCompareRawData(&sb,seg5,(const uint8_t *)"EEEEEEEE", 8)); Dump(&sb); + FAIL_IF_NOT(sb.head == RB_MIN(SBB, &sb.sbb_tree)); SCFree(seg1); SCFree(seg2); @@ -1202,14 +1241,17 @@ static int StreamingBufferTest06(void) StreamingBufferSegment seg2; FAIL_IF(StreamingBufferInsertAt(sb, &seg2, (const uint8_t *)"C", 1, 2) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferInsertAt(sb, &seg3, (const uint8_t *)"F", 1, 5) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg4; FAIL_IF(StreamingBufferInsertAt(sb, &seg4, (const uint8_t *)"H", 1, 7) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg5; FAIL_IF(StreamingBufferInsertAt(sb, &seg5, (const uint8_t *)"ABCDEFGHIJ", 10, 0) != 0); @@ -1219,6 +1261,7 @@ static int StreamingBufferTest06(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg6; FAIL_IF(StreamingBufferInsertAt(sb, &seg6, (const uint8_t *)"abcdefghij", 10, 0) != 0); @@ -1228,6 +1271,7 @@ static int StreamingBufferTest06(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferFree(sb); PASS; @@ -1245,14 +1289,17 @@ static int StreamingBufferTest07(void) StreamingBufferSegment seg2; FAIL_IF(StreamingBufferInsertAt(sb, &seg2, (const uint8_t *)"D", 1, 3) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferInsertAt(sb, &seg3, (const uint8_t *)"F", 1, 5) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg4; FAIL_IF(StreamingBufferInsertAt(sb, &seg4, (const uint8_t *)"H", 1, 7) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg5; FAIL_IF(StreamingBufferInsertAt(sb, &seg5, (const uint8_t *)"ABCDEFGHIJ", 10, 0) != 0); @@ -1262,6 +1309,7 @@ static int StreamingBufferTest07(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg6; FAIL_IF(StreamingBufferInsertAt(sb, &seg6, (const uint8_t *)"abcdefghij", 10, 0) != 0); @@ -1271,6 +1319,7 @@ static int StreamingBufferTest07(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferFree(sb); PASS; @@ -1288,14 +1337,17 @@ static int StreamingBufferTest08(void) StreamingBufferSegment seg2; FAIL_IF(StreamingBufferInsertAt(sb, &seg2, (const uint8_t *)"D", 1, 3) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferInsertAt(sb, &seg3, (const uint8_t *)"F", 1, 5) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg4; FAIL_IF(StreamingBufferInsertAt(sb, &seg4, (const uint8_t *)"H", 1, 7) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg5; FAIL_IF(StreamingBufferInsertAt(sb, &seg5, (const uint8_t *)"ABCDEFGHIJ", 10, 0) != 0); @@ -1305,6 +1357,7 @@ static int StreamingBufferTest08(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg6; FAIL_IF(StreamingBufferAppend(sb, &seg6, (const uint8_t *)"abcdefghij", 10) != 0); @@ -1314,6 +1367,7 @@ static int StreamingBufferTest08(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 20); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferFree(sb); PASS; @@ -1331,14 +1385,17 @@ static int StreamingBufferTest09(void) StreamingBufferSegment seg2; FAIL_IF(StreamingBufferInsertAt(sb, &seg2, (const uint8_t *)"D", 1, 3) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg3; FAIL_IF(StreamingBufferInsertAt(sb, &seg3, (const uint8_t *)"H", 1, 7) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg4; FAIL_IF(StreamingBufferInsertAt(sb, &seg4, (const uint8_t *)"F", 1, 5) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg5; FAIL_IF(StreamingBufferInsertAt(sb, &seg5, (const uint8_t *)"ABCDEFGHIJ", 10, 0) != 0); @@ -1348,6 +1405,7 @@ static int StreamingBufferTest09(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg6; FAIL_IF(StreamingBufferInsertAt(sb, &seg6, (const uint8_t *)"abcdefghij", 10, 0) != 0); @@ -1357,6 +1415,7 @@ static int StreamingBufferTest09(void) FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); FAIL_IF(SBB_RB_NEXT(sbb1)); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferFree(sb); PASS; @@ -1388,6 +1447,7 @@ static int StreamingBufferTest10(void) StreamingBufferSegment seg6; FAIL_IF(StreamingBufferInsertAt(sb, &seg6, (const uint8_t *)"G", 1, 6) != 0); Dump(sb); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); StreamingBufferSegment seg7; FAIL_IF(StreamingBufferInsertAt(sb, &seg7, (const uint8_t *)"ABCDEFGHIJ", 10, 0) != 0); @@ -1402,6 +1462,7 @@ static int StreamingBufferTest10(void) FAIL_IF(StreamingBufferInsertAt(sb, &seg8, (const uint8_t *)"abcdefghij", 10, 0) != 0); Dump(sb); sbb1 = RB_MIN(SBB, &sb->sbb_tree); + FAIL_IF_NOT(sb->head == RB_MIN(SBB, &sb->sbb_tree)); FAIL_IF_NULL(sbb1); FAIL_IF(sbb1->offset != 0); FAIL_IF(sbb1->len != 10); diff --git a/src/util-streaming-buffer.h b/src/util-streaming-buffer.h index defe09ce23..f346e432ab 100644 --- a/src/util-streaming-buffer.h +++ b/src/util-streaming-buffer.h @@ -101,15 +101,16 @@ typedef struct StreamingBuffer_ { uint32_t buf_offset; /**< how far we are in buf_size */ struct SBB sbb_tree; /**< red black tree of Stream Buffer Blocks */ + StreamingBufferBlock *head; /**< head, should always be the same as RB_MIN */ #ifdef DEBUG uint32_t buf_size_max; #endif } StreamingBuffer; #ifndef DEBUG -#define STREAMING_BUFFER_INITIALIZER(cfg) { (cfg), 0, NULL, 0, 0, { NULL }, }; +#define STREAMING_BUFFER_INITIALIZER(cfg) { (cfg), 0, NULL, 0, 0, { NULL }, NULL, }; #else -#define STREAMING_BUFFER_INITIALIZER(cfg) { (cfg), 0, NULL, 0, 0, { NULL }, 0 }; +#define STREAMING_BUFFER_INITIALIZER(cfg) { (cfg), 0, NULL, 0, 0, { NULL }, NULL, 0 }; #endif typedef struct StreamingBufferSegment_ {