75static SCMutex segment_pool_memuse_mutex;
76static uint64_t segment_pool_memuse = 0;
77static uint64_t segment_pool_memcnt = 0;
89static int g_tcp_session_dump_enabled = 0;
93 return g_tcp_session_dump_enabled == 1;
98 g_tcp_session_dump_enabled = 1;
116static void StreamTcpReassembleIncrMemuse(uint64_t size)
129static void StreamTcpReassembleDecrMemuse(uint64_t size)
134 BUG_ON(presize > UINT_MAX);
143 BUG_ON(postsize > presize);
167 if (
unlikely((g_eps_stream_reassembly_memcap != UINT64_MAX &&
168 g_eps_stream_reassembly_memcap ==
t_pcapcnt))) {
174 if (memcapcopy == 0 ||
175 (uint64_t)((uint64_t)size +
SC_ATOMIC_GET(ra_memuse)) <= memcapcopy)
187 if (size == 0 || (uint64_t)
SC_ATOMIC_GET(ra_memuse) < size) {
211static void *ReassembleCalloc(
size_t n,
size_t size)
222 StreamTcpReassembleIncrMemuse(n * size);
231 if (size > orig_size) {
244 if (size > orig_size) {
245 StreamTcpReassembleIncrMemuse(size - orig_size);
247 StreamTcpReassembleDecrMemuse(orig_size - size);
255static void ReassembleFree(
void *ptr,
size_t size)
258 StreamTcpReassembleDecrMemuse(size);
262static void *TcpSegmentPoolAlloc(
void)
286 "TcpSegmentPcapHdrStorage");
295 "packet header data within "
296 "TcpSegmentPcapHdrStorage");
303 StreamTcpReassembleIncrMemuse(memuse);
311static int TcpSegmentPoolInit(
void *data,
void *initdata)
329 StreamTcpReassembleIncrMemuse(memuse);
339 segment_pool_memcnt++;
340 SCLogDebug(
"segment_pool_memcnt %"PRIu64
"", segment_pool_memcnt);
344 StreamTcpReassembleIncrMemuse((uint32_t)
sizeof(
TcpSegment));
349static void TcpSegmentPoolCleanup(
void *ptr)
365 StreamTcpReassembleDecrMemuse((uint32_t)
sizeof(
TcpSegment));
370 segment_pool_memcnt--;
371 SCLogDebug(
"segment_pool_memcnt %"PRIu64
"", segment_pool_memcnt);
408static inline uint64_t GetAbsLastAck(
const TcpStream *stream)
410 if (STREAM_LASTACK_GT_BASESEQ(stream)) {
421 right_edge =
MIN(GetAbsLastAck(stream), right_edge);
428 uint64_t right_edge = StreamingBufferGetConsecutiveDataRightEdge(&stream->
sb);
430 right_edge =
MIN(GetAbsLastAck(stream), right_edge);
472static int StreamTcpReassemblyConfig(
bool quiet)
474 uint32_t segment_prealloc = 2048;
477 uint32_t prealloc = 0;
484 segment_prealloc = prealloc;
487 SCLogConfig(
"stream.reassembly \"segment-prealloc\": %u", segment_prealloc);
490 int overlap_diff_data = 0;
491 (void)
SCConfGetBool(
"stream.reassembly.check-overlap-different-data", &overlap_diff_data);
492 if (overlap_diff_data) {
499 uint16_t max_regions = 8;
510 SCLogConfig(
"stream.reassembly \"max-regions\": %u", max_regions);
528 if (StreamTcpReassemblyConfig(quiet) < 0)
550 if (segment_pool_memuse > 0)
551 SCLogDebug(
"segment_pool_memuse %" PRIu64
" segment_pool_memcnt %" PRIu64
"",
552 segment_pool_memuse, segment_pool_memcnt);
573 TcpSegmentPoolInit, NULL,
574 TcpSegmentPoolCleanup, NULL);
576 SCLogDebug(
"pool size %d, thread segment_thread_pool_id %d",
582 SCLogDebug(
"pool size %d, thread segment_thread_pool_id %d",
588 SCLogError(
"failed to setup/expand stream segment pool. Expand stream.reassembly.memcap?");
608static void StreamTcpReassembleExceptionPolicyStatsIncr(
654 uint32_t
seq, uint32_t size)
672 SCLogDebug(
"segment entirely before base_seq, weird: base %u, seq %u, re %u",
686 SCLogDebug(
"seq + size %u, base %u, seg_depth %"PRIu64
" limit %u", (
seq + size),
691 SCLogDebug(
"STREAMTCP_STREAM_FLAG_DEPTH_REACHED");
695 SCLogDebug(
"NOT STREAMTCP_STREAM_FLAG_DEPTH_REACHED");
698 SCLogDebug(
"full depth not yet reached: %"PRIu64
" <= %"PRIu32,
699 (stream->base_seq_offset + stream->
base_seq + size),
766 SCLogDebug(
"ssn %p: both app and raw reassembly disabled, not reassembling", ssn);
770 uint16_t *urg_offset;
777 const TCPHdr *tcph = PacketGetTCP(p);
781 uint8_t urg_data = 0;
791 if ((*urg_offset) < UINT16_MAX) {
795 if ((*urg_offset) == UINT16_MAX) {
812 (*urg_offset) == UINT16_MAX &&
828 uint32_t size = StreamTcpReassembleCheckDepth(ssn, stream, seg_seq,
payload_len);
829 SCLogDebug(
"ssn %p: check depth returned %"PRIu32, ssn, size);
838 SCLogDebug(
"ssn %p: depth reached, not reassembling", ssn);
876 SCLogDebug(
"StreamTcpReassembleInsertSegment failed");
888 flag |= STREAM_START;
896 flag |= STREAM_MIDSTREAM;
903 if (&ssn->
client == stream) {
904 flag |= STREAM_TOSERVER;
906 flag |= STREAM_TOCLIENT;
909 flag |= STREAM_DEPTH;
920static bool StreamTcpReassembleRawCheckLimit(
926#define STREAMTCP_STREAM_FLAG_FLUSH_FLAGS \
927 ( STREAMTCP_STREAM_FLAG_DEPTH_REACHED \
928 | STREAMTCP_STREAM_FLAG_TRIGGER_RAW \
929 | STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED)
933 SCLogDebug(
"reassembling now as STREAMTCP_STREAM_FLAG_DEPTH_REACHED "
934 "is set, so not expecting any new data segments");
937 SCLogDebug(
"reassembling now as STREAMTCP_STREAM_FLAG_TRIGGER_RAW is set");
940 SCLogDebug(
"reassembling now as STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED is set, "
941 "so no new segments will be considered");
945#undef STREAMTCP_STREAM_FLAG_FLUSH_FLAGS
954 const uint64_t last_ack_abs = GetAbsLastAck(stream);
960 if (chunk_size <= diff) {
963 SCLogDebug(
"%s min chunk len not yet reached: "
964 "last_ack %" PRIu32
", ra_raw_base_seq %" PRIu32
", %" PRIu32
" < "
966 PKT_IS_TOSERVER(p) ?
"toserver" :
"toclient", stream->last_ack, stream->base_seq,
967 (stream->last_ack - stream->base_seq), chunk_size);
981 const char *dirstr = NULL;
983 if (direction == STREAM_TOSERVER) {
1007 const uint64_t right_edge =
1009 SCLogDebug(
"%s: app %" PRIu64
" (use: %s), raw %" PRIu64
1010 " (use: %s). Stream right edge: %" PRIu64,
1014 SCLogDebug(
"%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION", dirstr);
1019 const uint64_t right_edge = StreamingBufferGetConsecutiveDataRightEdge(&stream->
sb);
1020 SCLogDebug(
"%s: app %" PRIu64
" (use: %s), raw %" PRIu64
1021 " (use: %s). Stream right edge: %" PRIu64,
1025 SCLogDebug(
"%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION", dirstr);
1030 SCLogDebug(
"%s: STREAM_HAS_UNPROCESSED_SEGMENTS_NONE", dirstr);
1035static uint64_t GetStreamSize(
TcpStream *stream)
1040 uint64_t last_ack_abs = GetAbsLastAck(stream);
1041 uint64_t last_re = 0;
1047 const uint64_t seg_abs =
1049 if (last_re != 0 && last_re < seg_abs) {
1050 const char *gacked = NULL;
1051 if (last_ack_abs >= seg_abs) {
1052 gacked =
"fully ack'd";
1053 }
else if (last_ack_abs > last_re) {
1054 gacked =
"partly ack'd";
1056 gacked =
"not yet ack'd";
1058 SCLogDebug(
" -> gap of size %" PRIu64
", ack:%s", seg_abs - last_re, gacked);
1061 const char *acked = NULL;
1062 if (last_ack_abs >= seg_abs + (uint64_t)
TCP_SEG_LEN(seg)) {
1063 acked =
"fully ack'd";
1064 }
else if (last_ack_abs > seg_abs) {
1065 acked =
"partly ack'd";
1067 acked =
"not yet ack'd";
1070 SCLogDebug(
"%u -> seg %p seq %u abs %" PRIu64
" size %u abs %" PRIu64
" (%" PRIu64
1079 SCLogDebug(
"size %"PRIu64
", cnt %"PRIu32, size, cnt);
1089 size = GetStreamSize(&ssn->
client);
1090 size += GetStreamSize(&ssn->
server);
1105 GetAbsLastAck(stream) > (cur_blk->
offset + cur_blk->
len)) {
1120static bool GetAppBuffer(
const TcpStream *stream,
const uint8_t **data, uint32_t *data_len,
1121 uint64_t
offset,
const bool check_for_gap)
1123 const uint8_t *mydata;
1124 uint32_t mydata_len;
1125 bool gap_ahead =
false;
1133 *data_len = mydata_len;
1152 gap_ahead = check_for_gap && GapAhead(stream, blk);
1156 SCLogDebug(
"gap, want data at offset %"PRIu64
", "
1157 "got data at %"PRIu64
". GAP of size %"PRIu64,
1164 SCLogDebug(
"get data from offset %"PRIu64
". SBB %"PRIu64
"/%u",
1167 SCLogDebug(
"data %p, data_len %u", *data, *data_len);
1169 gap_ahead = check_for_gap && GapAhead(stream, blk);
1188 const uint64_t last_ack_abs = GetAbsLastAck(stream) - (uint64_t)ackadded;
1195 if (last_ack_abs > app_progress) {
1202 "next_seq %u < last_ack %u, but no data in list",
1206 const uint64_t next_seq_abs =
1209 if (blk->
offset > next_seq_abs && blk->
offset < last_ack_abs) {
1212 "next_seq %u < last_ack %u, but ACK'd data beyond gap.",
1219 "last_ack_abs %" PRIu64
" > app_progress %" PRIu64
", "
1220 "but we have no data.",
1221 p->
pcap_cnt, last_ack_abs, app_progress);
1225 "last_ack_abs %"PRIu64
" <= app_progress %"PRIu64,
1226 p->
pcap_cnt, last_ack_abs, app_progress);
1230static inline uint32_t AdjustToAcked(
const Packet *p,
1232 const uint64_t app_progress,
const uint32_t data_len)
1234 uint32_t adjusted = data_len;
1245 const uint64_t last_ack_abs = GetAbsLastAck(stream);
1249 if (app_progress <= last_ack_abs && app_progress + data_len > last_ack_abs) {
1250 adjusted = (uint32_t)(last_ack_abs - app_progress);
1252 SCLogDebug(
"data len adjusted to %u to make sure only ACK'd "
1253 "data is considered", adjusted);
1270 SCLogDebug(
"app progress %"PRIu64, app_progress);
1272 uint64_t last_ack_abs = GetAbsLastAck(*stream);
1273 SCLogDebug(
"last_ack %u (abs %" PRIu64
"), base_seq %u", (*stream)->last_ack, last_ack_abs,
1274 (*stream)->base_seq);
1276 const uint8_t *mydata;
1277 uint32_t mydata_len;
1278 bool last_was_gap =
false;
1281 const uint8_t
flags = StreamGetAppLayerFlags(ssn, *stream, p);
1282 bool check_for_gap_ahead = ((*stream)->data_required > 0);
1284 GetAppBuffer(*stream, &mydata, &mydata_len, app_progress, check_for_gap_ahead);
1286 if (last_was_gap && mydata_len == 0) {
1289 last_was_gap =
false;
1292 mydata_len = AdjustToAcked(p, ssn, *stream, app_progress, mydata_len);
1294 if (mydata == NULL && mydata_len > 0 && CheckGap(ssn, *stream, p)) {
1295 SCLogDebug(
"sending GAP to app-layer (size: %u)", mydata_len);
1298 StreamGetAppLayerFlags(ssn, *stream, p) | STREAM_GAP, app_update_dir);
1312 if ((*stream)->data_required > 0) {
1313 if ((*stream)->data_required > mydata_len) {
1314 (*stream)->data_required -= mydata_len;
1316 (*stream)->data_required = 0;
1321 if (no_progress_update)
1323 last_was_gap =
true;
1326 }
else if (
flags & STREAM_DEPTH) {
1329 if (mydata == NULL && mydata_len > 0) {
1332 }
else if (mydata == NULL || (mydata_len == 0 && ((
flags & STREAM_EOF) == 0))) {
1345 SCLogDebug(
"stream %p data in buffer %p of len %u and offset %"PRIu64,
1346 *stream, &(*stream)->sb, mydata_len, app_progress);
1350 if (mydata_len < (*stream)->data_required) {
1353 SCLogDebug(
"GAP while expecting more data (expect %u, gap size %u)",
1354 (*stream)->data_required, mydata_len);
1355 (*stream)->app_progress_rel += mydata_len;
1356 (*stream)->data_required -= mydata_len;
1366 (*stream)->data_required = 0;
1371 mydata_len,
flags, app_update_dir);
1377 app_progress = new_app_progress;
1378 if (
flags & STREAM_DEPTH)
1406 SCLogDebug(
"stream no reassembly flag set or app-layer disabled.");
1412 GetSessionSize(ssn, p);
1423 uint8_t stream_flags = StreamGetAppLayerFlags(ssn, stream, p);
1426 tv, ra_ctx, p, p->
flow, ssn, &stream, NULL, 0, stream_flags, app_update_dir);
1434 return ReassembleUpdateAppLayer(
tv, ra_ctx, ssn, &stream, p, app_update_dir);
1440static int GetRawBuffer(
const TcpStream *stream,
const uint8_t **data, uint32_t *data_len,
1443 const uint8_t *mydata;
1444 uint32_t mydata_len;
1449 uint64_t roffset =
offset;
1457 *data_len = mydata_len;
1458 *data_offset = roffset;
1460 SCLogDebug(
"multiblob %s. Want offset %"PRIu64,
1461 *iter == NULL ?
"starting" :
"continuing",
offset);
1462 if (*iter == NULL) {
1467 if (*iter == NULL) {
1474 SCLogDebug(
"getting multiple blobs. Iter %p, %"PRIu64
"/%u", *iter, (*iter)->offset, (*iter)->len);
1479 if ((*iter)->offset <
offset) {
1480 uint64_t delta =
offset - (*iter)->offset;
1481 if (delta < mydata_len) {
1482 *data = mydata + delta;
1483 *data_len = (uint32_t)(mydata_len - delta);
1494 *data_len = mydata_len;
1495 *data_offset = (*iter)->offset;
1498 *iter = SBB_RB_NEXT(*iter);
1529 const uint64_t segs_re_abs =
1534 if (StreamTcpReassembleRawCheckLimit(ssn, stream, p) == 1) {
1570 stream->
flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW;
1572 }
else if (progress == 0) {
1577 target = GetAbsLastAck(stream);
1584 stream->
flags &= ~STREAMTCP_STREAM_FLAG_TRIGGER_RAW;
1587 SCLogDebug(
"p->pcap_cnt %"PRIu64
": progress %"PRIu64
" app %"PRIu64
" raw %"PRIu64
" tcp win %"PRIu32,
1596 SCLogDebug(
"ssn %p: STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED set, "
1597 "now that detect ran also set STREAMTCP_STREAM_FLAG_DISABLE_RAW", ssn);
1644 "packet payload len %u, so chunk_size adjusted to %u", p->
payload_len, chunk_size);
1647 const TCPHdr *tcph = PacketGetTCP(p);
1648 uint64_t packet_leftedge_abs =
1650 uint64_t packet_rightedge_abs = packet_leftedge_abs + p->
payload_len;
1651 SCLogDebug(
"packet_leftedge_abs %"PRIu64
", rightedge %"PRIu64,
1652 packet_leftedge_abs, packet_rightedge_abs);
1654 const uint8_t *mydata = NULL;
1655 uint32_t mydata_len = 0;
1656 uint64_t mydata_offset = 0;
1658 bool return_progress =
false;
1663 return_progress =
true;
1666 SCLogDebug(
"finding our SBB from offset %"PRIu64, packet_leftedge_abs);
1673 mydata_offset = sbb->
offset;
1678 uint64_t mydata_rightedge_abs = mydata_offset + mydata_len;
1679 if ((mydata == NULL || mydata_len == 0) ||
1680 (mydata_offset >= packet_rightedge_abs ||
1681 packet_leftedge_abs >= mydata_rightedge_abs) ||
1682 (packet_leftedge_abs < mydata_offset ||
1683 packet_rightedge_abs > mydata_rightedge_abs))
1688 mydata_offset = packet_leftedge_abs;
1692 SCLogDebug(
"chunk_size %u mydata_len %u", chunk_size, mydata_len);
1693 if (mydata_len > chunk_size) {
1694 uint32_t excess = mydata_len - chunk_size;
1695 SCLogDebug(
"chunk_size %u mydata_len %u excess %u", chunk_size, mydata_len, excess);
1697 if (mydata_rightedge_abs == packet_rightedge_abs) {
1699 mydata_len -= excess;
1700 mydata_offset += excess;
1701 SCLogDebug(
"cutting front of the buffer with %u", excess);
1702 }
else if (mydata_offset == packet_leftedge_abs) {
1703 mydata_len -= excess;
1704 SCLogDebug(
"cutting tail of the buffer with %u", excess);
1707 uint32_t abs_before = (uint32_t)(packet_leftedge_abs - mydata_offset);
1709 uint32_t abs_after = (uint32_t)(mydata_rightedge_abs - packet_rightedge_abs);
1710 uint32_t before = abs_before;
1711 uint32_t after = abs_after;
1712 SCLogDebug(
"before %u after %u", before, after);
1717 if (before >= (chunk_size - p->
payload_len) / 2) {
1719 before = after = (chunk_size - p->
payload_len) / 2;
1728 if (before >= (chunk_size - p->
payload_len) / 2) {
1737 uint32_t skip = abs_before - before;
1739 uint32_t cut = abs_after - after;
1744 mydata_len -= (skip + cut);
1745 mydata_offset += skip;
1751 r = Callback(cb_data, mydata, mydata_len, mydata_offset);
1754 if (return_progress) {
1755 *progress_out = (mydata_offset + mydata_len);
1762 const uint64_t last_ack_abs = GetAbsLastAck(stream);
1763 SCLogDebug(
"last_ack_abs %"PRIu64, last_ack_abs);
1766 if (mydata_offset > last_ack_abs) {
1768 *progress_out = last_ack_abs;
1770 *progress_out = (mydata_offset + mydata_len);
1809 const uint64_t re, uint64_t *progress_out,
bool eof)
1815 uint64_t progress = progress_in;
1820 const uint8_t *mydata;
1821 uint32_t mydata_len;
1822 uint64_t mydata_offset = 0;
1824 GetRawBuffer(stream, &mydata, &mydata_len, &iter, progress, &mydata_offset);
1825 if (mydata_len == 0) {
1831 SCLogDebug(
"raw progress %"PRIu64, progress);
1832 SCLogDebug(
"stream %p data in buffer %p of len %u and offset %"PRIu64,
1833 stream, &stream->
sb, mydata_len, progress);
1838 if (re < progress) {
1843 SCLogDebug(
"re %" PRIu64
", raw_progress %" PRIu64, re, progress);
1844 SCLogDebug(
"raw_progress + mydata_len %" PRIu64
", re %" PRIu64, progress + mydata_len,
1848 if (progress + mydata_len > re) {
1849#ifdef DEBUG_VALIDATION
1850 uint32_t check = mydata_len;
1852 mydata_len = (uint32_t)(re - progress);
1854 SCLogDebug(
"data len adjusted to %u to make sure only ACK'd "
1855 "data is considered", mydata_len);
1858 if (mydata_len == 0)
1861 SCLogDebug(
"data %p len %u", mydata, mydata_len);
1864 r = Callback(cb_data, mydata, mydata_len, mydata_offset);
1867 if (mydata_offset == progress) {
1868 SCLogDebug(
"progress %"PRIu64
" increasing with data len %u to %"PRIu64,
1869 progress, mydata_len, progress_in + mydata_len);
1871 progress += mydata_len;
1872 SCLogDebug(
"raw progress now %"PRIu64, progress);
1875 }
else if (mydata_offset > progress && mydata_offset < re) {
1876 SCLogDebug(
"GAP: data is missing from %"PRIu64
" (%u bytes), setting to first data we have: %"PRIu64, progress, (uint32_t)(mydata_offset - progress), mydata_offset);
1878 progress = mydata_offset;
1879 SCLogDebug(
"raw progress now %"PRIu64, progress);
1882 SCLogDebug(
"not increasing progress, data gap => mydata_offset "
1883 "%"PRIu64
" != progress %"PRIu64, mydata_offset, progress);
1886 if (iter == NULL || r == 1)
1890 *progress_out = progress;
1895 void *cb_data,
const uint64_t
offset,
const bool eof)
1899 SCLogDebug(
"app_progress %" PRIu64, app_progress);
1901 uint64_t unused = 0;
1902 return StreamReassembleRawDo(
1903 ssn, stream, Callback, cb_data,
offset, app_progress, &unused, eof);
1908 uint64_t *progress_out,
bool respect_inspect_depth)
1912 return StreamReassembleRawInline(ssn, p, Callback, cb_data, progress_out);
1923 StreamTcpReassembleRawCheckLimit(ssn, stream, p) == 0)
1935 SCLogDebug(
"respect_inspect_depth %s STREAMTCP_STREAM_FLAG_TRIGGER_RAW %s "
1936 "stream->min_inspect_depth %u",
1937 respect_inspect_depth ?
"true" :
"false",
1954 SCLogDebug(
"applied min inspect depth due to STREAMTCP_STREAM_FLAG_TRIGGER_RAW: progress "
1964 const uint64_t last_ack_abs = GetAbsLastAck(stream);
1965 SCLogDebug(
"last_ack_abs %" PRIu64, last_ack_abs);
1967 return StreamReassembleRawDo(ssn, stream, Callback, cb_data, progress, last_ack_abs,
1973 uint64_t *progress_out,
const bool eof)
1979 const uint64_t last_ack_abs = GetAbsLastAck(stream);
1980 SCLogDebug(
"last_ack_abs %" PRIu64, last_ack_abs);
1982 return StreamReassembleRawDo(
1983 ssn, stream, Callback, cb_data, progress_in, last_ack_abs, progress_out, eof);
1991static int StreamTcpReassembleHandleSegmentUpdateACK (
ThreadVars *
tv,
2008 const TCPHdr *tcph = PacketGetTCP(p);
2010 SCLogDebug(
"ssn %p, stream %p, p %p, p->payload_len %"PRIu16
"",
2040 if (stream == &ssn->
client) {
2041 opposing_stream = &ssn->
server;
2043 opposing_stream = &ssn->
client;
2048 if (StreamTcpReassembleHandleSegmentUpdateACK(
tv, ra_ctx, ssn, opposing_stream, p) != 0) {
2049 SCLogDebug(
"StreamTcpReassembleHandleSegmentUpdateACK error");
2057 if (reversed_before_ack_handling != reversed_after_ack_handling) {
2059 stream = opposing_stream;
2065 SCLogDebug(
"calling StreamTcpReassembleHandleSegmentHandleData");
2068 SCLogDebug(
"StreamTcpReassembleHandleSegmentHandleData error");
2072 StreamTcpReassembleExceptionPolicyStatsIncr(
2080 SCLogDebug(
"ssn %p / stream %p: not calling StreamTcpReassembleHandleSegmentHandleData:"
2081 " p->payload_len %u, STREAMTCP_STREAM_FLAG_NOREASSEMBLY %s",
2091 if ((stream->
flags &
2095 SCLogDebug(
"STREAMTCP_STREAM_FLAG_DEPTH_REACHED, truncate applayer");
2097 SCLogDebug(
"override: direction now UPDATE_DIR_PACKET so we "
2098 "can trigger Truncate");
2106 SCLogDebug(
"inline (%s) or PKT_PSEUDO_STREAM_END (%s)",
2165 if (direction == STREAM_TOSERVER) {
2171 SCLogDebug(
"flagged ssn %p for immediate raw reassembly", ssn);
2182 if (direction == STREAM_TOSERVER) {
2184 SCLogDebug(
"ssn %p: set client.min_inspect_depth to %u", ssn, depth);
2187 SCLogDebug(
"ssn %p: set server.min_inspect_depth to %u", ssn, depth);
2195#define SET_ISN(stream, setseq) \
2196 (stream)->isn = (setseq); \
2197 (stream)->base_seq = (setseq) + 1
2215 for (; i <
len; i++)
2229 data, data_len) == 0)
2238#define MISSED_START(isn) \
2239 TcpReassemblyThreadCtx *ra_ctx = NULL; \
2242 memset(&tv, 0, sizeof(tv)); \
2244 StreamTcpUTInit(&ra_ctx); \
2246 StreamTcpUTSetupSession(&ssn); \
2247 StreamTcpUTSetupStream(&ssn.server, (isn)); \
2248 StreamTcpUTSetupStream(&ssn.client, (isn)); \
2250 TcpStream *stream = &ssn.client;
2253 StreamTcpUTClearSession(&ssn); \
2254 StreamTcpUTDeinit(ra_ctx); \
2257#define MISSED_STEP(seq, seg, seglen, buf, buflen) \
2258 StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen)); \
2259 FAIL_IF(!(VALIDATE(stream, (uint8_t *)(buf), (buflen))));
2261#define MISSED_ADD_PAYLOAD(seq, seg, seglen) \
2262 StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen));
2269 uint64_t last_re = 0;
2273 if (sbb->
offset != last_re) {
2293 uint64_t last_re = 0;
2297 if (sbb->
offset != last_re) {
2303 const uint8_t *buf = NULL;
2304 uint32_t buf_len = 0;
2307 if (
len == buf_len) {
2308 return (memcmp(data, buf,
len) == 0);
2325static int StreamTcpReassembleTest25 (
void)
2346static int StreamTcpReassembleTest26 (
void)
2365static int StreamTcpReassembleTest27 (
void)
2382static int StreamTcpReassembleTest28 (
void)
2406static int StreamTcpReassembleTest29 (
void)
2418static int StreamTcpReassembleTest33(
void)
2427 uint8_t packet[1460] =
"";
2432 memset(&f, 0,
sizeof (
Flow));
2433 memset(&tcph, 0,
sizeof (
TCPHdr));
2438 f.
proto = IPPROTO_TCP;
2441 p->
proto = IPPROTO_TCP;
2479static int StreamTcpReassembleTest34(
void)
2488 uint8_t packet[1460] =
"";
2492 memset(&f, 0,
sizeof (
Flow));
2493 memset(&tcph, 0,
sizeof (
TCPHdr));
2498 f.
proto = IPPROTO_TCP;
2501 p->
proto = IPPROTO_TCP;
2510 tcph.
th_seq = htonl(857961230);
2516 tcph.
th_seq = htonl(857961534);
2522 tcph.
th_seq = htonl(857963582);
2528 tcph.
th_seq = htonl(857960946);
2548static int StreamTcpReassembleTest39 (
void)
2558 memset (&f, 0,
sizeof(
Flow));
2560 memset(&stt, 0,
sizeof (stt));
2561 memset(&tcph, 0,
sizeof (
TCPHdr));
2565 f.
proto = IPPROTO_TCP;
2572 tcph.
th_win = htons(5480);
2640 uint8_t request1[] = { 0x47, 0x45, };
2687 uint8_t request2[] = {
2688 0x54, 0x20, 0x2f, 0x69, 0x6e, 0x64,
2689 0x65, 0x78, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x20,
2690 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x30,
2691 0x0d, 0x0a, 0x48, 0x6f, 0x73, 0x74, 0x3a, 0x20,
2692 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73,
2693 0x74, 0x0d, 0x0a, 0x55, 0x73, 0x65, 0x72, 0x2d,
2694 0x41, 0x67, 0x65, 0x6e, 0x74, 0x3a, 0x20, 0x41,
2695 0x70, 0x61, 0x63, 0x68, 0x65, 0x42, 0x65, 0x6e,
2696 0x63, 0x68, 0x2f, 0x32, 0x2e, 0x33, 0x0d, 0x0a,
2697 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x3a, 0x20,
2698 0x2a, 0x2f, 0x2a, 0x0d, 0x0a, 0x0d, 0x0a };
2723 uint8_t response[] = {
2724 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31,
2725 0x20, 0x32, 0x30, 0x30, 0x20, 0x4f, 0x4b, 0x0d,
2726 0x0a, 0x44, 0x61, 0x74, 0x65, 0x3a, 0x20, 0x46,
2727 0x72, 0x69, 0x2c, 0x20, 0x32, 0x33, 0x20, 0x53,
2728 0x65, 0x70, 0x20, 0x32, 0x30, 0x31, 0x31, 0x20,
2729 0x30, 0x36, 0x3a, 0x32, 0x39, 0x3a, 0x33, 0x39,
2730 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a, 0x53, 0x65,
2731 0x72, 0x76, 0x65, 0x72, 0x3a, 0x20, 0x41, 0x70,
2732 0x61, 0x63, 0x68, 0x65, 0x2f, 0x32, 0x2e, 0x32,
2733 0x2e, 0x31, 0x35, 0x20, 0x28, 0x55, 0x6e, 0x69,
2734 0x78, 0x29, 0x20, 0x44, 0x41, 0x56, 0x2f, 0x32,
2735 0x0d, 0x0a, 0x4c, 0x61, 0x73, 0x74, 0x2d, 0x4d,
2736 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x3a,
2737 0x20, 0x54, 0x68, 0x75, 0x2c, 0x20, 0x30, 0x34,
2738 0x20, 0x4e, 0x6f, 0x76, 0x20, 0x32, 0x30, 0x31,
2739 0x30, 0x20, 0x31, 0x35, 0x3a, 0x30, 0x34, 0x3a,
2740 0x34, 0x36, 0x20, 0x47, 0x4d, 0x54, 0x0d, 0x0a,
2741 0x45, 0x54, 0x61, 0x67, 0x3a, 0x20, 0x22, 0x61,
2742 0x62, 0x38, 0x39, 0x36, 0x35, 0x2d, 0x32, 0x63,
2743 0x2d, 0x34, 0x39, 0x34, 0x33, 0x62, 0x37, 0x61,
2744 0x37, 0x66, 0x37, 0x66, 0x38, 0x30, 0x22, 0x0d,
2745 0x0a, 0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d,
2746 0x52, 0x61, 0x6e, 0x67, 0x65, 0x73, 0x3a, 0x20,
2747 0x62, 0x79, 0x74, 0x65, 0x73, 0x0d, 0x0a, 0x43,
2748 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x4c,
2749 0x65, 0x6e, 0x67, 0x74, 0x68, 0x3a, 0x20, 0x34,
2750 0x34, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
2751 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x63,
2752 0x6c, 0x6f, 0x73, 0x65, 0x0d, 0x0a, 0x43, 0x6f,
2753 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2d, 0x54, 0x79,
2754 0x70, 0x65, 0x3a, 0x20, 0x74, 0x65, 0x78, 0x74,
2755 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x0d, 0x0a, 0x58,
2756 0x2d, 0x50, 0x61, 0x64, 0x3a, 0x20, 0x61, 0x76,
2757 0x6f, 0x69, 0x64, 0x20, 0x62, 0x72, 0x6f, 0x77,
2758 0x73, 0x65, 0x72, 0x20, 0x62, 0x75, 0x67, 0x0d,
2759 0x0a, 0x0d, 0x0a, 0x3c, 0x68, 0x74, 0x6d, 0x6c,
2760 0x3e, 0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x3c,
2761 0x68, 0x31, 0x3e, 0x49, 0x74, 0x20, 0x77, 0x6f,
2762 0x72, 0x6b, 0x73, 0x21, 0x3c, 0x2f, 0x68, 0x31,
2763 0x3e, 0x3c, 0x2f, 0x62, 0x6f, 0x64, 0x79, 0x3e,
2764 0x3c, 0x2f, 0x68, 0x74, 0x6d, 0x6c, 0x3e };
2790 tcph.
th_ack = htonl(328);
2816 tcph.
th_seq = htonl(328);
2840 tcph.
th_ack = htonl(328);
2865 tcph.
th_seq = htonl(328);
2890 tcph.
th_ack = htonl(328);
2916 tcph.
th_seq = htonl(328);
2941 tcph.
th_ack = htonl(328);
2967 tcph.
th_ack = htonl(175);
2968 tcph.
th_seq = htonl(328);
2994 tcph.
th_ack = htonl(175);
2995 tcph.
th_seq = htonl(328);
3011 tcph.
th_ack = htonl(328);
3012 tcph.
th_seq = htonl(175);
3032static int StreamTcpReassembleTest40 (
void)
3039 memset(&tcph, 0,
sizeof (
TCPHdr));
3049 uint8_t httpbuf1[] =
"P";
3050 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3051 uint8_t httpbuf3[] =
"O";
3052 uint32_t httplen3 =
sizeof(httpbuf3) - 1;
3053 uint8_t httpbuf4[] =
"S";
3054 uint32_t httplen4 =
sizeof(httpbuf4) - 1;
3055 uint8_t httpbuf5[] =
"T \r\n";
3056 uint32_t httplen5 =
sizeof(httpbuf5) - 1;
3058 uint8_t httpbuf2[] =
"HTTP/1.0 200 OK\r\nServer: VictorServer/1.0\r\n\r\n";
3059 uint32_t httplen2 =
sizeof(httpbuf2) - 1;
3066 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 200, 220);
3069 f->
proto = IPPROTO_TCP;
3072 tcph.
th_win = htons(5480);
3124 tcph.
th_ack = htonl(100);
3133 tcph.
th_seq = htonl(100);
3144 tcph.
th_ack = htonl(145);
3153 tcph.
th_seq = htonl(145);
3170static int StreamTcpReassembleTest44(
void)
3174 StreamTcpReassembleIncrMemuse(500);
3176 StreamTcpReassembleDecrMemuse(500);
3191static int StreamTcpReassembleTest45 (
void)
3196 memset(&
tv, 0,
sizeof(
tv));
3197 uint8_t payload[100] = {0};
3198 uint16_t payload_size = 100;
3229static int StreamTcpReassembleTest46 (
void)
3235 memset(&
tv, 0,
sizeof(
tv));
3236 uint8_t payload[100] = {0};
3237 uint16_t payload_size = 100;
3250 printf(
"STREAMTCP_STREAM_FLAG_NOREASSEMBLY set: ");
3258 printf(
"STREAMTCP_STREAM_FLAG_NOREASSEMBLY set: ");
3278static int StreamTcpReassembleTest47 (
void)
3286 memset(&tcph, 0,
sizeof (
TCPHdr));
3293 uint8_t httpbuf1[] =
"GET /EVILSUFF HTTP/1.1\r\n\r\n";
3294 uint32_t httplen1 =
sizeof(httpbuf1) - 1;
3302 f =
UTHBuildFlow(AF_INET,
"1.2.3.4",
"1.2.3.5", 200, 220);
3305 f->
proto = IPPROTO_TCP;
3308 tcph.
th_win = htons(5480);
3313 for (cnt=0;
cnt < httplen1;
cnt++) {
3315 tcph.
th_ack = htonl(572799782UL);
3327 tcph.
th_seq = htonl(572799782UL);
3346static int StreamTcpReassembleInlineTest01(
void)
3354 memset(&
tv, 0x00,
sizeof(
tv));
3362 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3365 printf(
"couldn't get a packet: ");
3372 printf(
"failed to add segment 1: ");
3376 printf(
"failed to add segment 2: ");
3380 printf(
"failed to add segment 3: ");
3396static int StreamTcpReassembleInlineTest02(
void)
3404 memset(&
tv, 0x00,
sizeof(
tv));
3412 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3415 printf(
"couldn't get a packet: ");
3422 printf(
"failed to add segment 1: ");
3426 printf(
"failed to add segment 2: ");
3430 printf(
"failed to add segment 3: ");
3435 printf(
"failed to add segment 4: ");
3452static int StreamTcpReassembleInlineTest03(
void)
3460 memset(&
tv, 0x00,
sizeof(
tv));
3470 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3473 printf(
"couldn't get a packet: ");
3481 printf(
"failed to add segment 1: ");
3485 printf(
"failed to add segment 2: ");
3489 printf(
"failed to add segment 3: ");
3494 printf(
"failed to add segment 4: ");
3513static int StreamTcpReassembleInlineTest04(
void)
3521 memset(&
tv, 0x00,
sizeof(
tv));
3531 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3534 printf(
"couldn't get a packet: ");
3542 printf(
"failed to add segment 1: ");
3546 printf(
"failed to add segment 2: ");
3550 printf(
"failed to add segment 3: ");
3555 printf(
"failed to add segment 4: ");
3575static int StreamTcpReassembleInlineTest08(
void)
3579 memset(&
tv, 0x00,
sizeof(
tv));
3591 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3623static int StreamTcpReassembleInlineTest09(
void)
3631 memset(&
tv, 0x00,
sizeof(
tv));
3641 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3644 printf(
"couldn't get a packet: ");
3652 printf(
"failed to add segment 1: ");
3656 printf(
"failed to add segment 2: ");
3660 printf(
"failed to add segment 3: ");
3668 printf(
"failed to add segment 4: ");
3690static int StreamTcpReassembleInlineTest10(
void)
3699 memset(&
tv, 0x00,
sizeof(
tv));
3710 f =
UTHBuildFlow(AF_INET,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3714 f->
proto = IPPROTO_TCP;
3716 uint8_t stream_payload1[] =
"GE";
3717 uint8_t stream_payload2[] =
"T /";
3718 uint8_t stream_payload3[] =
"HTTP/1.0\r\n\r\n";
3720 p =
UTHBuildPacketReal(stream_payload3, 12, IPPROTO_TCP,
"1.1.1.1",
"2.2.2.2", 1024, 80);
3722 printf(
"couldn't get a packet: ");
3730 printf(
"failed to add segment 1: ");
3737 printf(
"StreamTcpReassembleAppLayer failed: ");
3743 printf(
"expected ra_app_base_seq 1, got %u: ", ssn.
client.
base_seq);
3748 printf(
"failed to add segment 2: ");
3752 printf(
"failed to add segment 3: ");
3759 printf(
"StreamTcpReassembleAppLayer failed: ");
3776static int StreamTcpReassembleInsertTest01(
void)
3783 memset(&
tv, 0x00,
sizeof(
tv));
3791 uint8_t payload[] = {
'C',
'C',
'C',
'C',
'C' };
3813static int StreamTcpReassembleInsertTest02(
void)
3820 memset(&
tv, 0x00,
sizeof(
tv));
3827 for (i = 2; i < 10; i++) {
3838 printf(
"failed to add segment 1: ");
3843 printf(
"failed to add segment 2: ");
3856static int StreamTcpReassembleInsertTest03(
void)
3863 memset(&
tv, 0x00,
sizeof(
tv));
3870 printf(
"failed to add segment 2: ");
3875 for (i = 2; i < 10; i++) {
3886 printf(
"failed to add segment 2: ");
3907 UtRegisterTest(
"StreamTcpReassembleTest25 -- Gap at Start Reassembly Test",
3908 StreamTcpReassembleTest25);
3909 UtRegisterTest(
"StreamTcpReassembleTest26 -- Gap at middle Reassembly Test",
3910 StreamTcpReassembleTest26);
3911 UtRegisterTest(
"StreamTcpReassembleTest27 -- Gap at after Reassembly Test",
3912 StreamTcpReassembleTest27);
3913 UtRegisterTest(
"StreamTcpReassembleTest28 -- Gap at Start IDS missed packet Reassembly Test",
3914 StreamTcpReassembleTest28);
3915 UtRegisterTest(
"StreamTcpReassembleTest29 -- Gap at Middle IDS missed packet Reassembly Test",
3916 StreamTcpReassembleTest29);
3918 StreamTcpReassembleTest33);
3920 StreamTcpReassembleTest34);
3922 StreamTcpReassembleTest39);
3924 StreamTcpReassembleTest40);
3926 StreamTcpReassembleTest44);
3928 StreamTcpReassembleTest45);
3930 StreamTcpReassembleTest46);
3931 UtRegisterTest(
"StreamTcpReassembleTest47 -- TCP Sequence Wraparound Test",
3932 StreamTcpReassembleTest47);
3934 UtRegisterTest(
"StreamTcpReassembleInlineTest01 -- inline RAW ra",
3935 StreamTcpReassembleInlineTest01);
3936 UtRegisterTest(
"StreamTcpReassembleInlineTest02 -- inline RAW ra 2",
3937 StreamTcpReassembleInlineTest02);
3938 UtRegisterTest(
"StreamTcpReassembleInlineTest03 -- inline RAW ra 3",
3939 StreamTcpReassembleInlineTest03);
3940 UtRegisterTest(
"StreamTcpReassembleInlineTest04 -- inline RAW ra 4",
3941 StreamTcpReassembleInlineTest04);
3942 UtRegisterTest(
"StreamTcpReassembleInlineTest08 -- inline RAW ra 8 cleanup",
3943 StreamTcpReassembleInlineTest08);
3944 UtRegisterTest(
"StreamTcpReassembleInlineTest09 -- inline RAW ra 9 GAP cleanup",
3945 StreamTcpReassembleInlineTest09);
3947 UtRegisterTest(
"StreamTcpReassembleInlineTest10 -- inline APP ra 10",
3948 StreamTcpReassembleInlineTest10);
3950 UtRegisterTest(
"StreamTcpReassembleInsertTest01 -- insert with overlap",
3951 StreamTcpReassembleInsertTest01);
3952 UtRegisterTest(
"StreamTcpReassembleInsertTest02 -- insert with overlap",
3953 StreamTcpReassembleInsertTest02);
3954 UtRegisterTest(
"StreamTcpReassembleInsertTest03 -- insert with overlap",
3955 StreamTcpReassembleInsertTest03);
3960 StreamTcpReassembleRawRegisterTests();
void AppLayerDecoderEventsSetEventRaw(AppLayerDecoderEvents **sevents, uint8_t event)
Set an app layer decoder event.
@ APPLAYER_PROTO_DETECTION_SKIPPED
void AppLayerFrameDump(Flow *f)
void SCAppLayerParserStateSetFlag(AppLayerParserState *pstate, uint16_t flag)
#define APP_LAYER_PARSER_EOF_TC
#define APP_LAYER_PARSER_EOF_TS
int AppLayerHandleTCPData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, Packet *p, Flow *f, TcpSession *ssn, TcpStream **stream, uint8_t *data, uint32_t data_len, uint8_t flags, enum StreamUpdateDir app_update_dir)
handle TCP data for the app-layer.
void AppLayerDestroyCtxThread(AppLayerThreadCtx *app_tctx)
Destroys the context created by AppLayerGetCtxThread().
AppLayerThreadCtx * AppLayerGetCtxThread(void)
Creates a new app layer thread context.
#define APP_LAYER_DATA_ALREADY_SENT_TO_APP_LAYER
#define AppLayerProfilingStore(app_tctx, p)
SCConfNode * SCConfGetNode(const char *name)
Get a SCConfNode by name.
int SCConfGetBool(const char *name, int *val)
Retrieve a configuration value as a boolean.
uint16_t StatsRegisterGlobalCounter(const char *name, uint64_t(*Func)(void))
Registers a counter, which represents a global value.
void StatsIncr(ThreadVars *tv, uint16_t id)
Increments the local counter.
@ STREAM_REASSEMBLY_NO_SEGMENT
@ STREAM_REASSEMBLY_URGENT_OOB_LIMIT_REACHED
@ STREAM_REASSEMBLY_SEQ_GAP
@ STREAM_REASSEMBLY_DEPTH_REACHED
#define TCP_GET_RAW_SEQ(tcph)
@ PKT_DROP_REASON_STREAM_URG
@ PKT_DROP_REASON_STREAM_REASSEMBLY
#define PKT_PSEUDO_STREAM_END
#define PKT_IS_TOSERVER(p)
Data structures and function prototypes for keeping state for the detection engine.
TcpStreamCnf stream_config
#define FLOW_INITIALIZE(f)
int FlowChangeProto(Flow *f)
Check if change proto flag is set for flow.
#define FLOW_PKT_TOSERVER
#define FLOW_DIR_REVERSED
#define FLOW_IS_PP_DONE(f, dir)
#define FLOW_IS_PM_DONE(f, dir)
#define FLOW_PKT_TOCLIENT
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define FAIL_IF_NOT(expr)
Fail a test if expression evaluates to false.
#define PASS
Pass the test.
#define FAIL_IF(expr)
Fail a test if expression evaluates to true.
Packet * PacketGetFromAlloc(void)
Get a malloced packet.
void PoolThreadFree(PoolThread *pt)
destroy the thread pool
int PoolThreadExpand(PoolThread *pt)
expand pool by one for a new thread
void * PoolThreadGetById(PoolThread *pt, uint16_t id)
get data from thread pool by thread id
int PoolThreadSize(PoolThread *pt)
get size of PoolThread (number of 'threads', so array elements)
PoolThread * PoolThreadInit(int threads, uint32_t size, uint32_t prealloc_size, uint32_t elt_size, void *(*Alloc)(void), int(*Init)(void *, void *), void *InitData, void(*Cleanup)(void *), void(*Free)(void *))
per thread Pool, initialization function
void PacketDrop(Packet *p, const uint8_t action, enum PacketDropReason r)
issue drop action
void StreamTcpThreadCacheCleanup(void)
TcpSegment * StreamTcpThreadCacheGetSegment(void)
void StreamTcpThreadCacheReturnSegment(TcpSegment *seg)
void StreamTcpInlineRegisterTests(void)
void StreamTcpReassembleConfigEnableOverlapCheck(void)
int StreamTcpReassembleInsertSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, TcpSegment *seg, Packet *p, uint8_t *pkt_data, uint16_t pkt_datalen)
void StreamTcpPruneSession(Flow *f, uint8_t flags)
Remove idle TcpSegments from TcpSession.
void StreamTcpListRegisterTests(void)
#define STREAMTCP_STREAM_FLAG_NOREASSEMBLY
#define TCPSEG_PKT_HDR_DEFAULT_SIZE
#define STREAMTCP_STREAM_FLAG_DISABLE_RAW
#define STREAMTCP_FLAG_ASYNC
#define STREAMTCP_FLAG_CLOSED_BY_RST
#define StreamTcpIsSetStreamFlagAppProtoDetectionCompleted(stream)
#define STREAM_APP_PROGRESS(stream)
#define STREAM_BASE_OFFSET(stream)
#define STREAMTCP_STREAM_FLAG_TRIGGER_RAW
#define STREAM_HAS_SEEN_DATA(stream)
#define StreamTcpSetStreamFlagAppProtoDetectionCompleted(stream)
#define STREAMTCP_FLAG_MIDSTREAM
#define StreamTcpSetEvent(p, e)
#define StreamTcpDisableAppLayerReassembly(ssn)
#define STREAMTCP_FLAG_LOSSY_BE_LIBERAL
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_SKIPPED
struct TcpSegmentPcapHdrStorage_ TcpSegmentPcapHdrStorage
#define STREAM_RIGHT_EDGE(stream)
#define STREAMTCP_STREAM_FLAG_NEW_RAW_DISABLED
#define STREAMTCP_STREAM_FLAG_APPPROTO_DETECTION_COMPLETED
#define STREAMTCP_FLAG_APP_LAYER_DISABLED
#define STREAMTCP_STREAM_FLAG_HAS_GAP
#define STREAMTCP_STREAM_FLAG_DEPTH_REACHED
#define STREAM_RAW_PROGRESS(stream)
#define SET_ISN(stream, setseq)
void StreamTcpSegmentReturntoPool(TcpSegment *seg)
Function to return the segment back to the pool.
void StreamTcpReassembleTriggerRawInspection(TcpSession *ssn, int direction)
Trigger RAW stream inspection.
int StreamTcpReassembleCheckMemcap(uint64_t size)
Function to Check the reassembly memory usage counter against the allowed max memory usage for TCP se...
bool StreamReassembleRawHasDataReady(TcpSession *ssn, Packet *p)
does the stream engine have data to inspect?
int StreamReassembleRaw(TcpSession *ssn, const Packet *p, StreamReassembleRawFunc Callback, void *cb_data, uint64_t *progress_out, bool respect_inspect_depth)
#define MISSED_STEP(seq, seg, seglen, buf, buflen)
void EnableTcpSessionDumping(void)
void StreamTcpDisableAppLayer(Flow *f)
uint64_t StreamTcpReassembleMemuseGlobalCounter(void)
void StreamTcpReassembleRegisterTests(void)
The Function Register the Unit tests to test the reassembly engine for various OS policies.
uint64_t StreamTcpReassembleGetMemcap(void)
Return memcap value.
#define MISSED_ADD_PAYLOAD(seq, seg, seglen)
bool StreamTcpReassembleDepthReached(Packet *p)
check if stream in pkt direction has depth reached
uint64_t StreamTcpGetUsable(const TcpStream *stream, const bool eof)
void StreamReassembleRawUpdateProgress(TcpSession *ssn, Packet *p, const uint64_t progress)
update stream engine after detection
void StreamTcpReassemblySetMinInspectDepth(TcpSession *ssn, int direction, uint32_t depth)
#define STREAMTCP_STREAM_FLAG_FLUSH_FLAGS
int StreamTcpReassembleHandleSegmentHandleData(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
Insert a TCP packet data into the stream reassembly engine.
void * StreamTcpReassembleRealloc(void *optr, size_t orig_size, size_t size)
int UTHCheckDataAtPosition(TcpStream *stream, int pos, uint64_t offset, const char *data, uint32_t len)
void StreamTcpReassembleInitMemuse(void)
thread_local uint64_t t_pcapcnt
void StreamTcpReassembleFreeThreadCtx(TcpReassemblyThreadCtx *ra_ctx)
TcpSegment * StreamTcpGetSegment(ThreadVars *tv, TcpReassemblyThreadCtx *)
get a segment from the pool
int StreamTcpReassembleInit(bool quiet)
bool IsTcpSessionDumpingEnabled(void)
int UTHCheckGapAtPosition(TcpStream *stream, int pos, uint64_t offset, uint32_t len)
int StreamTcpReassembleAppLayer(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p, enum StreamUpdateDir app_update_dir)
Update the stream reassembly upon receiving a packet.
int StreamReassembleLog(const TcpSession *ssn, const TcpStream *stream, StreamReassembleRawFunc Callback, void *cb_data, const uint64_t progress_in, uint64_t *progress_out, const bool eof)
uint64_t StreamDataRightEdge(const TcpStream *stream, const bool eof)
uint32_t StreamDataAvailableForProtoDetect(TcpStream *stream)
int StreamTcpAppLayerIsDisabled(Flow *f)
TcpReassemblyThreadCtx * StreamTcpReassembleInitThreadCtx(ThreadVars *tv)
int StreamTcpReassembleHandleSegment(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, Packet *p)
int StreamTcpReassembleSetMemcap(uint64_t size)
Update memcap value.
void StreamTcpReturnStreamSegments(TcpStream *stream)
return all segments in this stream into the pool(s)
PoolThread * segment_thread_pool
void StreamTcpReassembleFree(bool quiet)
void StreamTcpCreateTestPacket(uint8_t *, uint8_t, uint8_t, uint8_t)
The Function to create the packet with given payload, which is used to test the reassembly of the eng...
uint8_t StreamNeedsReassembly(const TcpSession *ssn, uint8_t direction)
see what if any work the TCP session still needs
#define MISSED_START(isn)
int StreamReassembleForFrame(TcpSession *ssn, TcpStream *stream, StreamReassembleRawFunc Callback, void *cb_data, const uint64_t offset, const bool eof)
void StreamTcpSetOSPolicy(TcpStream *, Packet *)
Function to set the OS policy for the given stream based on the destination of the received packet.
void StreamTcpUTSetupSession(TcpSession *ssn)
void StreamTcpUTSetupStream(TcpStream *s, uint32_t isn)
void StreamTcpUtilRegisterTests(void)
void StreamTcpUTClearSession(TcpSession *ssn)
int StreamTcpUTAddSegmentWithByte(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t byte, uint16_t len)
void StreamTcpUTClearStream(TcpStream *s)
void StreamTcpUTInitInline(void)
int StreamTcpUTAddSegmentWithPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
void StreamTcpUTInit(TcpReassemblyThreadCtx **ra_ctx)
int StreamTcpUTAddPayload(ThreadVars *tv, TcpReassemblyThreadCtx *ra_ctx, TcpSession *ssn, TcpStream *stream, uint32_t seq, uint8_t *payload, uint16_t len)
wrapper for StreamTcpReassembleHandleSegmentHandleData
void StreamTcpUTDeinit(TcpReassemblyThreadCtx *ra_ctx)
bool StreamTcpInlineMode(void)
See if stream engine is operating in inline mode.
const char * StreamTcpStateAsString(const enum TcpState state)
void StreamTcpFreeConfig(bool quiet)
void StreamTcpInitConfig(bool)
To initialize the stream global configuration data.
int StreamTcpPacket(ThreadVars *tv, Packet *p, StreamTcpThread *stt, PacketQueueNoLock *pq)
void StreamTcpSessionClear(void *ssnptr)
Function to return the stream back to the pool. It returns the segments in the stream to the segment ...
@ TCP_STREAM_URGENT_INLINE
@ STREAM_HAS_UNPROCESSED_SEGMENTS_NEED_ONLY_DETECTION
@ STREAM_HAS_UNPROCESSED_SEGMENTS_NONE
int(* StreamReassembleRawFunc)(void *data, const uint8_t *input, const uint32_t input_len, const uint64_t offset)
uint16_t eps_id[EXCEPTION_POLICY_MAX]
AppProto alproto
application level protocol
AppLayerParserState * alparser
union PacketL4::L4Hdrs hdrs
simple fifo queue for packets
uint8_t app_update_direction
AppLayerDecoderEvents * app_layer_events
TcpReassemblyThreadCtx * ra_ctx
void(* Free)(void *ptr, size_t size)
void *(* Realloc)(void *ptr, size_t orig_size, size_t size)
void *(* Calloc)(size_t n, size_t size)
StreamingBufferRegion region
StreamingBufferBlock * head
uint16_t counter_tcp_stream_depth
uint16_t counter_tcp_segment_from_pool
uint16_t counter_tcp_reass_gap
int segment_thread_pool_id
uint16_t counter_tcp_segment_from_cache
uint16_t counter_tcp_urgent_oob
uint16_t counter_tcp_segment_memcap
ExceptionPolicyCounters counter_tcp_reas_eps
StreamingBufferSegment sbseg
TcpSegmentPcapHdrStorage * pcap_hdr_storage
uint32_t reassembly_depth
int8_t data_first_seen_dir
enum ExceptionPolicy reassembly_memcap_policy
uint16_t reassembly_toserver_chunk_size
uint32_t reassembly_depth
uint16_t reassembly_toclient_chunk_size
enum TcpStreamUrgentHandling urgent_policy
StreamingBufferConfig sbcnf
enum TcpStreamUrgentHandling urgent_oob_limit_policy
uint32_t prealloc_segments
uint32_t min_inspect_depth
uint32_t raw_progress_rel
Per thread variable structure.
int RunmodeIsUnittests(void)
#define SCMUTEX_INITIALIZER
#define SCMutexUnlock(mut)
#define SCMutexInit(mut, mutattrs)
#define RB_FOREACH(x, name, head)
#define RB_FOREACH_SAFE(x, name, head, y)
#define RB_REMOVE(name, x, y)
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
int StringParseUint16(uint16_t *res, int base, size_t len, const char *str)
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
#define SCLogNotice(...)
Macro used to log NOTICE messages.
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
#define SCReturnPtr(x, type)
#define SCLogError(...)
Macro used to log ERROR messages.
thread_local SCError sc_errno
void ExceptionPolicyApply(Packet *p, enum ExceptionPolicy policy, enum PacketDropReason drop_reason)
#define SCRealloc(ptr, sz)
void PrintRawDataFp(FILE *fp, const uint8_t *buf, uint32_t buflen)
void StreamingBufferSBBGetDataAtOffset(const StreamingBuffer *sb, const StreamingBufferBlock *sbb, const uint8_t **data, uint32_t *data_len, uint64_t offset)
get the data for one SBB
int StreamingBufferGetDataAtOffset(const StreamingBuffer *sb, const uint8_t **data, uint32_t *data_len, uint64_t offset)
StreamingBufferBlock * SBB_RB_FIND_INCLUSIVE(struct SBB *head, StreamingBufferBlock *elm)
int StreamingBufferCompareRawData(const StreamingBuffer *sb, const uint8_t *rawdata, uint32_t rawdata_len)
void StreamingBufferSBBGetData(const StreamingBuffer *sb, const StreamingBufferBlock *sbb, const uint8_t **data, uint32_t *data_len)
get the data for one SBB
int StreamingBufferGetData(const StreamingBuffer *sb, const uint8_t **data, uint32_t *data_len, uint64_t *stream_offset)
#define STREAMING_BUFFER_REGION_GAP_DEFAULT
Packet * UTHBuildPacketReal(uint8_t *payload, uint16_t payload_len, uint8_t ipproto, const char *src, const char *dst, uint16_t sport, uint16_t dport)
UTHBuildPacketReal is a function that create tcp/udp packets for unittests specifying ip and port sou...
void UTHFreeFlow(Flow *flow)
void UTHFreePacket(Packet *p)
UTHFreePacket: function to release the allocated data from UTHBuildPacket and the packet itself.
void UTHSetTCPHdr(Packet *p, TCPHdr *tcph)
Flow * UTHBuildFlow(int family, const char *src, const char *dst, Port sp, Port dp)
#define DEBUG_VALIDATE_BUG_ON(exp)