|
|
|
|
@ -223,13 +223,16 @@ static void *ReassembleCalloc(size_t n, size_t size)
|
|
|
|
|
void *StreamTcpReassembleRealloc(void *optr, size_t orig_size, size_t size)
|
|
|
|
|
{
|
|
|
|
|
if (size > orig_size) {
|
|
|
|
|
if (StreamTcpReassembleCheckMemcap(size - orig_size) == 0)
|
|
|
|
|
if (StreamTcpReassembleCheckMemcap(size - orig_size) == 0) {
|
|
|
|
|
SCLogDebug("memcap hit at %" PRIu64, SC_ATOMIC_GET(stream_config.reassembly_memcap));
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void *nptr = SCRealloc(optr, size);
|
|
|
|
|
if (nptr == NULL)
|
|
|
|
|
if (nptr == NULL) {
|
|
|
|
|
SCLogDebug("realloc fail");
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (size > orig_size) {
|
|
|
|
|
StreamTcpReassembleIncrMemuse(size - orig_size);
|
|
|
|
|
} else {
|
|
|
|
|
@ -250,6 +253,7 @@ static void ReassembleFree(void *ptr, size_t size)
|
|
|
|
|
/** \brief alloc a tcp segment pool entry */
|
|
|
|
|
static void *TcpSegmentPoolAlloc(void)
|
|
|
|
|
{
|
|
|
|
|
SCLogDebug("segment alloc");
|
|
|
|
|
if (StreamTcpReassembleCheckMemcap((uint32_t)sizeof(TcpSegment)) == 0) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
@ -1048,6 +1052,7 @@ static bool GetAppBuffer(const TcpStream *stream, const uint8_t **data, uint32_t
|
|
|
|
|
*data = mydata;
|
|
|
|
|
*data_len = mydata_len;
|
|
|
|
|
} else {
|
|
|
|
|
SCLogDebug("block mode");
|
|
|
|
|
StreamingBufferBlock *blk = GetBlock(&stream->sb, offset);
|
|
|
|
|
if (blk == NULL) {
|
|
|
|
|
*data = NULL;
|
|
|
|
|
@ -1058,6 +1063,7 @@ static bool GetAppBuffer(const TcpStream *stream, const uint8_t **data, uint32_t
|
|
|
|
|
|
|
|
|
|
/* block at expected offset */
|
|
|
|
|
if (blk->offset == offset) {
|
|
|
|
|
SCLogDebug("blk at offset");
|
|
|
|
|
|
|
|
|
|
StreamingBufferSBBGetData(&stream->sb, blk, data, data_len);
|
|
|
|
|
|
|
|
|
|
@ -1184,8 +1190,11 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
|
|
|
|
|
uint64_t app_progress = STREAM_APP_PROGRESS(*stream);
|
|
|
|
|
|
|
|
|
|
SCLogDebug("app progress %"PRIu64, app_progress);
|
|
|
|
|
SCLogDebug("last_ack %u, base_seq %u", (*stream)->last_ack, (*stream)->base_seq);
|
|
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
uint64_t last_ack_abs = GetAbsLastAck(*stream);
|
|
|
|
|
SCLogDebug("last_ack %u (abs %" PRIu64 "), base_seq %u", (*stream)->last_ack, last_ack_abs,
|
|
|
|
|
(*stream)->base_seq);
|
|
|
|
|
#endif
|
|
|
|
|
const uint8_t *mydata;
|
|
|
|
|
uint32_t mydata_len;
|
|
|
|
|
bool last_was_gap = false;
|
|
|
|
|
@ -1195,6 +1204,7 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
|
|
|
|
|
bool check_for_gap_ahead = ((*stream)->data_required > 0);
|
|
|
|
|
bool gap_ahead =
|
|
|
|
|
GetAppBuffer(*stream, &mydata, &mydata_len, app_progress, check_for_gap_ahead);
|
|
|
|
|
SCLogDebug("gap_ahead %s mydata_len %u", BOOL2STR(gap_ahead), mydata_len);
|
|
|
|
|
if (last_was_gap && mydata_len == 0) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
@ -1237,11 +1247,13 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
} else if (flags & STREAM_DEPTH) {
|
|
|
|
|
SCLogDebug("DEPTH");
|
|
|
|
|
// we're just called once with this flag, so make sure we pass it on
|
|
|
|
|
if (mydata == NULL && mydata_len > 0) {
|
|
|
|
|
mydata_len = 0;
|
|
|
|
|
}
|
|
|
|
|
} else if (mydata == NULL || (mydata_len == 0 && ((flags & STREAM_EOF) == 0))) {
|
|
|
|
|
SCLogDebug("GAP?1");
|
|
|
|
|
/* Possibly a gap, but no new data. */
|
|
|
|
|
if ((p->flags & PKT_PSEUDO_STREAM_END) == 0 || ssn->state < TCP_CLOSED)
|
|
|
|
|
SCReturnInt(0);
|
|
|
|
|
@ -1257,7 +1269,9 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
|
|
|
|
|
*stream, &(*stream)->sb, mydata_len, app_progress);
|
|
|
|
|
|
|
|
|
|
if ((p->flags & PKT_PSEUDO_STREAM_END) == 0 || ssn->state < TCP_CLOSED) {
|
|
|
|
|
SCLogDebug("GAP?2");
|
|
|
|
|
if (mydata_len < (*stream)->data_required) {
|
|
|
|
|
SCLogDebug("GAP?3 gap_head %s", BOOL2STR(gap_ahead));
|
|
|
|
|
if (gap_ahead) {
|
|
|
|
|
SCLogDebug("GAP while expecting more data (expect %u, gap size %u)",
|
|
|
|
|
(*stream)->data_required, mydata_len);
|
|
|
|
|
@ -1274,6 +1288,7 @@ static int ReassembleUpdateAppLayer (ThreadVars *tv,
|
|
|
|
|
}
|
|
|
|
|
(*stream)->data_required = 0;
|
|
|
|
|
|
|
|
|
|
SCLogDebug("parser");
|
|
|
|
|
/* update the app-layer */
|
|
|
|
|
(void)AppLayerHandleTCPData(tv, ra_ctx, p, p->flow, ssn, stream,
|
|
|
|
|
(uint8_t *)mydata, mydata_len, flags);
|
|
|
|
|
|