#include "util-print.h"
#include "util-validate.h"
-//static void PrintList2(TcpSegment *seg);
-
static void StreamTcpRemoveSegmentFromStream(TcpStream *stream, TcpSegment *seg);
static int check_overlap_different_data = 0;
* Inserts and overlap handling
*/
+RB_GENERATE(TCPSEG, TcpSegment, rb, TcpSegmentCompare);
+
+int TcpSegmentCompare(struct TcpSegment *a, struct TcpSegment *b)
+{
+ if (SEQ_GT(a->seq, b->seq))
+ return 1;
+ else if (SEQ_LT(a->seq, b->seq))
+ return -1;
+ else {
+ if (a->payload_len == b->payload_len)
+ return 0;
+ else if (a->payload_len > b->payload_len)
+ return 1;
+ else
+ return -1;
+ }
+}
/** \internal
* \brief insert segment data into the streaming buffer
}
/** \internal
- * \brief insert the segment into the proper place in the list
+ * \brief check if this segments overlaps with an in-tree seg.
+ * \retval true
+ * \retval false
+ */
+static inline bool CheckOverlap(struct TCPSEG *tree, TcpSegment *seg)
+{
+ const uint32_t re = SEG_SEQ_RIGHT_EDGE(seg);
+ SCLogDebug("start. SEQ %u payload_len %u. Right edge: %u. Seg %p",
+ seg->seq, seg->payload_len, re, seg);
+
+ /* check forward */
+ TcpSegment *next = TCPSEG_RB_NEXT(seg);
+ if (next) {
+ // next has same seq, so data must overlap
+ if (SEQ_EQ(next->seq, seg->seq))
+ return true;
+ // our right edge is beyond next seq, overlap
+ if (SEQ_GT(re, next->seq))
+ return true;
+ }
+ /* check backwards */
+ TcpSegment *prev = TCPSEG_RB_PREV(seg);
+ if (prev) {
+ // prev has same seq, so data must overlap
+ if (SEQ_EQ(prev->seq, seg->seq))
+ return true;
+ // prev's right edge is beyond our seq, overlap
+ const uint32_t prev_re = SEG_SEQ_RIGHT_EDGE(prev);
+ if (SEQ_GT(prev_re, prev->seq))
+ return true;
+ }
+
+ SCLogDebug("no overlap");
+ return false;
+}
+
+/** \internal
+ * \brief insert the segment into the proper place in the tree
* don't worry about the data or overlaps
*
- * If seq is equal to list seq, keep sorted by insert time.
- * 1. seg 123 len 12
- * 2. seg 123 len 14
- * 3. seg 124 len 1
- *
+ * \retval 2 not inserted, data overlap
* \retval 1 inserted with overlap detected
* \retval 0 inserted, no overlap
* \retval -1 error
*/
-static int DoInsertSegment (TcpStream *stream, TcpSegment *seg, Packet *p)
+static int DoInsertSegment (TcpStream *stream, TcpSegment *seg, TcpSegment **dup_seg, Packet *p)
{
/* before our base_seq we don't insert it in our list */
- if (SEQ_LEQ((seg->seq + TCP_SEG_LEN(seg)), stream->base_seq))
+ if (SEQ_LEQ(SEG_SEQ_RIGHT_EDGE(seg), stream->base_seq))
{
SCLogDebug("not inserting: SEQ+payload %"PRIu32", last_ack %"PRIu32", "
"base_seq %"PRIu32, (seg->seq + TCP_SEG_LEN(seg)),
}
/* fast track */
- if (stream->seg_list == NULL) {
- SCLogDebug("empty list, inserting seg %p seq %" PRIu32 ", "
+ if (RB_EMPTY(&stream->seg_tree)) {
+ SCLogDebug("empty tree, inserting seg %p seq %" PRIu32 ", "
"len %" PRIu32 "", seg, seg->seq, TCP_SEG_LEN(seg));
- stream->seg_list = seg;
- seg->prev = NULL;
- stream->seg_list_tail = seg;
+ TCPSEG_RB_INSERT(&stream->seg_tree, seg);
return 0;
}
- /* insert the segment in the stream list using this fast track, if seg->seq
- is equal or higher than stream->seg_list_tail.*/
- if (SEQ_GEQ(seg->seq, (stream->seg_list_tail->seq +
- TCP_SEG_LEN(stream->seg_list_tail))))
+ /* insert the segment in the stream tree using this fast track, if seg->seq
+ is equal or higher than last segments tail. */
+ TcpSegment *last = RB_MAX(TCPSEG, &stream->seg_tree);
+ if (last && SEQ_GEQ(seg->seq, (uint32_t)SEG_SEQ_RIGHT_EDGE(last)))
{
- SCLogDebug("seg beyond list tail, append");
- stream->seg_list_tail->next = seg;
- seg->prev = stream->seg_list_tail;
- stream->seg_list_tail = seg;
+ SCLogDebug("seg beyond tree tail, append");
+ TCPSEG_RB_INSERT(&stream->seg_tree, seg);
return 0;
}
- /* walk the list to see where we can insert the segment.
- * Check if a segment overlaps with us, if so we return 1 to indicate
- * to the caller that we need to handle overlaps. */
- TcpSegment *list_seg;
- for (list_seg = stream->seg_list; list_seg != NULL; list_seg = list_seg->next)
- {
- if (SEQ_LT(seg->seq, list_seg->seq)) {
- if (list_seg->prev != NULL) {
- list_seg->prev->next = seg;
- } else {
- stream->seg_list = seg;
- }
- seg->prev = list_seg->prev;
- seg->next = list_seg;
- list_seg->prev = seg;
-
- SCLogDebug("inserted %u before %p seq %u", seg->seq, list_seg, list_seg->seq);
-
- if (seg->prev != NULL) {
- SCLogDebug("previous %u", seg->prev->seq);
- }
- if (seg->next != NULL) {
- SCLogDebug("next %u", seg->next->seq);
- }
- if (seg->prev != NULL && SEQ_GT(SEG_SEQ_RIGHT_EDGE(seg->prev), seg->seq)) {
- SCLogDebug("seg inserted with overlap (before)");
- return 1;
- }
- else if (SEQ_GT(SEG_SEQ_RIGHT_EDGE(seg), seg->next->seq)) {
- SCLogDebug("seg inserted with overlap (after)");
- return 1;
- }
-
- return 0;
+ /* insert and then check if there was any overlap with other segments */
+ TcpSegment *res = TCPSEG_RB_INSERT(&stream->seg_tree, seg);
+ if (res) {
+ SCLogDebug("seg has a duplicate in the tree seq %u/%u",
+ res->seq, res->payload_len);
+ /* exact duplicate SEQ + payload_len */
+ *dup_seg = res;
+ return 2; // duplicate has overlap by definition.
+ } else {
+ /* insert succeeded, now check if we overlap with someone */
+ if (CheckOverlap(&stream->seg_tree, seg) == true) {
+ SCLogDebug("seg %u has overlap in the tree", seg->seq);
+ return 1;
}
}
- /* if we got here we didn't insert. Append */
- seg->prev = stream->seg_list_tail;
- stream->seg_list_tail->next = seg;
- stream->seg_list_tail = seg;
-
- if (seg->prev != NULL && SEQ_GT(SEG_SEQ_RIGHT_EDGE(seg->prev), seg->seq)) {
- SCLogDebug("seg inserted with overlap (before)");
- return 1;
- }
-
- SCLogDebug("default: append");
+ SCLogDebug("seg %u: no overlap", seg->seq);
return 0;
}
* \retval 1 if data was different
* \retval 0 data was the same or we didn't check for differences
*/
-static int DoHandleDataOverlap(TcpStream *stream, TcpSegment *list, TcpSegment *seg, uint8_t *buf, Packet *p)
+static int DoHandleDataOverlap(TcpStream *stream, const TcpSegment *list,
+ const TcpSegment *seg, uint8_t *buf, Packet *p)
{
SCLogDebug("handle overlap for segment %p seq %u len %u re %u, "
- "list segment %p seq %u len %u re %u", seg, seg->seq, p->payload_len, SEG_SEQ_RIGHT_EDGE(seg),
+ "list segment %p seq %u len %u re %u", seg, seg->seq,
+ p->payload_len, SEG_SEQ_RIGHT_EDGE(seg),
list, list->seq, TCP_SEG_LEN(list), SEG_SEQ_RIGHT_EDGE(list));
int data_is_different = 0;
#define MAX_IP_DATA (uint32_t)(65536 - 40) // min ip header and min tcp header
/** \internal
- * \brief walk segment list backwards to see if there are overlaps
+ * \brief walk segment tree backwards to see if there are overlaps
*
- * Walk back from the current segment which is already in the list.
+ * Walk back from the current segment which is already in the tree.
* We walk until we can't possibly overlap anymore.
*/
-static int DoHandleDataCheckBackwards(TcpStream *stream, TcpSegment *seg, uint8_t *buf, Packet *p)
+static int DoHandleDataCheckBackwards(TcpStream *stream,
+ TcpSegment *seg, uint8_t *buf, Packet *p)
{
int retval = 0;
- SCLogDebug("check list backwards: insert data for segment %p seq %u len %u re %u",
+ SCLogDebug("check tree backwards: insert data for segment %p seq %u len %u re %u",
seg, seg->seq, TCP_SEG_LEN(seg), SEG_SEQ_RIGHT_EDGE(seg));
- TcpSegment *list = seg->prev;
- do {
+ /* check backwards */
+ TcpSegment *tree_seg = NULL, *s = seg;
+ RB_FOREACH_REVERSE_FROM(tree_seg, TCPSEG, s) {
+ if (tree_seg == seg)
+ continue;
+
int overlap = 0;
- if (SEQ_LEQ(SEG_SEQ_RIGHT_EDGE(list), stream->base_seq)) {
+ if (SEQ_LEQ(SEG_SEQ_RIGHT_EDGE(tree_seg), stream->base_seq)) {
// segment entirely before base_seq
;
- } else if (SEQ_LEQ(list->seq + MAX_IP_DATA, seg->seq)) {
+ } else if (SEQ_LEQ(tree_seg->seq + MAX_IP_DATA, seg->seq)) {
SCLogDebug("list segment too far to the left, no more overlap will be found");
break;
- } else if (SEQ_GT(SEG_SEQ_RIGHT_EDGE(list), seg->seq)) {
+ } else if (SEQ_GT(SEG_SEQ_RIGHT_EDGE(tree_seg), seg->seq)) {
overlap = 1;
}
- SCLogDebug("(back) list seg %u len %u re %u overlap? %s", list->seq, TCP_SEG_LEN(list),
- SEG_SEQ_RIGHT_EDGE(list), overlap ? "yes" : "no");
+ SCLogDebug("(back) tree seg %u len %u re %u overlap? %s",
+ tree_seg->seq, TCP_SEG_LEN(tree_seg),
+ SEG_SEQ_RIGHT_EDGE(tree_seg), overlap ? "yes" : "no");
if (overlap) {
- retval |= DoHandleDataOverlap(stream, list, seg, buf, p);
+ retval |= DoHandleDataOverlap(stream, tree_seg, seg, buf, p);
}
-
- list = list->prev;
- } while (list != NULL);
-
+ }
return retval;
}
/** \internal
- * \brief walk segment list in forward direction to see if there are overlaps
+ * \brief walk segment tree in forward direction to see if there are overlaps
*
- * Walk forward from the current segment which is already in the list.
+ * Walk forward from the current segment which is already in the tree.
* We walk until the next segs start with a SEQ beyond our right edge.
*/
-static int DoHandleDataCheckForward(TcpStream *stream, TcpSegment *seg, uint8_t *buf, Packet *p)
+static int DoHandleDataCheckForward(TcpStream *stream,
+ TcpSegment *seg, uint8_t *buf, Packet *p)
{
int retval = 0;
SCLogDebug("check list forward: insert data for segment %p seq %u len %u re %u",
seg, seg->seq, TCP_SEG_LEN(seg), seg_re);
- TcpSegment *list = seg->next;
- do {
+ TcpSegment *tree_seg = NULL, *s = seg;
+ RB_FOREACH_FROM(tree_seg, TCPSEG, s) {
+ if (tree_seg == seg)
+ continue;
+
int overlap = 0;
- if (SEQ_GT(seg_re, list->seq))
+ if (SEQ_GT(seg_re, tree_seg->seq))
overlap = 1;
- else if (SEQ_LEQ(seg_re, list->seq)) {
- SCLogDebug("list segment %u too far ahead, "
- "no more overlaps can happen", list->seq);
+ else if (SEQ_LEQ(seg_re, tree_seg->seq)) {
+ SCLogDebug("tree segment %u too far ahead, "
+ "no more overlaps can happen", tree_seg->seq);
break;
}
- SCLogDebug("(fwd) list seg %u len %u re %u overlap? %s", list->seq,
- TCP_SEG_LEN(list), SEG_SEQ_RIGHT_EDGE(list), overlap ? "yes" : "no");
+ SCLogDebug("(fwd) in-tree seg %u len %u re %u overlap? %s",
+ tree_seg->seq, TCP_SEG_LEN(tree_seg),
+ SEG_SEQ_RIGHT_EDGE(tree_seg), overlap ? "yes" : "no");
if (overlap) {
- retval |= DoHandleDataOverlap(stream, list, seg, buf, p);
+ retval |= DoHandleDataOverlap(stream, tree_seg, seg, buf, p);
}
-
- list = list->next;
- } while (list != NULL);
-
+ }
return retval;
}
+/**
+ * \param dup_seg in-tree duplicate of `seg`
+ */
static int DoHandleData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
- TcpStream *stream, TcpSegment *seg, Packet *p)
+ TcpStream *stream, TcpSegment *seg, TcpSegment *tree_seg, Packet *p)
{
int result = 0;
+ TcpSegment *handle = seg;
SCLogDebug("insert data for segment %p seq %u len %u re %u",
seg, seg->seq, TCP_SEG_LEN(seg), SEG_SEQ_RIGHT_EDGE(seg));
uint8_t buf[p->payload_len];
memcpy(buf, p->payload, p->payload_len);
+ /* if tree_seg is set, we have an exact duplicate that we need to check */
+ if (tree_seg) {
+ DoHandleDataOverlap(stream, tree_seg, seg, buf, p);
+ handle = tree_seg;
+ }
+
/* new list head */
- if (seg->next != NULL && seg->prev == NULL) {
- result = DoHandleDataCheckForward(stream, seg, buf, p);
+ if (handle == RB_MIN(TCPSEG, &stream->seg_tree) && TCPSEG_RB_NEXT(handle)) {
+ result = DoHandleDataCheckForward(stream, handle, buf, p);
/* new list tail */
- } else if (seg->next == NULL && seg->prev != NULL) {
- result = DoHandleDataCheckBackwards(stream, seg, buf, p);
+ } else if (handle == RB_MAX(TCPSEG, &stream->seg_tree) && TCPSEG_RB_PREV(handle)) {
+ result = DoHandleDataCheckBackwards(stream, handle, buf, p);
/* middle of the list */
- } else if (seg->next != NULL && seg->prev != NULL) {
- result = DoHandleDataCheckBackwards(stream, seg, buf, p);
- result |= DoHandleDataCheckForward(stream, seg, buf, p);
+ } else if (TCPSEG_RB_NEXT(handle) && TCPSEG_RB_PREV(handle)) {
+ result = DoHandleDataCheckBackwards(stream, handle, buf, p);
+ result |= DoHandleDataCheckForward(stream, handle, buf, p);
}
/* we had an overlap with different data */
/* insert the temp buffer now that we've (possibly) updated
* it to account for the overlap policies */
- if (InsertSegmentDataCustom(stream, seg, buf, p->payload_len) < 0) {
+ if (InsertSegmentDataCustom(stream, handle, buf, p->payload_len) < 0) {
return -1;
}
* In case of error, this function returns the segment to the pool
*/
int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
- TcpStream *stream, TcpSegment *seg, Packet *p, uint32_t pkt_seq, uint8_t *pkt_data, uint16_t pkt_datalen)
+ TcpStream *stream, TcpSegment *seg, Packet *p,
+ uint32_t pkt_seq, uint8_t *pkt_data, uint16_t pkt_datalen)
{
-#ifdef DEBUG
- SCLogDebug("pre insert");
- PrintList(stream->seg_list);
-#endif
+ SCEnter();
+
+ TcpSegment *dup_seg = NULL;
/* insert segment into list. Note: doesn't handle the data */
- int r = DoInsertSegment (stream, seg, p);
+ int r = DoInsertSegment (stream, seg, &dup_seg, p);
+ SCLogDebug("DoInsertSegment returned %d", r);
if (r < 0) {
StatsIncr(tv, ra_ctx->counter_tcp_reass_list_fail);
StreamTcpSegmentReturntoPool(seg);
SCReturnInt(-1);
}
-#ifdef DEBUG
- SCLogDebug("post insert");
- PrintList(stream->seg_list);
-#endif
-
if (likely(r == 0)) {
/* no overlap, straight data insert */
int res = InsertSegmentDataCustom(stream, seg, pkt_data, pkt_datalen);
SCReturnInt(-1);
}
- } else if (r == 1) {
+ } else if (r == 1 || r == 2) {
+ SCLogDebug("overlap (%s%s)", r == 1 ? "normal" : "", r == 2 ? "duplicate" : "");
+
+ if (r == 2) {
+ SCLogDebug("dup_seg %p", dup_seg);
+ }
+
/* XXX should we exclude 'retransmissions' here? */
StatsIncr(tv, ra_ctx->counter_tcp_reass_overlap);
/* now let's consider the data in the overlap case */
- int res = DoHandleData(tv, ra_ctx, stream, seg, p);
+ int res = DoHandleData(tv, ra_ctx, stream, seg, dup_seg, p);
if (res < 0) {
StatsIncr(tv, ra_ctx->counter_tcp_reass_data_overlap_fail);
- StreamTcpRemoveSegmentFromStream(stream, seg);
+
+ if (r == 1) // r == 2 mean seg wasn't added to stream
+ StreamTcpRemoveSegmentFromStream(stream, seg);
+
StreamTcpSegmentReturntoPool(seg);
SCReturnInt(-1);
}
+ if (r == 2) {
+ SCLogDebug("duplicate segment %u/%u, discard it",
+ seg->seq, seg->payload_len);
+
+ StreamTcpSegmentReturntoPool(seg);
+#ifdef DEBUG
+ if (SCLogDebugEnabled()) {
+ TcpSegment *s = NULL, *safe = NULL;
+ RB_FOREACH_SAFE(s, TCPSEG, &stream->seg_tree, safe)
+ {
+ SCLogDebug("tree: seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32"%s%s%s",
+ s, s->seq, TCP_SEG_LEN(s),
+ (uint32_t)(s->seq + TCP_SEG_LEN(s)),
+ s->seq == seg->seq ? " DUPLICATE" : "",
+ TCPSEG_RB_PREV(s) == NULL ? " HEAD" : "",
+ TCPSEG_RB_NEXT(s) == NULL ? " TAIL" : "");
+ }
+ }
+#endif
+ }
}
SCReturnInt(0);
/* we know left edge based on the progress values now,
* lets adjust it to make sure in-use segments still have
* data */
- const TcpSegment *seg;
- for (seg = stream->seg_list; seg != NULL; seg = seg->next)
- {
+ TcpSegment *seg = NULL;
+ RB_FOREACH(seg, TCPSEG, &stream->seg_tree) {
if (TCP_SEG_OFFSET(seg) > left_edge) {
SCLogDebug("seg beyond left_edge, we're done");
break;
static void StreamTcpRemoveSegmentFromStream(TcpStream *stream, TcpSegment *seg)
{
- if (seg->prev == NULL) {
- stream->seg_list = seg->next;
- if (stream->seg_list != NULL)
- stream->seg_list->prev = NULL;
- } else {
- seg->prev->next = seg->next;
- if (seg->next != NULL)
- seg->next->prev = seg->prev;
- }
-
- if (stream->seg_list_tail == seg)
- stream->seg_list_tail = seg->prev;
+ RB_REMOVE(TCPSEG, &stream->seg_tree, seg);
}
/** \brief Remove idle TcpSegments from TcpSession
stream->base_seq, STREAM_BASE_OFFSET(stream));
}
- /* loop through the segments and fill one or more msgs */
- TcpSegment *seg = stream->seg_list;
- while (seg != NULL)
+ /* loop through the segments and remove all not in use */
+ TcpSegment *seg = NULL, *safe = NULL;
+ RB_FOREACH_SAFE(seg, TCPSEG, &stream->seg_tree, safe)
{
SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32,
seg, seg->seq, TCP_SEG_LEN(seg),
break;
}
- TcpSegment *next_seg = seg->next;
StreamTcpRemoveSegmentFromStream(stream, seg);
StreamTcpSegmentReturntoPool(seg);
- seg = next_seg;
SCLogDebug("removed segment");
continue;
}
-#ifdef DEBUG
- PrintList(stream->seg_list);
-#endif
- SCReturn;
-}
-
-/*
- * Utils
- */
-
-#if 0
-void PrintList2(TcpSegment *seg)
-{
- TcpSegment *prev_seg = NULL;
-
- if (seg == NULL)
- return;
-
- uint32_t next_seq = seg->seq;
-
- while (seg != NULL) {
- if (SEQ_LT(next_seq,seg->seq)) {
- SCLogDebug("missing segment(s) for %" PRIu32 " bytes of data",
- (seg->seq - next_seq));
- }
-
- SCLogDebug("seg %10"PRIu32" len %" PRIu16 ", seg %p, prev %p, next %p",
- seg->seq, TCP_SEG_LEN(seg), seg, seg->prev, seg->next);
-
- if (seg->prev != NULL && SEQ_LT(seg->seq,seg->prev->seq)) {
- /* check for SEQ_LT cornercase where a - b is exactly 2147483648,
- * which makes the marco return TRUE in both directions. This is
- * a hack though, we're going to check next how we end up with
- * a segment list with seq differences that big */
- if (!(SEQ_LT(seg->prev->seq,seg->seq))) {
- SCLogDebug("inconsistent list: SEQ_LT(seg->seq,seg->prev->seq)) =="
- " TRUE, seg->seq %" PRIu32 ", seg->prev->seq %" PRIu32 ""
- "", seg->seq, seg->prev->seq);
- }
- }
-
- if (SEQ_LT(seg->seq,next_seq)) {
- SCLogDebug("inconsistent list: SEQ_LT(seg->seq,next_seq)) == TRUE, "
- "seg->seq %" PRIu32 ", next_seq %" PRIu32 "", seg->seq,
- next_seq);
- }
-
- if (prev_seg != seg->prev) {
- SCLogDebug("inconsistent list: prev_seg %p != seg->prev %p",
- prev_seg, seg->prev);
- }
-
- next_seq = seg->seq + TCP_SEG_LEN(seg);
- SCLogDebug("next_seq is now %"PRIu32"", next_seq);
- prev_seg = seg;
- seg = seg->next;
- }
-}
-#endif
-
-void PrintList(TcpSegment *seg)
-{
- TcpSegment *prev_seg = NULL;
-// TcpSegment *head_seg = seg;
- if (seg == NULL)
- return;
-
- uint32_t next_seq = seg->seq;
-
- while (seg != NULL) {
- if (SEQ_LT(next_seq,seg->seq)) {
- SCLogDebug("missing segment(s) for %" PRIu32 " bytes of data",
- (seg->seq - next_seq));
- }
-
- SCLogDebug("seg %10"PRIu32" len %" PRIu16 ", seg %p, prev %p, next %p",
- seg->seq, TCP_SEG_LEN(seg), seg, seg->prev, seg->next);
-
- if (seg->prev != NULL && SEQ_LT(seg->seq,seg->prev->seq)) {
- /* check for SEQ_LT cornercase where a - b is exactly 2147483648,
- * which makes the marco return TRUE in both directions. This is
- * a hack though, we're going to check next how we end up with
- * a segment list with seq differences that big */
- if (!(SEQ_LT(seg->prev->seq,seg->seq))) {
- SCLogDebug("inconsistent list: SEQ_LT(seg->seq,seg->prev->seq)) == "
- "TRUE, seg->seq %" PRIu32 ", seg->prev->seq %" PRIu32 "",
- seg->seq, seg->prev->seq);
-// PrintList2(head_seg);
-// abort();
- }
- }
-
- if (SEQ_LT(seg->seq,next_seq)) {
- SCLogDebug("inconsistent list: SEQ_LT(seg->seq,next_seq)) == TRUE, "
- "seg->seq %" PRIu32 ", next_seq %" PRIu32 "", seg->seq,
- next_seq);
-// PrintList2(head_seg);
-// abort();
- }
-
- if (prev_seg != seg->prev) {
- SCLogDebug("inconsistent list: prev_seg %p != seg->prev %p",
- prev_seg, seg->prev);
-// PrintList2(head_seg);
- abort();
- }
-
- next_seq = seg->seq + TCP_SEG_LEN(seg);
- SCLogDebug("next_seq is now %"PRIu32"", next_seq);
- prev_seg = seg;
- seg = seg->next;
- }
+ SCReturn;
}
-#if 0
-void ValidateList(const TcpStream *stream)
-{
- TcpSegment *seg = stream->seg_list;
- TcpSegment *prev_seg = NULL;
-
- BUG_ON(seg && seg->next == NULL && stream->seg_list != stream->seg_list_tail);
- BUG_ON(stream->seg_list != stream->seg_list_tail && stream->seg_list_tail->prev == NULL);
-
- while (seg != NULL) {
- prev_seg = seg;
- seg = seg->next;
- BUG_ON(seg && seg->prev != prev_seg);
-
- // equal is possible
- BUG_ON(seg && SEQ_LT(seg->seq, prev_seg->seq));
- }
-}
-#endif
/*
* unittests
if (seg == NULL)
return;
- seg->next = NULL;
- seg->prev = NULL;
PoolThreadReturn(segment_thread_pool, seg);
}
*/
void StreamTcpReturnStreamSegments (TcpStream *stream)
{
- TcpSegment *seg = stream->seg_list;
- TcpSegment *next_seg;
-
- if (seg == NULL)
- return;
-
- while (seg != NULL) {
- next_seg = seg->next;
+ TcpSegment *seg = NULL, *safe = NULL;
+ RB_FOREACH_SAFE(seg, TCPSEG, &stream->seg_tree, safe)
+ {
+ RB_REMOVE(TCPSEG, &stream->seg_tree, seg);
StreamTcpSegmentReturntoPool(seg);
- seg = next_seg;
}
-
- stream->seg_list = NULL;
- stream->seg_list_tail = NULL;
}
/** \internal
seg->seq = TCP_GET_SEQ(p);
/* proto detection skipped, but now we do get data. Set event. */
- if (stream->seg_list == NULL &&
+ if (RB_EMPTY(&stream->seg_tree) &&
stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED) {
AppLayerDecoderEventsSetEventRaw(&p->app_layer_events,
uint64_t right_edge = STREAM_BASE_OFFSET(stream) + stream->sb.buf_offset;
- SCLogDebug("%s: list %p app %"PRIu64" (use: %s), raw %"PRIu64" (use: %s). Stream right edge: %"PRIu64,
+ SCLogDebug("%s: app %"PRIu64" (use: %s), raw %"PRIu64" (use: %s). Stream right edge: %"PRIu64,
dirstr,
- stream->seg_list,
STREAM_APP_PROGRESS(stream), use_app ? "yes" : "no",
STREAM_RAW_PROGRESS(stream), use_raw ? "yes" : "no",
right_edge);
uint64_t size = 0;
uint32_t cnt = 0;
- TcpSegment *seg = stream->seg_list;
- while (seg) {
+ TcpSegment *seg;
+ RB_FOREACH(seg, TCPSEG, &stream->seg_tree) {
cnt++;
size += (uint64_t)TCP_SEG_LEN(seg);
-
- seg = seg->next;
}
SCLogDebug("size %"PRIu64", cnt %"PRIu32, size, cnt);
SCReturnInt(0);
}
- SCLogDebug("stream->seg_list %p", stream->seg_list);
#ifdef DEBUG
- PrintList(stream->seg_list);
+ SCLogDebug("stream->seg_tree RB_MIN %p", RB_MIN(TCPSEG, &stream->seg_tree));
GetSessionSize(ssn, p);
#endif
/* if no segments are in the list or all are already processed,
* and state is beyond established, we send an empty msg */
- TcpSegment *seg_tail = stream->seg_list_tail;
+ TcpSegment *seg_tail = RB_MAX(TCPSEG, &stream->seg_tree);
if (seg_tail == NULL ||
SEGMENT_BEFORE_OFFSET(stream, seg_tail, STREAM_APP_PROGRESS(stream)))
{
stream = &ssn->server;
}
- if (stream->seg_list == NULL) {
+ if (RB_EMPTY(&stream->seg_tree)) {
return false;
}
TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
{
SCEnter();
- SCLogDebug("stream->seg_list %p", stream->seg_list);
- int r = 0;
if (StreamTcpReassembleAppLayer(tv, ra_ctx, ssn, stream, p, UPDATE_DIR_OPPOSING) < 0)
- r = -1;
+ SCReturnInt(-1);
- SCLogDebug("stream->seg_list %p", stream->seg_list);
- SCReturnInt(r);
+ SCReturnInt(0);
}
int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
segment request due to memcap limit */
StatsIncr(tv, ra_ctx->counter_tcp_segment_memcap);
} else {
- seg->next = NULL;
- seg->prev = NULL;
-
memset(&seg->sbseg, 0, sizeof(seg->sbseg));
}
memset(&tv, 0, sizeof (ThreadVars));
memset(&stt, 0, sizeof (stt));
memset(&tcph, 0, sizeof (TCPHdr));
- TcpSession *ssn = NULL;
FLOW_INITIALIZE(&f);
f.flags = FLOW_IPV4;
p->flow = &f;
p->tcph = &tcph;
- FLOWLOCK_WRLOCK(&f);
- int ret = 0;
-
StreamTcpUTInit(&stt.ra_ctx);
/* handshake */
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
-
- ssn = (TcpSession *)f.protoctx;
-
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_UNKNOWN ||
- f.alproto_ts != ALPROTO_UNKNOWN ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != 0) {
- printf("failure 1\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+
+ TcpSession *ssn = (TcpSession *)f.protoctx;
+ FAIL_IF_NULL(ssn);
+
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(!RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(ssn->data_first_seen_dir != 0);
/* handshake */
p->tcph->th_ack = htonl(1);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_UNKNOWN ||
- f.alproto_ts != ALPROTO_UNKNOWN ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != 0) {
- printf("failure 2\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(!RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(ssn->data_first_seen_dir != 0);
/* handshake */
p->tcph->th_ack = htonl(1);
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_UNKNOWN ||
- f.alproto_ts != ALPROTO_UNKNOWN ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != 0) {
- printf("failure 3\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(!RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(ssn->data_first_seen_dir != 0);
/* partial request */
uint8_t request1[] = { 0x47, 0x45, };
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request1);
p->payload = request1;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_UNKNOWN ||
- f.alproto_ts != ALPROTO_UNKNOWN ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != STREAM_TOSERVER) {
- printf("failure 4\n");
- goto end;
- }
-
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(!RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response ack against partial request */
p->tcph->th_ack = htonl(3);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_UNKNOWN ||
- f.alproto_ts != ALPROTO_UNKNOWN ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != STREAM_TOSERVER) {
- printf("failure 5\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(!RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* complete partial request */
uint8_t request2[] = {
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request2);
p->payload = request2;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_UNKNOWN ||
- f.alproto_ts != ALPROTO_UNKNOWN ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != STREAM_TOSERVER) {
- printf("failure 6\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_ts != ALPROTO_UNKNOWN);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(!RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(ssn->data_first_seen_dir != STREAM_TOSERVER);
/* response - request ack */
uint8_t response[] = {
p->payload_len = sizeof(response);
p->payload = response;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_UNKNOWN ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next != NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 7\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_UNKNOWN);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
/* response ack from request */
p->tcph->th_ack = htonl(328);
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next != NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 8\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/* response - acking */
p->tcph->th_ack = htonl(88);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 9\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/* response ack from request */
p->tcph->th_ack = htonl(328);
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 10\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/* response - acking the request again*/
p->tcph->th_ack = htonl(88);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 11\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/*** New Request ***/
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request1);
p->payload = request1;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 12\n");
- goto end;
- }
-
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(!TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/* response ack against partial request */
p->tcph->th_ack = htonl(90);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 13\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(!TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/* complete request */
p->tcph->th_ack = htonl(328);
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = sizeof(request2);
p->payload = request2;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list == NULL ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next == NULL ||
- ssn->client.seg_list->next->next->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 14\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(!TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(!TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)))));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
/* response ack against second partial request */
p->tcph->th_ack = htonl(175);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP ||
- ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list->next == NULL ||
- ssn->client.seg_list->next->next == NULL ||
- ssn->client.seg_list->next->next->next == NULL ||
- ssn->server.seg_list == NULL ||
- ssn->server.seg_list->next != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER) {
- printf("failure 15\n");
- goto end;
- }
+
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
+ FAIL_IF(ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED);
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PP_DONE(&f, STREAM_TOSERVER));
+ FAIL_IF(!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT));
+ FAIL_IF(ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER);
+ FAIL_IF(RB_EMPTY(&ssn->client.seg_tree));
+ FAIL_IF(!TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)));
+ FAIL_IF(!TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree))));
+ FAIL_IF(!TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->client.seg_tree)))));
+ FAIL_IF(RB_EMPTY(&ssn->server.seg_tree));
+ FAIL_IF(TCPSEG_RB_NEXT(RB_MIN(TCPSEG, &ssn->server.seg_tree)));
+
/* response acking a request */
p->tcph->th_ack = htonl(175);
p->tcph->th_seq = htonl(328);
p->flowflags = FLOW_PKT_TOCLIENT;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
-
- SCLogDebug("StreamTcpIsSetStreamFlagAppProtoDetectionCompleted %s, "
- "StreamTcpIsSetStreamFlagAppProtoDetectionCompleted %s, "
- "f.alproto %u f.alproto_ts %u f.alproto_tc %u",
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ? "true" : "false",
- StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ? "true" : "false",
- f.alproto, f.alproto_ts, f.alproto_tc);
-
- if (!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- !StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- f.alproto != ALPROTO_HTTP ||
- f.alproto_ts != ALPROTO_HTTP ||
- f.alproto_tc != ALPROTO_HTTP)// ||
- //ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED)// ||
- //!FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- //!FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- //ssn->client.seg_list != NULL ||
- //ssn->server.seg_list == NULL ||
- //ssn->server.seg_list->next != NULL ||
- //ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER)
- {
- printf("failure 15\n");
- goto end;
- }
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server));
+ FAIL_IF(!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client));
+ FAIL_IF(f.alproto != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_ts != ALPROTO_HTTP);
+ FAIL_IF(f.alproto_tc != ALPROTO_HTTP);
StreamTcpPruneSession(&f, STREAM_TOSERVER);
StreamTcpPruneSession(&f, STREAM_TOCLIENT);
p->flowflags = FLOW_PKT_TOSERVER;
p->payload_len = 0;
p->payload = NULL;
- if (StreamTcpPacket(&tv, p, &stt, &pq) == -1)
- goto end;
-#if 0
- if (//!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->server) ||
- //!StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(&ssn->client) ||
- //f.alproto != ALPROTO_HTTP ||
- //f.alproto_ts != ALPROTO_HTTP ||
- //f.alproto_tc != ALPROTO_HTTP ||
- //ssn->flags & STREAMTCP_FLAG_APP_LAYER_DISABLED ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOSERVER) || !FLOW_IS_PP_DONE(&f, STREAM_TOSERVER) ||
- !FLOW_IS_PM_DONE(&f, STREAM_TOCLIENT) || FLOW_IS_PP_DONE(&f, STREAM_TOCLIENT) ||
- ssn->client.seg_list != NULL ||
- ssn->server.seg_list != NULL ||
- ssn->data_first_seen_dir != APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
- ) {
- printf("failure 16\n");
- abort();
- goto end;
- }
-#endif
+ FAIL_IF(StreamTcpPacket(&tv, p, &stt, &pq) == -1);
- ret = 1;
-end:
StreamTcpSessionClear(ssn);
StreamTcpUTDeinit(stt.ra_ctx);
SCFree(p);
- FLOWLOCK_UNLOCK(&f);
- return ret;
+ PASS;
}
/**
}
/* check is have the segment in the list and flagged or not */
- if (ssn.client.seg_list == NULL ||
- SEGMENT_BEFORE_OFFSET(&ssn.client, ssn.client.seg_list, STREAM_APP_PROGRESS(&ssn.client)))
- {
- printf("the list is NULL or the processed segment has not been flaged (7): ");
- goto end;
- }
+ TcpSegment *seg = RB_MIN(TCPSEG, &ssn.client.seg_tree);
+ FAIL_IF_NULL(seg);
+ FAIL_IF(SEGMENT_BEFORE_OFFSET(&ssn.client, seg, STREAM_APP_PROGRESS(&ssn.client)));
p->flowflags = FLOW_PKT_TOSERVER;
p->payload = httpbuf4;
p->tcph->th_seq = htonl(17);
StreamTcpPruneSession(&f, STREAM_TOSERVER);
- FAIL_IF (ssn.client.seg_list->seq != 2);
+ TcpSegment *seg = RB_MIN(TCPSEG, &ssn.client.seg_tree);
+ FAIL_IF_NULL(seg);
+ FAIL_IF_NOT(seg->seq == 2);
FLOW_DESTROY(&f);
UTHFreePacket(p);
p->tcph->th_seq = htonl(12);
- if (ssn.client.seg_list->seq != 2) {
- printf("expected segment 1 (seq 2) to be first in the list, got seq %"PRIu32": ", ssn.client.seg_list->seq);
- goto end;
- }
+ TcpSegment *seg = RB_MIN(TCPSEG, &ssn.client.seg_tree);
+ FAIL_IF_NULL(seg);
+ FAIL_IF_NOT(seg->seq == 2);
ret = 1;
end: