stream: implement raw reassembly stop api

Implement StreamTcpSetDisableRawReassemblyFlag() which stops raw
reassembly for _NEW_ segments in a stream direction.

It is used only by TLS/SSL now, to flag the streams as encrypted.
Existing segments will still be reassembled and inspected, while
new segments won't be. This allows for pattern based inspection
of the TLS handshake.

Like is the case with completely disabled 'raw' reassembly, the
logic is that the segments are flagged as completed for 'raw' right
away. So they are not considered in raw reassembly anymore.

As no new segments will be considered, the chunk limit check will
return true on the next call.
pull/961/head
Victor Julien 12 years ago
parent b2184f936e
commit 3543150f42

@ -850,9 +850,18 @@ int AppLayerParserParse(AppLayerParserThreadCtx *alp_tctx, Flow *f, AppProto alp
}
/* In cases like HeartBleed for TLS we need to inspect AppLayer but not Payload */
if (pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) {
if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION) && pstate->flags & APP_LAYER_PARSER_NO_INSPECTION_PAYLOAD) {
FlowSetNoPayloadInspectionFlag(f);
AppLayerParserTriggerRawStreamReassembly(f);
/* Set the no reassembly flag for both the stream in this TcpSession */
if (f->proto == IPPROTO_TCP) {
/* Used only if it's TCP */
TcpSession *ssn = f->protoctx;
if (ssn != NULL) {
StreamTcpSetDisableRawReassemblyFlag(ssn, 0);
StreamTcpSetDisableRawReassemblyFlag(ssn, 1);
AppLayerParserTriggerRawStreamReassembly(f);
}
}
}
/* next, see if we can get rid of transactions now */

@ -165,6 +165,8 @@ enum
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED 0x0080
/** App proto detection skipped */
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED 0x0100
/** Raw reassembly disabled for new segments */
#define STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED 0x0200
/*
* Per SEGMENT flags

@ -1882,6 +1882,14 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre
seg->payload_len = size;
seg->seq = TCP_GET_SEQ(p);
/* if raw reassembly is disabled for new segments, flag each
* segment as complete for raw before insert */
if (stream->flags & STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED) {
seg->flags |= SEGMENTTCP_FLAG_RAW_PROCESSED;
SCLogDebug("segment %p flagged with SEGMENTTCP_FLAG_RAW_PROCESSED, "
"flags %02x", seg, seg->flags);
}
/* proto detection skipped, but now we do get data. Set event. */
if (stream->seg_list == NULL &&
stream->flags & STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED) {
@ -1965,6 +1973,12 @@ static int StreamTcpReassembleRawCheckLimit(TcpSession *ssn, TcpStream *stream,
SCReturnInt(1);
}
if (stream->flags & STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED) {
SCLogDebug("reassembling now as STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED is set, "
"so no new segments will be considered");
SCReturnInt(1);
}
/* some states mean we reassemble no matter how much data we have */
if (ssn->state >= TCP_TIME_WAIT)
SCReturnInt(1);
@ -2725,10 +2739,8 @@ static inline int StreamTcpReturnSegmentCheck(const Flow *f, TcpSession *ssn, Tc
}
/* check raw reassembly conditions */
if (!(f->flags & FLOW_NOPAYLOAD_INSPECTION)) {
if (!(seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED)) {
SCReturnInt(0);
}
if (!(seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED)) {
SCReturnInt(0);
}
SCReturnInt(1);
@ -2935,6 +2947,10 @@ int StreamTcpReassembleAppLayer (ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx,
StreamTcpSegmentReturntoPool(seg);
seg = next_seg;
continue;
} else if (StreamTcpAppLayerSegmentProcessed(stream, seg)) {
TcpSegment *next_seg = seg->next;
seg = next_seg;
continue;
}
/* we've run into a sequence gap */
@ -3235,11 +3251,6 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
seg, seg->seq, seg->payload_len,
(uint32_t)(seg->seq + seg->payload_len), seg->flags);
if (p->flow->flags & FLOW_NOPAYLOAD_INSPECTION) {
SCLogDebug("FLOW_NOPAYLOAD_INSPECTION set, breaking out");
break;
}
if (StreamTcpReturnSegmentCheck(p->flow, ssn, stream, seg) == 1) {
SCLogDebug("removing segment");
TcpSegment *next_seg = seg->next;
@ -3247,6 +3258,10 @@ static int StreamTcpReassembleRaw (TcpReassemblyThreadCtx *ra_ctx,
StreamTcpSegmentReturntoPool(seg);
seg = next_seg;
continue;
} else if(seg->flags & SEGMENTTCP_FLAG_RAW_PROCESSED) {
TcpSegment *next_seg = seg->next;
seg = next_seg;
continue;
}
/* we've run into a sequence gap */

@ -87,6 +87,7 @@ int StreamTcpReassembleInlineAppLayer(ThreadVars *tv,
void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t);
void StreamTcpSetSessionNoReassemblyFlag (TcpSession *, char );
void StreamTcpSetDisableRawReassemblyFlag (TcpSession *ssn, char direction);
void StreamTcpSetOSPolicy(TcpStream *, Packet *);
void StreamTcpReassemblePause (TcpSession *, char );

@ -5223,6 +5223,18 @@ void StreamTcpSetSessionNoReassemblyFlag (TcpSession *ssn, char direction)
(ssn->client.flags |= STREAMTCP_STREAM_FLAG_NOREASSEMBLY);
}
/** \brief Set the No reassembly flag for the given direction in given TCP
* session.
*
* \param ssn TCP Session to set the flag in
* \param direction direction to set the flag in: 0 toserver, 1 toclient
*/
void StreamTcpSetDisableRawReassemblyFlag (TcpSession *ssn, char direction)
{
direction ? (ssn->server.flags |= STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED) :
(ssn->client.flags |= STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED);
}
#define PSEUDO_PKT_SET_IPV4HDR(nipv4h,ipv4h) do { \
IPV4_SET_RAW_VER(nipv4h, IPV4_GET_RAW_VER(ipv4h)); \
IPV4_SET_RAW_HLEN(nipv4h, IPV4_GET_RAW_HLEN(ipv4h)); \

Loading…
Cancel
Save