#ifdef DEBUG
static void StreamTcpSackPrintList(TcpStream *stream)
{
+ SCLogDebug("size %u", stream->sack_size);
StreamTcpSackRecord *rec = NULL;
RB_FOREACH(rec, TCPSACK, &stream->sack_tree) {
- SCLogDebug("record %8u - %8u", rec->le, rec->re);
+ SCLogDebug("- record %8u - %8u", rec->le, rec->re);
}
}
#endif /* DEBUG */
StreamTcpDecrMemuse((uint64_t)sizeof(*rec));
}
-static inline void ConsolidateFwd(struct TCPSACK *tree, struct StreamTcpSackRecord *sa)
+static inline void ConsolidateFwd(TcpStream *stream, struct TCPSACK *tree, struct StreamTcpSackRecord *sa)
{
struct StreamTcpSackRecord *tr, *s = sa;
RB_FOREACH_FROM(tr, TCPSACK, s) {
break; // entirely before
if (SEQ_GEQ(sa->le, tr->le) && SEQ_LEQ(sa->re, tr->re)) {
+ stream->sack_size -= (tr->re - tr->le);
+ stream->sack_size -= (sa->re - sa->le);
sa->re = tr->re;
sa->le = tr->le;
+ stream->sack_size += (sa->re - sa->le);
SCLogDebug("-> (fwd) tr %p %u/%u REMOVED ECLIPSED2", tr, tr->le, tr->re);
TCPSACK_RB_REMOVE(tree, tr);
StreamTcpSackRecordFree(tr);
*/
} else if (SEQ_LEQ(sa->le, tr->le) && SEQ_GEQ(sa->re, tr->re)) {
SCLogDebug("-> (fwd) tr %p %u/%u REMOVED ECLIPSED", tr, tr->le, tr->re);
+ stream->sack_size -= (tr->re - tr->le);
TCPSACK_RB_REMOVE(tree, tr);
StreamTcpSackRecordFree(tr);
/*
SEQ_GEQ(sa->re, tr->le) && SEQ_LT(sa->re, tr->re) // ends inside
) {
// merge
+ stream->sack_size -= (tr->re - tr->le);
+ stream->sack_size -= (sa->re - sa->le);
sa->re = tr->re;
+ stream->sack_size += (sa->re - sa->le);
SCLogDebug("-> (fwd) tr %p %u/%u REMOVED MERGED", tr, tr->le, tr->re);
TCPSACK_RB_REMOVE(tree, tr);
StreamTcpSackRecordFree(tr);
}
}
-static inline void ConsolidateBackward(struct TCPSACK *tree, struct StreamTcpSackRecord *sa)
+static inline void ConsolidateBackward(TcpStream *stream,
+ struct TCPSACK *tree, struct StreamTcpSackRecord *sa)
{
struct StreamTcpSackRecord *tr, *s = sa;
RB_FOREACH_REVERSE_FROM(tr, TCPSACK, s) {
if (SEQ_GT(sa->le, tr->re))
break; // entirely after
if (SEQ_GEQ(sa->le, tr->le) && SEQ_LEQ(sa->re, tr->re)) {
+ stream->sack_size -= (tr->re - tr->le);
+ stream->sack_size -= (sa->re - sa->le);
sa->re = tr->re;
sa->le = tr->le;
+ stream->sack_size += (sa->re - sa->le);
SCLogDebug("-> (bwd) tr %p %u/%u REMOVED ECLIPSED2", tr, tr->le, tr->re);
TCPSACK_RB_REMOVE(tree, tr);
StreamTcpSackRecordFree(tr);
*/
} else if (SEQ_LEQ(sa->le, tr->le) && SEQ_GEQ(sa->re, tr->re)) {
SCLogDebug("-> (bwd) tr %p %u/%u REMOVED ECLIPSED", tr, tr->le, tr->re);
+ stream->sack_size -= (tr->re - tr->le);
TCPSACK_RB_REMOVE(tree, tr);
StreamTcpSackRecordFree(tr);
/*
*/
} else if (SEQ_GT(sa->le, tr->le) && SEQ_GT(sa->re, tr->re) && SEQ_LEQ(sa->le,tr->re)) {
// merge
+ stream->sack_size -= (tr->re - tr->le);
+ stream->sack_size -= (sa->re - sa->le);
sa->le = tr->le;
+ stream->sack_size += (sa->re - sa->le);
SCLogDebug("-> (bwd) tr %p %u/%u REMOVED MERGED", tr, tr->le, tr->re);
TCPSACK_RB_REMOVE(tree, tr);
StreamTcpSackRecordFree(tr);
}
}
-static int Insert(struct TCPSACK *tree, uint32_t le, uint32_t re)
+static int Insert(TcpStream *stream, struct TCPSACK *tree, uint32_t le, uint32_t re)
{
SCLogDebug("* inserting: %u/%u\n", le, re);
StreamTcpSackRecordFree(sa);
return 0;
}
- ConsolidateBackward(tree, sa);
- ConsolidateFwd(tree, sa);
+ stream->sack_size += (re - le);
+ ConsolidateBackward(stream, tree, sa);
+ ConsolidateFwd(stream, tree, sa);
return 0;
}
SCReturnInt(0);
}
- if (Insert(&stream->sack_tree, le, re) < 0)
+ if (Insert(stream, &stream->sack_tree, le, re) < 0)
SCReturnInt(-1);
SCReturnInt(0);
RB_FOREACH_SAFE(rec, TCPSACK, &stream->sack_tree, safe) {
if (SEQ_LT(rec->re, stream->last_ack)) {
SCLogDebug("removing le %u re %u", rec->le, rec->re);
+ stream->sack_size -= (rec->re - rec->le);
TCPSACK_RB_REMOVE(&stream->sack_tree, rec);
StreamTcpSackRecordFree(rec);
} else if (SEQ_LT(rec->le, stream->last_ack)) {
SCLogDebug("adjusting record to le %u re %u", rec->le, rec->re);
/* last ack inside this record, update */
+ stream->sack_size -= (rec->re - rec->le);
rec->le = stream->last_ack;
+ stream->sack_size += (rec->re - rec->le);
break;
} else {
SCLogDebug("record beyond last_ack, nothing to do. Bailing out.");
StreamTcpSackRecord *rec = NULL, *safe = NULL;
RB_FOREACH_SAFE(rec, TCPSACK, &stream->sack_tree, safe) {
+ stream->sack_size -= (rec->re - rec->le);
TCPSACK_RB_REMOVE(&stream->sack_tree, rec);
StreamTcpSackRecordFree(rec);
}
stream.window = 100;
StreamTcpSackInsertRange(&stream, 1, 10);
+ FAIL_IF_NOT(stream.sack_size == 9);
StreamTcpSackInsertRange(&stream, 10, 20);
+ FAIL_IF_NOT(stream.sack_size == 19);
StreamTcpSackInsertRange(&stream, 10, 20);
+ FAIL_IF_NOT(stream.sack_size == 19);
StreamTcpSackInsertRange(&stream, 1, 20);
+ FAIL_IF_NOT(stream.sack_size == 19);
#ifdef DEBUG
StreamTcpSackPrintList(&stream);
#endif /* DEBUG */