stream: fix raw reassembly flag issue

AppLayer reassembly correctly only flags a segment as done when it's
completely used in reassembly. Raw reassembly could flag a partially
used segment as complete as well. In this case the segment could be
discarded early. Further reassembly would miss data, leading to a
gap. Due to this, up to 'window size' bytes worth of segments could
remain in the session for a long time, leading to memory resource
pressure.

This patch sets the flag correctly.
pull/945/head
Victor Julien 12 years ago
parent 539bf57a65
commit 5db228b9f6

@ -3221,8 +3221,10 @@ int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
TcpSegment *next_seg = seg->next; TcpSegment *next_seg = seg->next;
next_seq = seg->seq + seg->payload_len; next_seq = seg->seq + seg->payload_len;
if (partial == FALSE) { if (partial == FALSE) {
SCLogDebug("fully done with segment in app layer reassembly"); SCLogDebug("fully done with segment in app layer reassembly (seg %p seq %"PRIu32")",
seg, seg->seq);
seg->flags |= SEGMENTTCP_FLAG_APPLAYER_PROCESSED; seg->flags |= SEGMENTTCP_FLAG_APPLAYER_PROCESSED;
SCLogDebug("flags now %02x", seg->flags);
} else { } else {
SCLogDebug("not yet fully done with segment in app layer reassembly"); SCLogDebug("not yet fully done with segment in app layer reassembly");
} }
@ -3300,9 +3302,9 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
/* loop through the segments and fill one or more msgs */ /* loop through the segments and fill one or more msgs */
for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);) for (; seg != NULL && SEQ_LT(seg->seq, stream->last_ack);)
{ {
SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32, SCLogDebug("seg %p, SEQ %"PRIu32", LEN %"PRIu16", SUM %"PRIu32", flags %02x",
seg, seg->seq, seg->payload_len, seg, seg->seq, seg->payload_len,
(uint32_t)(seg->seq + seg->payload_len)); (uint32_t)(seg->seq + seg->payload_len), seg->flags);
if ((p->flow->flags & FLOW_NO_APPLAYER_INSPECTION) || if ((p->flow->flags & FLOW_NO_APPLAYER_INSPECTION) ||
(stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) || (stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED) ||
@ -3405,6 +3407,8 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
} }
} }
int partial = FALSE;
/* if the segment ends beyond ra_base_seq we need to consider it */ /* if the segment ends beyond ra_base_seq we need to consider it */
if (SEQ_GT((seg->seq + seg->payload_len), ra_base_seq+1)) { if (SEQ_GT((seg->seq + seg->payload_len), ra_base_seq+1)) {
SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", " SCLogDebug("seg->seq %" PRIu32 ", seg->payload_len %" PRIu32 ", "
@ -3422,6 +3426,7 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
} else { } else {
payload_len = (stream->last_ack - seg->seq) - payload_offset; payload_len = (stream->last_ack - seg->seq) - payload_offset;
} }
partial = TRUE;
} else { } else {
payload_len = seg->payload_len - payload_offset; payload_len = seg->payload_len - payload_offset;
} }
@ -3435,6 +3440,7 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) { if (SEQ_LT(stream->last_ack, (seg->seq + seg->payload_len))) {
payload_len = stream->last_ack - seg->seq; payload_len = stream->last_ack - seg->seq;
partial = TRUE;
} else { } else {
payload_len = seg->payload_len; payload_len = seg->payload_len;
} }
@ -3564,8 +3570,15 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
/* done with this segment, return it to the pool */ /* done with this segment, return it to the pool */
TcpSegment *next_seg = seg->next; TcpSegment *next_seg = seg->next;
seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED;
next_seq = seg->seq + seg->payload_len; next_seq = seg->seq + seg->payload_len;
if (partial == FALSE) {
SCLogDebug("fully done with segment in raw reassembly (seg %p seq %"PRIu32")",
seg, seg->seq);
seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED;
SCLogDebug("flags now %02x", seg->flags);
} else {
SCLogDebug("not yet fully done with segment in raw reassembly");
}
seg = next_seg; seg = next_seg;
} }

Loading…
Cancel
Save