stream: per TcpStream reassembly depth

pull/2319/head
Eric Leblond 10 years ago committed by Victor Julien
parent 960ebb2822
commit a63c6b320e

@ -222,6 +222,7 @@ typedef struct TcpSession_ {
uint8_t tcp_packet_flags; uint8_t tcp_packet_flags;
/* coccinelle: TcpSession:flags:STREAMTCP_FLAG */ /* coccinelle: TcpSession:flags:STREAMTCP_FLAG */
uint16_t flags; uint16_t flags;
uint32_t reassembly_depth; /**< reassembly depth for the stream */
TcpStream server; TcpStream server;
TcpStream client; TcpStream client;
struct StreamMsg_ *toserver_smsg_head; /**< list of stream msgs (for detection inspection) */ struct StreamMsg_ *toserver_smsg_head; /**< list of stream msgs (for detection inspection) */

@ -1770,14 +1770,14 @@ int StreamTcpReassembleDepthReached(Packet *p)
* *
* \retval size Part of the size that fits in the depth, 0 if none * \retval size Part of the size that fits in the depth, 0 if none
*/ */
static uint32_t StreamTcpReassembleCheckDepth(TcpStream *stream, static uint32_t StreamTcpReassembleCheckDepth(TcpSession *ssn, TcpStream *stream,
uint32_t seq, uint32_t size) uint32_t seq, uint32_t size)
{ {
SCEnter(); SCEnter();
/* if the configured depth value is 0, it means there is no limit on /* if the configured depth value is 0, it means there is no limit on
reassembly depth. Otherwise carry on my boy ;) */ reassembly depth. Otherwise carry on my boy ;) */
if (stream_config.reassembly_depth == 0) { if (ssn->reassembly_depth == 0) {
SCReturnUInt(size); SCReturnUInt(size);
} }
@ -1790,25 +1790,25 @@ static uint32_t StreamTcpReassembleCheckDepth(TcpStream *stream,
* checking and just reject the rest of the packets including * checking and just reject the rest of the packets including
* retransmissions. Saves us the hassle of dealing with sequence * retransmissions. Saves us the hassle of dealing with sequence
* wraps as well */ * wraps as well */
if (SEQ_GEQ((StreamTcpReassembleGetRaBaseSeq(stream)+1),(stream->isn + stream_config.reassembly_depth))) { if (SEQ_GEQ((StreamTcpReassembleGetRaBaseSeq(stream)+1),(stream->isn + ssn->reassembly_depth))) {
stream->flags |= STREAMTCP_STREAM_FLAG_DEPTH_REACHED; stream->flags |= STREAMTCP_STREAM_FLAG_DEPTH_REACHED;
SCReturnUInt(0); SCReturnUInt(0);
} }
SCLogDebug("full Depth not yet reached: %"PRIu32" <= %"PRIu32, SCLogDebug("full Depth not yet reached: %"PRIu32" <= %"PRIu32,
(StreamTcpReassembleGetRaBaseSeq(stream)+1), (StreamTcpReassembleGetRaBaseSeq(stream)+1),
(stream->isn + stream_config.reassembly_depth)); (stream->isn + ssn->reassembly_depth));
if (SEQ_GEQ(seq, stream->isn) && SEQ_LT(seq, (stream->isn + stream_config.reassembly_depth))) { if (SEQ_GEQ(seq, stream->isn) && SEQ_LT(seq, (stream->isn + ssn->reassembly_depth))) {
/* packet (partly?) fits the depth window */ /* packet (partly?) fits the depth window */
if (SEQ_LEQ((seq + size),(stream->isn + stream_config.reassembly_depth))) { if (SEQ_LEQ((seq + size),(stream->isn + ssn->reassembly_depth))) {
/* complete fit */ /* complete fit */
SCReturnUInt(size); SCReturnUInt(size);
} else { } else {
stream->flags |= STREAMTCP_STREAM_FLAG_DEPTH_REACHED; stream->flags |= STREAMTCP_STREAM_FLAG_DEPTH_REACHED;
/* partial fit, return only what fits */ /* partial fit, return only what fits */
uint32_t part = (stream->isn + stream_config.reassembly_depth) - seq; uint32_t part = (stream->isn + ssn->reassembly_depth) - seq;
#if DEBUG #if DEBUG
BUG_ON(part > size); BUG_ON(part > size);
#else #else
@ -1903,7 +1903,7 @@ int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThre
/* If we have reached the defined depth for either of the stream, then stop /* If we have reached the defined depth for either of the stream, then stop
reassembling the TCP session */ reassembling the TCP session */
uint32_t size = StreamTcpReassembleCheckDepth(stream, TCP_GET_SEQ(p), p->payload_len); uint32_t size = StreamTcpReassembleCheckDepth(ssn, stream, TCP_GET_SEQ(p), p->payload_len);
SCLogDebug("ssn %p: check depth returned %"PRIu32, ssn, size); SCLogDebug("ssn %p: check depth returned %"PRIu32, ssn, size);
if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) { if (stream->flags & STREAMTCP_STREAM_FLAG_DEPTH_REACHED) {
@ -7286,7 +7286,7 @@ static int StreamTcpReassembleTest45 (void)
ssn.state = TCP_ESTABLISHED; ssn.state = TCP_ESTABLISHED;
/* set the default value of reassembly depth, as there is no config file */ /* set the default value of reassembly depth, as there is no config file */
stream_config.reassembly_depth = httplen1 + 1; ssn.reassembly_depth = httplen1 + 1;
TcpStream *s = NULL; TcpStream *s = NULL;
s = &ssn.server; s = &ssn.server;

@ -647,6 +647,7 @@ TcpSession *StreamTcpNewSession (Packet *p, int id)
} }
ssn->state = TCP_NONE; ssn->state = TCP_NONE;
ssn->reassembly_depth = stream_config.reassembly_depth;
ssn->flags = stream_config.ssn_init_flags; ssn->flags = stream_config.ssn_init_flags;
ssn->tcp_packet_flags = p->tcph ? p->tcph->th_flags : 0; ssn->tcp_packet_flags = p->tcph ? p->tcph->th_flags : 0;
@ -5799,6 +5800,15 @@ int StreamTcpBypassEnabled(void)
return stream_config.bypass; return stream_config.bypass;
} }
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size)
{
if (size > ssn->reassembly_depth || size == 0) {
ssn->reassembly_depth = size;
}
return;
}
#ifdef UNITTESTS #ifdef UNITTESTS
/** /**

@ -123,6 +123,7 @@ int StreamTcpSegmentForEach(const Packet *p, uint8_t flag,
StreamSegmentCallback CallbackFunc, StreamSegmentCallback CallbackFunc,
void *data); void *data);
void StreamTcpReassembleConfigEnableOverlapCheck(void); void StreamTcpReassembleConfigEnableOverlapCheck(void);
void TcpSessionSetReassemblyDepth(TcpSession *ssn, uint32_t size);
/** ------- Inline functions: ------ */ /** ------- Inline functions: ------ */

Loading…
Cancel
Save