85 #define STREAMTCP_DEFAULT_PREALLOC 2048
86 #define STREAMTCP_DEFAULT_MEMCAP (64 * 1024 * 1024)
87 #define STREAMTCP_DEFAULT_REASSEMBLY_MEMCAP (256 * 1024 * 1024)
88 #define STREAMTCP_DEFAULT_TOSERVER_CHUNK_SIZE 2560
89 #define STREAMTCP_DEFAULT_TOCLIENT_CHUNK_SIZE 2560
90 #define STREAMTCP_DEFAULT_MAX_SYN_QUEUED 10
91 #define STREAMTCP_DEFAULT_MAX_SYNACK_QUEUED 5
106 .valid_settings_ips = {
132 .valid_settings_ips = {
158 .valid_settings_ips = {
184 .valid_settings_ips = {
207 static int StreamTcpStateDispatch(
216 static uint64_t ssn_pool_cnt = 0;
237 #if defined(DEBUG_VALIDATION) && defined(UNITTESTS)
240 BUG_ON(presize > UINT_MAX);
246 #if defined(DEBUG_VALIDATION) && defined(UNITTESTS)
249 BUG_ON(postsize > presize);
271 if (memcapcopy == 0 || size +
SC_ATOMIC_GET(st_memuse) <= memcapcopy)
283 if (size == 0 || (uint64_t)
SC_ATOMIC_GET(st_memuse) < size) {
304 if (stream != NULL) {
311 static void StreamTcp3wsFreeQueue(
TcpSession *ssn)
338 StreamTcp3wsFreeQueue(ssn);
399 static void *StreamTcpSessionPoolAlloc(
void)
413 static int StreamTcpSessionPoolInit(
void *data,
void* initdata)
423 static void StreamTcpSessionPoolCleanup(
void *s)
437 static inline bool StreamTcpInlineDropInvalid(
void)
446 static int RandomGetWrap(
void)
452 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
466 uint16_t rdrange = 10;
475 if ((
ConfGetInt(
"stream.max-sessions", &value)) == 1) {
477 "Number of concurrent sessions is now only limited by Flow and "
478 "TCP stream engine memcaps.");
481 if ((
ConfGetInt(
"stream.prealloc-sessions", &value)) == 1) {
488 if (
ConfGetNode(
"stream.prealloc-sessions") != NULL) {
496 SCLogConfig(
"stream \"prealloc-sessions\": %"PRIu32
" (per thread)",
500 const char *temp_stream_memcap_str;
501 if (
ConfGet(
"stream.memcap", &temp_stream_memcap_str) == 1) {
502 uint64_t stream_memcap_copy;
505 "from conf file - %s. Killing engine",
506 temp_stream_memcap_str);
520 (void)
ConfGetBool(
"stream.midstream", &imidstream);
528 (void)
ConfGetBool(
"stream.async-oneside", &async_oneside);
537 if ((
ConfGetBool(
"stream.checksum-validation", &csum)) == 1) {
549 "enabled" :
"disabled");
552 const char *temp_stream_inline_str;
553 if (
ConfGet(
"stream.inline", &temp_stream_inline_str) == 1) {
558 if (strcmp(temp_stream_inline_str,
"auto") == 0) {
562 }
else if (
ConfGetBool(
"stream.inline", &inl) == 1) {
581 ?
"enabled" :
"disabled");
585 if ((
ConfGetBool(
"stream.bypass", &bypass)) == 1) {
594 ?
"enabled" :
"disabled");
597 int drop_invalid = 0;
598 if ((
ConfGetBool(
"stream.drop-invalid", &drop_invalid)) == 1) {
599 if (drop_invalid == 1) {
606 if ((
ConfGetInt(
"stream.max-syn-queued", &value)) == 1) {
607 if (value >= 0 && value <= 255) {
619 if ((
ConfGetInt(
"stream.max-synack-queued", &value)) == 1) {
620 if (value >= 0 && value <= 255) {
632 const char *temp_stream_reassembly_memcap_str;
633 if (
ConfGet(
"stream.reassembly.memcap", &temp_stream_reassembly_memcap_str) == 1) {
634 uint64_t stream_reassembly_memcap_copy;
636 &stream_reassembly_memcap_copy) < 0) {
638 "stream.reassembly.memcap "
639 "from conf file - %s. Killing engine",
640 temp_stream_reassembly_memcap_str);
650 SCLogConfig(
"stream.reassembly \"memcap\": %"PRIu64
"",
654 const char *temp_stream_reassembly_depth_str;
655 if (
ConfGet(
"stream.reassembly.depth", &temp_stream_reassembly_depth_str) == 1) {
659 "stream.reassembly.depth "
660 "from conf file - %s. Killing engine",
661 temp_stream_reassembly_depth_str);
673 if ((
ConfGetBool(
"stream.reassembly.randomize-chunk-size", &randomize)) == 0) {
681 const char *temp_rdrange;
682 if (
ConfGet(
"stream.reassembly.randomize-chunk-range", &temp_rdrange) == 1) {
685 "stream.reassembly.randomize-chunk-range "
686 "from conf file - %s. Killing engine",
689 }
else if (rdrange >= 100) {
690 FatalError(
"stream.reassembly.randomize-chunk-range "
691 "must be lower than 100");
696 const char *temp_stream_reassembly_toserver_chunk_size_str;
697 if (
ConfGet(
"stream.reassembly.toserver-chunk-size",
698 &temp_stream_reassembly_toserver_chunk_size_str) == 1) {
702 "stream.reassembly.toserver-chunk-size "
703 "from conf file - %s. Killing engine",
704 temp_stream_reassembly_toserver_chunk_size_str);
713 long int r = RandomGetWrap();
718 const char *temp_stream_reassembly_toclient_chunk_size_str;
719 if (
ConfGet(
"stream.reassembly.toclient-chunk-size",
720 &temp_stream_reassembly_toclient_chunk_size_str) == 1) {
724 "stream.reassembly.toclient-chunk-size "
725 "from conf file - %s. Killing engine",
726 temp_stream_reassembly_toclient_chunk_size_str);
735 long int r = RandomGetWrap();
741 SCLogConfig(
"stream.reassembly \"toserver-chunk-size\": %"PRIu16,
743 SCLogConfig(
"stream.reassembly \"toclient-chunk-size\": %"PRIu16,
748 if (
ConfGetBool(
"stream.reassembly.raw", &enable_raw) == 1) {
756 SCLogConfig(
"stream.reassembly.raw: %s", enable_raw ?
"enabled" :
"disabled");
760 int liberal_timestamps = 0;
761 if (
ConfGetBool(
"stream.liberal-timestamps", &liberal_timestamps) == 1) {
765 SCLogConfig(
"stream.liberal-timestamps: %s", liberal_timestamps ?
"enabled" :
"disabled");
785 StreamTcpSessionPoolAlloc,
786 StreamTcpSessionPoolInit, NULL,
787 StreamTcpSessionPoolCleanup, NULL);
806 SCLogDebug(
"ssn_pool_cnt %"PRIu64
"", ssn_pool_cnt);
809 static bool IsReassemblyMemcapExceptionPolicyStatsValid(
enum ExceptionPolicy exception_policy)
817 static bool IsStreamTcpSessionMemcapExceptionPolicyStatsValid(
enum ExceptionPolicy policy)
825 static void StreamTcpSsnMemcapExceptionPolicyStatsIncr(
869 if (
unlikely((g_eps_stream_ssn_memcap != UINT64_MAX &&
870 g_eps_stream_ssn_memcap ==
t_pcapcnt))) {
980 #define StreamTcpUpdateLastAck(ssn, stream, ack) { \
981 if (SEQ_GT((ack), (stream)->last_ack)) \
983 SCLogDebug("ssn %p: last_ack set to %"PRIu32", moved %u forward", (ssn), (ack), (ack) - (stream)->last_ack); \
984 if ((SEQ_LEQ((stream)->last_ack, (stream)->next_seq) && SEQ_GT((ack),(stream)->next_seq))) { \
985 SCLogDebug("last_ack just passed next_seq: %u (was %u) > %u", (ack), (stream)->last_ack, (stream)->next_seq); \
987 SCLogDebug("next_seq (%u) <> last_ack now %d", (stream)->next_seq, (int)(stream)->next_seq - (ack)); \
989 (stream)->last_ack = (ack); \
990 StreamTcpSackPruneList((stream)); \
992 SCLogDebug("ssn %p: no update: ack %u, last_ack %"PRIu32", next_seq %u (state %u)", \
993 (ssn), (ack), (stream)->last_ack, (stream)->next_seq, (ssn)->state); \
997 #define StreamTcpAsyncLastAckUpdate(ssn, stream) { \
998 if ((ssn)->flags & STREAMTCP_FLAG_ASYNC) { \
999 if (SEQ_GT((stream)->next_seq, (stream)->last_ack)) { \
1000 uint32_t ack_diff = (stream)->next_seq - (stream)->last_ack; \
1001 (stream)->last_ack += ack_diff; \
1002 SCLogDebug("ssn %p: ASYNC last_ack set to %"PRIu32", moved %u forward", \
1003 (ssn), (stream)->next_seq, ack_diff); \
1008 #define StreamTcpUpdateNextSeq(ssn, stream, seq) { \
1009 (stream)->next_seq = seq; \
1010 SCLogDebug("ssn %p: next_seq %" PRIu32, (ssn), (stream)->next_seq); \
1011 StreamTcpAsyncLastAckUpdate((ssn), (stream)); \
1021 #define StreamTcpUpdateNextWin(ssn, stream, win) { \
1022 uint32_t sacked_size__ = StreamTcpSackedSize((stream)); \
1023 if (SEQ_GT(((win) + sacked_size__), (stream)->next_win)) { \
1024 (stream)->next_win = ((win) + sacked_size__); \
1025 SCLogDebug("ssn %p: next_win set to %"PRIu32, (ssn), (stream)->next_win); \
1033 SCLogDebug(
"ssn %p: (state: %s) Reset received and state changed to "
1037 static bool IsMidstreamExceptionPolicyStatsValid(
enum ExceptionPolicy policy)
1051 static void StreamTcpMidstreamExceptionPolicyStatsIncr(
1060 static int StreamTcpPacketIsRetransmission(
TcpStream *stream,
Packet *p)
1102 static int StreamTcpPacketStateNone(
1107 SCLogDebug(
"RST packet received, no session setup");
1117 SCLogDebug(
"FIN packet received, no session setup");
1123 SCLogDebug(
"FIN packet received, no session setup");
1140 SCLogDebug(
"ssn %p: =~ midstream picked ssn state is now "
1172 SCLogDebug(
"ssn %p: ssn->client.next_win %" PRIu32
", "
1173 "ssn->server.next_win %" PRIu32
"",
1175 SCLogDebug(
"ssn %p: ssn->client.last_ack %" PRIu32
", "
1176 "ssn->server.last_ack %" PRIu32
"",
1184 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1185 "ssn->client.last_ts %" PRIu32
"",
1204 SCLogDebug(
"ssn %p: assuming SACK permitted for both sides", ssn);
1213 SCLogDebug(
"Midstream not enabled, so won't pick up a session");
1218 SCLogDebug(
"Midstream policy not permissive, so won't pick up a session");
1241 SCLogDebug(
"ssn %p: =~ midstream picked ssn state is now "
1242 "TCP_SYN_RECV", ssn);
1273 SCLogDebug(
"ssn %p: wscale enabled. client %u server %u",
1277 SCLogDebug(
"ssn %p: ssn->client.isn %"PRIu32
", ssn->client.next_seq"
1278 " %"PRIu32
", ssn->client.last_ack %"PRIu32
"", ssn,
1281 SCLogDebug(
"ssn %p: ssn->server.isn %"PRIu32
", ssn->server.next_seq"
1282 " %"PRIu32
", ssn->server.last_ack %"PRIu32
"", ssn,
1291 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1292 "ssn->client.last_ts %" PRIu32
"", ssn,
1310 SCLogDebug(
"ssn %p: SYN/ACK with SACK permitted, assuming "
1311 "SACK permitted for both sides", ssn);
1329 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_SYN_SENT", ssn);
1362 SCLogDebug(
"ssn %p: SACK permitted on SYN packet", ssn);
1369 SCLogDebug(
"ssn: %p (TFO) [len: %d] isn %u base_seq %u next_seq %u payload len %u",
1375 SCLogDebug(
"ssn %p: ssn->client.isn %" PRIu32
", "
1376 "ssn->client.next_seq %" PRIu32
", ssn->client.last_ack "
1386 SCLogDebug(
"Midstream not enabled, so won't pick up a session");
1391 SCLogDebug(
"Midstream policy not permissive, so won't pick up a session");
1408 SCLogDebug(
"ssn %p: =~ midstream picked ssn state is now "
1409 "TCP_ESTABLISHED", ssn);
1430 SCLogDebug(
"ssn %p: ssn->client.isn %u, ssn->client.next_seq %u",
1439 SCLogDebug(
"ssn %p: ssn->client.next_win %"PRIu32
", "
1440 "ssn->server.next_win %"PRIu32
"", ssn,
1442 SCLogDebug(
"ssn %p: ssn->client.last_ack %"PRIu32
", "
1443 "ssn->server.last_ack %"PRIu32
"", ssn,
1451 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1452 "ssn->client.last_ts %" PRIu32
"", ssn,
1471 SCLogDebug(
"ssn %p: assuming SACK permitted for both sides", ssn);
1514 StreamTcp3whsSynAckToStateQueue(p, &search);
1522 search.
ts == q->
ts) {
1535 if (StreamTcp3whsFindSynAckBySynAck(ssn, p) != NULL)
1539 SCLogDebug(
"ssn %p: =~ SYN/ACK queue limit reached", ssn);
1545 SCLogDebug(
"ssn %p: =~ SYN/ACK queue failed: stream memcap reached", ssn);
1551 SCLogDebug(
"ssn %p: =~ SYN/ACK queue failed: alloc failed", ssn);
1556 StreamTcp3whsSynAckToStateQueue(p, q);
1604 StreamTcp3whsSynAckToStateQueue(p, &update);
1611 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_SYN_RECV", ssn);
1627 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1628 "ssn->client.last_ts %" PRIu32
"", ssn,
1656 SCLogDebug(
"ssn %p: SACK permitted for session", ssn);
1663 SCLogDebug(
"ssn %p: ssn->server.next_win %" PRIu32
"", ssn,
1665 SCLogDebug(
"ssn %p: ssn->client.next_win %" PRIu32
"", ssn,
1667 SCLogDebug(
"ssn %p: ssn->server.isn %" PRIu32
", "
1668 "ssn->server.next_seq %" PRIu32
", "
1669 "ssn->server.last_ack %" PRIu32
" "
1670 "(ssn->client.last_ack %" PRIu32
")", ssn,
1677 SCLogDebug(
"ssn %p: STREAMTCP_FLAG_4WHS unset, normal SYN/ACK"
1678 " so considering 3WHS", ssn);
1689 static inline bool StateSynSentValidateTimestamp(
TcpSession *ssn,
Packet *p)
1699 if (receiver_stream->
last_ts != 0 && ts_echo != 0 &&
1700 ts_echo != receiver_stream->
last_ts)
1702 SCLogDebug(
"ssn %p: BAD TSECR echo %u recv %u", ssn,
1703 ts_echo, receiver_stream->
last_ts);
1707 if (receiver_stream->
last_ts == 0 && ts_echo != 0) {
1708 SCLogDebug(
"ssn %p: BAD TSECR echo %u recv %u", ssn,
1709 ts_echo, receiver_stream->
last_ts);
1719 memset(q, 0,
sizeof(*q));
1739 SCLogDebug(
"ssn %p: state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq, q->
win,
1745 #if defined(DEBUG_VALIDATION) || defined(DEBUG)
1749 memset(q, 0,
sizeof(*q));
1767 SCLogDebug(
"ssn %p: state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq, q->
win,
1774 #if defined(DEBUG_VALIDATION) || defined(DEBUG)
1781 memset(q, 0,
sizeof(*q));
1799 SCLogDebug(
"ssn %p: state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq, q->
win,
1809 SCLogDebug(
"ssn %p: search state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, s, s->
seq, s->
win,
1813 SCLogDebug(
"ssn %p: queue state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq,
1827 TcpStateQueueInitFromSsnSyn(ssn, &search);
1830 if (ssn->
queue != NULL && StreamTcp3whsFindSyn(ssn, &search) != NULL)
1834 SCLogDebug(
"ssn %p: =~ SYN queue limit reached", ssn);
1840 SCLogDebug(
"ssn %p: =~ SYN queue failed: stream memcap reached", ssn);
1846 SCLogDebug(
"ssn %p: =~ SYN queue failed: alloc failed", ssn);
1893 static int StreamTcpPacketStateSynSent(
1902 SCLogDebug(
"ssn %p: SYN/ACK on SYN_SENT state for packet %" PRIu64, ssn, p->
pcap_cnt);
1909 SCLogDebug(
"ssn %p: ACK mismatch, packet ACK %" PRIu32
" != "
1916 SCLogDebug(
"ssn %p: (TFO) ACK matches next_seq, packet ACK %" PRIu32
" == "
1917 "%" PRIu32
" from stream",
1920 SCLogDebug(
"ssn %p: (TFO) ACK matches ISN+1, packet ACK %" PRIu32
" == "
1921 "%" PRIu32
" from stream",
1929 SCLogDebug(
"ssn %p: (TFO) ACK mismatch, packet ACK %" PRIu32
" != "
1938 const bool ts_mismatch = !StateSynSentValidateTimestamp(ssn, p);
1943 TcpStateQueueInitFromPktSynAck(p, &search);
1945 const TcpStateQueue *q = StreamTcp3whsFindSyn(ssn, &search);
1951 SCLogDebug(
"ssn %p: found queued SYN state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u",
1955 StreamTcp3whsStoreSynApplyToSsn(ssn, q);
1965 StreamTcp3wsFreeQueue(ssn);
1967 StreamTcp3whsSynAckUpdate(ssn, p, NULL);
1974 SCLogDebug(
"ssn %p: SYN/ACK received in the wrong direction", ssn);
1978 SCLogDebug(
"ssn %p: SYN/ACK received on 4WHS session", ssn);
1985 SCLogDebug(
"ssn %p: 4WHS ACK mismatch, packet ACK %" PRIu32
""
1986 " != %" PRIu32
" from stream",
1996 SCLogDebug(
"ssn %p: 4WHS SEQ mismatch, packet SEQ %" PRIu32
""
1997 " != %" PRIu32
" from *first* SYN pkt",
2004 SCLogDebug(
"ssn %p: =~ 4WHS ssn state is now TCP_SYN_RECV", ssn);
2018 SCLogDebug(
"ssn %p: 4WHS ssn->client.last_ts %" PRIu32
" "
2019 "ssn->server.last_ts %" PRIu32
"",
2044 SCLogDebug(
"ssn %p: SACK permitted for 4WHS session", ssn);
2051 SCLogDebug(
"ssn %p: 4WHS ssn->client.isn %" PRIu32
", "
2052 "ssn->client.next_seq %" PRIu32
", "
2053 "ssn->client.last_ack %" PRIu32
" "
2054 "(ssn->server.last_ack %" PRIu32
")",
2063 if (StateSynSentValidateTimestamp(ssn, p) ==
false) {
2071 if (!StreamTcpValidateRst(ssn, p))
2077 SCLogDebug(
"ssn->server.flags |= STREAMTCP_STREAM_FLAG_RST_RECV");
2079 StreamTcpCloseSsnWithReset(p, ssn);
2080 StreamTcp3wsFreeQueue(ssn);
2084 SCLogDebug(
"ssn->client.flags |= STREAMTCP_STREAM_FLAG_RST_RECV");
2085 StreamTcpCloseSsnWithReset(p, ssn);
2086 StreamTcp3wsFreeQueue(ssn);
2094 SCLogDebug(
"ssn %p: SYN packet on state SYN_SENT... resent", ssn);
2096 SCLogDebug(
"ssn %p: SYN packet on state SYN_SENT... resent of "
2109 SCLogDebug(
"ssn %p: STREAMTCP_FLAG_4WHS flag set", ssn);
2146 SCLogDebug(
"ssn %p: 4WHS ssn->server.isn %" PRIu32
", "
2147 "ssn->server.next_seq %" PRIu32
", "
2148 "ssn->server.last_ack %"PRIu32
"", ssn,
2151 SCLogDebug(
"ssn %p: 4WHS ssn->client.isn %" PRIu32
", "
2152 "ssn->client.next_seq %" PRIu32
", "
2153 "ssn->client.last_ack %"PRIu32
"", ssn,
2162 TcpStateQueueInitFromPktSyn(p, &syn_pkt);
2163 TcpStateQueueInitFromSsnSyn(ssn, &syn_ssn);
2165 if (memcmp(&syn_pkt, &syn_ssn,
sizeof(
TcpStateQueue)) != 0) {
2167 StreamTcp3whsStoreSyn(ssn, p);
2168 SCLogDebug(
"ssn %p: Retransmitted SYN. Updating ssn from packet %" PRIu64
2169 ". Stored previous state",
2172 StreamTcp3whsStoreSynApplyToSsn(ssn, &syn_pkt);
2188 SCLogDebug(
"ssn %p: SEQ mismatch, packet SEQ %" PRIu32
" != "
2196 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2197 StreamTcp3wsFreeQueue(ssn);
2210 SCLogDebug(
"ssn %p: synsent => Asynchronous stream, packet SEQ"
2211 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2212 "ssn->client.next_seq %" PRIu32
""
2261 static int StreamTcpPacketStateSynRecv(
2267 if (!StreamTcpValidateRst(ssn, p))
2284 SCLogDebug(
"Detection evasion has been attempted, so"
2285 " not resetting the connection !!");
2293 SCLogDebug(
"Detection evasion has been attempted, so"
2294 " not resetting the connection !!");
2300 StreamTcpCloseSsnWithReset(p, ssn);
2303 StreamTcpHandleTimestamp(ssn, p);
2310 if (!StreamTcpValidateTimestamp(ssn, p))
2314 if ((StreamTcpHandleFin(
tv, stt, ssn, p)) == -1)
2319 SCLogDebug(
"ssn %p: SYN/ACK packet on state SYN_RECV. resent", ssn);
2322 SCLogDebug(
"ssn %p: SYN/ACK-pkt to server in SYN_RECV state", ssn);
2331 SCLogDebug(
"ssn %p: ACK mismatch, packet ACK %" PRIu32
" != "
2342 SCLogDebug(
"ssn %p: SEQ mismatch, packet SEQ %" PRIu32
" != "
2346 if (StreamTcp3whsQueueSynAck(ssn, p) == -1)
2348 SCLogDebug(
"ssn %p: queued different SYN/ACK", ssn);
2352 SCLogDebug(
"ssn %p: SYN packet on state SYN_RECV... resent", ssn);
2355 SCLogDebug(
"ssn %p: SYN-pkt to client in SYN_RECV state", ssn);
2362 SCLogDebug(
"ssn %p: SYN with different SEQ on SYN_RECV state", ssn);
2370 SCLogDebug(
"ssn %p: checking ACK against queued SYN/ACKs", ssn);
2373 SCLogDebug(
"ssn %p: here we update state against queued SYN/ACK", ssn);
2374 StreamTcp3whsSynAckUpdate(ssn, p, q);
2376 SCLogDebug(
"ssn %p: none found, now checking ACK against original SYN/ACK (state)", ssn);
2386 if (!(StreamTcpValidateTimestamp(ssn, p))) {
2392 SCLogDebug(
"ssn %p: ACK received on 4WHS session",ssn);
2395 SCLogDebug(
"ssn %p: 4WHS wrong seq nr on packet", ssn);
2400 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
2401 SCLogDebug(
"ssn %p: 4WHS invalid ack nr on packet", ssn);
2407 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
2408 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
2412 StreamTcpHandleTimestamp(ssn, p);
2421 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2425 SCLogDebug(
"ssn %p: ssn->client.next_win %" PRIu32
", "
2426 "ssn->client.last_ack %"PRIu32
"", ssn,
2431 bool ack_indicates_missed_3whs_ack_packet =
false;
2441 SCLogDebug(
"ssn %p: ACK received on midstream SYN/ACK "
2442 "pickup session",ssn);
2445 SCLogDebug(
"ssn %p: ACK received on TFO session",ssn);
2463 SCLogDebug(
"ssn %p: possible data injection", ssn);
2468 SCLogDebug(
"ssn %p: ACK received in the wrong direction",
2473 ack_indicates_missed_3whs_ack_packet =
true;
2477 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ %" PRIu32
""
2490 StreamTcpHandleTimestamp(ssn, p);
2514 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2531 StreamTcpHandleTimestamp(ssn, p);
2544 SCLogDebug(
"ssn %p: synrecv => Asynchronous stream, packet SEQ"
2545 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2546 "ssn->server.next_seq %" PRIu32
2551 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2560 SCLogDebug(
"ssn %p: wrong ack nr on packet, possible evasion!!",
2570 SCLogDebug(
"ssn %p: ACK for missing data", ssn);
2573 StreamTcpHandleTimestamp(ssn, p);
2579 SCLogDebug(
"ssn %p: ACK for missing data: ssn->server.next_seq %u", ssn,
2589 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2598 SCLogDebug(
"ssn %p: ACK for missing data", ssn);
2601 StreamTcpHandleTimestamp(ssn, p);
2623 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2628 }
else if ((ack_indicates_missed_3whs_ack_packet ||
2632 if (ack_indicates_missed_3whs_ack_packet) {
2633 SCLogDebug(
"ssn %p: packet fits perfectly after a missed 3whs-ACK", ssn);
2635 SCLogDebug(
"ssn %p: (TFO) expected packet fits perfectly after SYN/ACK", ssn);
2644 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2649 SCLogDebug(
"ssn %p: wrong seq nr on packet", ssn);
2655 SCLogDebug(
"ssn %p: ssn->server.next_win %" PRIu32
", "
2656 "ssn->server.last_ack %"PRIu32
"", ssn,
2678 static int HandleEstablishedPacketToServer(
2681 SCLogDebug(
"ssn %p: =+ pkt (%" PRIu32
") is to server: SEQ %" PRIu32
","
2682 "ACK %" PRIu32
", WIN %"PRIu16
"", ssn, p->
payload_len,
2688 SCLogDebug(
"ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn);
2691 }
else if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
2692 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
2701 SCLogDebug(
"ssn %p: pkt is keep alive", ssn);
2706 SCLogDebug(
"ssn %p: server => Asynchronous stream, packet SEQ"
2707 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2708 " ssn->client.last_ack %" PRIu32
", ssn->client.next_win"
2709 "%" PRIu32
"(%" PRIu32
")",
2720 SCLogDebug(
"ssn %p: server => Asynchronous stream, packet SEQ."
2721 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2722 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2736 SCLogDebug(
"ssn %p: server => Asynchronous stream, packet SEQ"
2737 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2738 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2755 SCLogDebug(
"ssn %p: PKT SEQ %" PRIu32
" payload_len %" PRIu16
2756 " before last_ack %" PRIu32
", after next_seq %" PRIu32
":"
2757 " acked data that we haven't seen before",
2761 SCLogDebug(
"ssn %p: server => SEQ before last_ack, packet SEQ"
2762 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2763 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2769 SCLogDebug(
"ssn %p: rejecting because pkt before last_ack", ssn);
2775 int zerowindowprobe = 0;
2778 SCLogDebug(
"ssn %p: zero window probe", ssn);
2779 zerowindowprobe = 1;
2789 if (zerowindowprobe) {
2790 SCLogDebug(
"ssn %p: zero window probe, skipping oow check", ssn);
2794 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->client.next_win "
2798 SCLogDebug(
"ssn %p: ssn->server.window %"PRIu32
"", ssn,
2814 StreamTcpHandleTimestamp(ssn, p);
2826 SCLogDebug(
"ssn %p: toserver => SEQ out of window, packet SEQ "
2827 "%" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2828 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2834 StreamTcpSackedSize(&ssn->
client));
2854 static int HandleEstablishedPacketToClient(
2857 SCLogDebug(
"ssn %p: =+ pkt (%" PRIu32
") is to client: SEQ %" PRIu32
","
2858 " ACK %" PRIu32
", WIN %"PRIu16
"", ssn, p->
payload_len,
2864 SCLogDebug(
"ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn);
2867 }
else if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
2868 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
2882 SCLogDebug(
"ssn %p: adjusted midstream ssn->server.next_win to "
2889 SCLogDebug(
"ssn %p: pkt is keep alive", ssn);
2895 SCLogDebug(
"ssn %p: client => Asynchronous stream, packet SEQ"
2896 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2897 " ssn->client.last_ack %" PRIu32
", ssn->client.next_win"
2898 " %" PRIu32
"(%" PRIu32
")",
2911 SCLogDebug(
"ssn %p: PKT SEQ %" PRIu32
" payload_len %" PRIu16
2912 " before last_ack %" PRIu32
", after next_seq %" PRIu32
":"
2913 " acked data that we haven't seen before",
2917 SCLogDebug(
"ssn %p: PKT SEQ %"PRIu32
" payload_len %"PRIu16
2918 " before last_ack %"PRIu32
". next_seq %"PRIu32,
2925 int zerowindowprobe = 0;
2928 SCLogDebug(
"ssn %p: zero window probe", ssn);
2929 zerowindowprobe = 1;
2940 if (zerowindowprobe) {
2941 SCLogDebug(
"ssn %p: zero window probe, skipping oow check", ssn);
2945 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->server.next_win "
2948 SCLogDebug(
"ssn %p: ssn->client.window %"PRIu32
"", ssn,
2961 StreamTcpHandleTimestamp(ssn, p);
2970 SCLogDebug(
"ssn %p: client => SEQ out of window, packet SEQ"
2971 "%" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2972 " ssn->server.last_ack %" PRIu32
", ssn->server.next_win "
2995 static inline uint32_t StreamTcpResetGetMaxAck(
TcpStream *stream, uint32_t
seq)
3001 if (
SEQ_GT(tail_seq, ack)) {
3009 static bool StreamTcpPacketIsZeroWindowProbeAck(
const TcpSession *ssn,
const Packet *p)
3034 if (pkt_win != rcv->
window)
3041 SCLogDebug(
"ssn %p: packet %" PRIu64
" is a Zero Window Probe ACK", ssn, p->
pcap_cnt);
3048 static bool StreamTcpPacketIsDupAck(
const TcpSession *ssn,
const Packet *p)
3067 if (pkt_win == 0 || rcv->
window == 0)
3069 if (pkt_win != rcv->
window)
3077 SCLogDebug(
"ssn %p: packet:%" PRIu64
" seq:%u ack:%u win:%u snd %u:%u:%u rcv %u:%u:%u", ssn,
3151 static int StreamTcpPacketIsSpuriousRetransmission(
const TcpSession *ssn,
Packet *p)
3167 "ssn %p: spurious retransmission; packet entirely before base_seq: SEQ %u(%u) "
3168 "last_ack %u base_seq %u",
3177 SCLogDebug(
"ssn %p: spurious retransmission; packet entirely before last_ack: SEQ %u(%u) "
3184 SCLogDebug(
"ssn %p: NOT spurious retransmission; packet NOT entirely before last_ack: SEQ "
3185 "%u(%u) last_ack %u, base_seq %u",
3202 static int StreamTcpPacketStateEstablished(
3208 if (!StreamTcpValidateRst(ssn, p))
3212 StreamTcpCloseSsnWithReset(p, ssn);
3216 SCLogDebug(
"ssn %p: ssn->server.next_seq %" PRIu32
"", ssn,
3228 StreamTcpHandleTimestamp(ssn, p);
3232 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3240 StreamTcpCloseSsnWithReset(p, ssn);
3245 SCLogDebug(
"ssn %p: ssn->server.next_seq %" PRIu32
"", ssn,
3257 StreamTcpHandleTimestamp(ssn, p);
3261 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3272 if (!StreamTcpValidateTimestamp(ssn, p))
3277 " %" PRIu32
", last ACK %" PRIu32
", next win %"PRIu32
","
3282 if ((StreamTcpHandleFin(
tv, stt, ssn, p)) == -1)
3287 SCLogDebug(
"ssn %p: SYN/ACK packet on state ESTABLISHED... resent",
3291 SCLogDebug(
"ssn %p: SYN/ACK-pkt to server in ESTABLISHED state", ssn);
3300 SCLogDebug(
"ssn %p: ACK mismatch, packet ACK %" PRIu32
" != "
3311 SCLogDebug(
"ssn %p: SEQ mismatch, packet SEQ %" PRIu32
" != "
3325 SCLogDebug(
"ssn %p: SYN/ACK packet on state ESTABLISHED... resent. "
3326 "Likely due server not receiving final ACK in 3whs", ssn);
3330 SCLogDebug(
"ssn %p: SYN packet on state ESTABLISHED... resent", ssn);
3332 SCLogDebug(
"ssn %p: SYN-pkt to client in EST state", ssn);
3339 SCLogDebug(
"ssn %p: SYN with different SEQ on SYN_RECV state", ssn);
3360 if (!StreamTcpValidateTimestamp(ssn, p))
3366 HandleEstablishedPacketToServer(
tv, ssn, p, stt);
3368 SCLogDebug(
"ssn %p: next SEQ %" PRIu32
", last ACK %" PRIu32
","
3369 " next win %" PRIu32
", win %" PRIu32
"", ssn,
3376 SCLogDebug(
"3whs is now confirmed by server");
3380 HandleEstablishedPacketToClient(
tv, ssn, p, stt);
3382 SCLogDebug(
"ssn %p: next SEQ %" PRIu32
", last ACK %" PRIu32
","
3383 " next win %" PRIu32
", win %" PRIu32
"", ssn,
3409 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ %" PRIu32
","
3413 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3414 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3426 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
" != "
3440 SCLogDebug(
"ssn %p: state changed to TCP_CLOSE_WAIT", ssn);
3445 SCLogDebug(
"ssn %p: ssn->client.next_seq %" PRIu32
"", ssn,
3450 StreamTcpHandleTimestamp(ssn, p);
3463 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK %" PRIu32
"",
3466 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ %" PRIu32
", "
3470 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3471 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3483 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
" != "
3484 "%" PRIu32
" from stream (last_ack %u win %u = %u)", ssn,
TCP_GET_SEQ(p),
3492 SCLogDebug(
"ssn %p: state changed to TCP_FIN_WAIT1", ssn);
3501 StreamTcpHandleTimestamp(ssn, p);
3514 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK %" PRIu32
"",
3534 static int StreamTcpPacketStateFinWait1(
3540 if (!StreamTcpValidateRst(ssn, p))
3543 StreamTcpCloseSsnWithReset(p, ssn);
3554 StreamTcpHandleTimestamp(ssn, p);
3567 StreamTcpHandleTimestamp(ssn, p);
3575 if (!StreamTcpValidateTimestamp(ssn, p))
3580 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3581 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3583 int retransmission = 0;
3585 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3586 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3592 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3593 " != %" PRIu32
" from stream", ssn,
3599 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3600 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3605 if (!retransmission) {
3607 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
3613 StreamTcpHandleTimestamp(ssn, p);
3629 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3633 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3634 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3636 int retransmission = 0;
3638 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3639 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3645 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3651 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3652 " != %" PRIu32
" from stream", ssn,
3658 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3659 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3665 StreamTcpHandleTimestamp(ssn, p);
3668 if (!retransmission) {
3670 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
3688 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3695 if (!StreamTcpValidateTimestamp(ssn, p))
3700 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3701 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3703 int retransmission = 0;
3705 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3706 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3712 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3713 " != %" PRIu32
" from stream", ssn,
3719 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3720 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3725 if (!retransmission) {
3727 SCLogDebug(
"ssn %p: state changed to TCP_CLOSING", ssn);
3733 StreamTcpHandleTimestamp(ssn, p);
3750 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3754 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3755 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3758 int retransmission = 0;
3760 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3761 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3767 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3768 " != %" PRIu32
" from stream", ssn,
3774 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3775 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3780 if (!retransmission) {
3782 SCLogDebug(
"ssn %p: state changed to TCP_CLOSING", ssn);
3788 StreamTcpHandleTimestamp(ssn, p);
3805 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3810 SCLogDebug(
"ssn (%p): SYN pkt on FinWait1", ssn);
3816 if (!StreamTcpValidateTimestamp(ssn, p))
3821 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3822 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3824 int retransmission = 0;
3826 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3827 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3832 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3833 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3841 }
else if (!retransmission) {
3845 SCLogDebug(
"ssn %p: seq %" PRIu32
" in window, ssn->client.next_win "
3852 SCLogDebug(
"ssn %p: state changed to TCP_FIN_WAIT2", ssn);
3855 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3856 " != %" PRIu32
" from stream",
3868 StreamTcpHandleTimestamp(ssn, p);
3889 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3895 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3896 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3899 int retransmission = 0;
3901 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3902 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3907 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3908 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3913 if (!retransmission) {
3917 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->server.next_win "
3922 SCLogDebug(
"ssn %p: state changed to TCP_FIN_WAIT2", ssn);
3925 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3926 " != %" PRIu32
" from stream", ssn,
3936 StreamTcpHandleTimestamp(ssn, p);
3957 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3978 static int StreamTcpPacketStateFinWait2(
3984 if (!StreamTcpValidateRst(ssn, p))
3987 StreamTcpCloseSsnWithReset(p, ssn);
3998 StreamTcpHandleTimestamp(ssn, p);
4011 StreamTcpHandleTimestamp(ssn, p);
4019 if (!StreamTcpValidateTimestamp(ssn, p))
4024 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4025 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4027 int retransmission = 0;
4034 }
else if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4035 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4042 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ "
4043 "%" PRIu32
" != %" PRIu32
" from stream", ssn,
4049 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4050 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4055 if (!retransmission) {
4057 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
4067 StreamTcpHandleTimestamp(ssn, p);
4080 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4084 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4085 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4087 int retransmission = 0;
4094 }
else if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4095 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4102 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ "
4103 "%" PRIu32
" != %" PRIu32
" from stream", ssn,
4109 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4110 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4115 if (!retransmission) {
4117 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
4123 StreamTcpHandleTimestamp(ssn, p);
4135 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4141 SCLogDebug(
"ssn (%p): SYN pkt on FinWait2", ssn);
4147 if (!StreamTcpValidateTimestamp(ssn, p))
4152 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4153 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4155 int retransmission = 0;
4157 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4158 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4163 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4164 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4169 if (!retransmission) {
4173 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->client.next_win "
4177 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4178 " != %" PRIu32
" from stream", ssn,
4188 StreamTcpHandleTimestamp(ssn, p);
4204 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4208 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4209 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4211 int retransmission = 0;
4213 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4214 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4219 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4220 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4225 if (!retransmission) {
4229 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->server.next_win "
4232 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4233 " != %" PRIu32
" from stream", ssn,
4243 StreamTcpHandleTimestamp(ssn, p);
4259 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4280 static int StreamTcpPacketStateClosing(
4286 if (!StreamTcpValidateRst(ssn, p))
4289 StreamTcpCloseSsnWithReset(p, ssn);
4300 StreamTcpHandleTimestamp(ssn, p);
4313 StreamTcpHandleTimestamp(ssn, p);
4320 SCLogDebug(
"ssn (%p): SYN pkt on Closing", ssn);
4326 if (!StreamTcpValidateTimestamp(ssn, p))
4331 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4332 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4334 int retransmission = 0;
4335 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4336 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4342 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4343 " != %" PRIu32
" from stream", ssn,
4349 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4350 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4355 if (!retransmission) {
4357 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
4363 StreamTcpHandleTimestamp(ssn, p);
4373 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4377 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4378 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4380 int retransmission = 0;
4381 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4382 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4388 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4389 " != %" PRIu32
" from stream", ssn,
4395 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4396 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4401 if (!retransmission) {
4403 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
4409 StreamTcpHandleTimestamp(ssn, p);
4420 SCLogDebug(
"StreamTcpPacketStateClosing (%p): =+ next SEQ "
4421 "%" PRIu32
", last ACK %" PRIu32
"", ssn,
4441 static int StreamTcpPacketStateCloseWait(
4449 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4450 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4453 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4454 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4459 if (!StreamTcpValidateRst(ssn, p))
4462 StreamTcpCloseSsnWithReset(p, ssn);
4473 StreamTcpHandleTimestamp(ssn, p);
4486 StreamTcpHandleTimestamp(ssn, p);
4494 if (!StreamTcpValidateTimestamp(ssn, p))
4499 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4500 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4503 int retransmission = 0;
4504 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4505 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4510 if (!retransmission) {
4514 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4515 " != %" PRIu32
" from stream", ssn,
4522 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4523 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4530 if (!retransmission)
4534 StreamTcpHandleTimestamp(ssn, p);
4546 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4550 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4551 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4554 int retransmission = 0;
4555 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4556 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4561 if (!retransmission) {
4565 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4566 " != %" PRIu32
" from stream", ssn,
4573 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4574 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4579 if (!retransmission) {
4581 SCLogDebug(
"ssn %p: state changed to TCP_LAST_ACK", ssn);
4587 StreamTcpHandleTimestamp(ssn, p);
4599 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4605 SCLogDebug(
"ssn (%p): SYN pkt on CloseWait", ssn);
4611 if (!StreamTcpValidateTimestamp(ssn, p))
4616 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4617 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4620 int retransmission = 0;
4621 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4622 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4628 SCLogDebug(
"ssn %p: -> retransmission", ssn);
4634 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4635 " != %" PRIu32
" from stream", ssn,
4641 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4642 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4647 if (!retransmission) {
4652 StreamTcpHandleTimestamp(ssn, p);
4666 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4670 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4671 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4673 int retransmission = 0;
4674 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4675 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4681 SCLogDebug(
"ssn %p: -> retransmission", ssn);
4687 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4688 " != %" PRIu32
" from stream", ssn,
4694 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4695 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4700 if (!retransmission) {
4705 StreamTcpHandleTimestamp(ssn, p);
4719 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4740 static int StreamTcpPacketStateLastAck(
4746 if (!StreamTcpValidateRst(ssn, p))
4749 StreamTcpCloseSsnWithReset(p, ssn);
4760 StreamTcpHandleTimestamp(ssn, p);
4773 StreamTcpHandleTimestamp(ssn, p);
4781 SCLogDebug(
"ssn (%p): FIN pkt on LastAck", ssn);
4784 SCLogDebug(
"ssn (%p): SYN pkt on LastAck", ssn);
4790 if (!StreamTcpValidateTimestamp(ssn, p))
4795 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4796 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4799 int retransmission = 0;
4800 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4801 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4806 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4807 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4812 if (!retransmission) {
4814 SCLogDebug(
"ssn %p: not updating state as packet is before next_seq", ssn);
4816 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4817 " != %" PRIu32
" from stream", ssn,
4823 SCLogDebug(
"ssn %p: state changed to TCP_CLOSED", ssn);
4830 StreamTcpHandleTimestamp(ssn, p);
4841 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4862 static int StreamTcpPacketStateTimeWait(
4868 if (!StreamTcpValidateRst(ssn, p))
4871 StreamTcpCloseSsnWithReset(p, ssn);
4882 StreamTcpHandleTimestamp(ssn, p);
4895 StreamTcpHandleTimestamp(ssn, p);
4905 SCLogDebug(
"ssn (%p): SYN pkt on TimeWait", ssn);
4911 if (!StreamTcpValidateTimestamp(ssn, p))
4916 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4917 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4919 int retransmission = 0;
4920 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4921 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4926 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4927 " != %" PRIu32
" from stream", ssn,
4933 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4934 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4939 if (!retransmission) {
4941 SCLogDebug(
"ssn %p: state changed to TCP_CLOSED", ssn);
4947 StreamTcpHandleTimestamp(ssn, p);
4958 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4962 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4963 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4965 int retransmission = 0;
4966 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4967 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4973 SCLogDebug(
"ssn %p: -> retransmission", ssn);
4976 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4977 " != %" PRIu32
" from stream", ssn,
4984 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4985 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4990 if (!retransmission) {
4992 SCLogDebug(
"ssn %p: state changed to TCP_CLOSED", ssn);
4998 StreamTcpHandleTimestamp(ssn, p);
5009 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
5021 static int StreamTcpPacketStateClosed(
5031 TcpStream *stream = NULL, *ostream = NULL;
5048 if (StreamTcpStateDispatch(
tv, p, stt, ssn, ssn->
pstate) < 0)
5076 SCLogDebug(
"regular packet %"PRIu64
" from same sender as "
5077 "the previous RST. Looks like it injected!", p->
pcap_cnt);
5108 TcpStream *stream = NULL, *ostream = NULL;
5119 if (ack == ostream->last_ack &&
seq == (stream->
next_seq - 1)) {
5135 TcpStream *stream = NULL, *ostream = NULL;
5164 if (pkt_win != ostream->window)
5173 SCLogDebug(
"seq %u (%u), ack %u (%u) FLAG_KEEPALIVE: %s",
seq, stream->
next_seq, ack, ostream->last_ack,
5203 TcpStream *stream = NULL, *ostream = NULL;
5235 if (pkt_win == ostream->window)
5238 if (ack == ostream->last_ack &&
seq == stream->
next_seq) {
5253 TcpStream *stream = NULL, *ostream = NULL;
5277 SCLogDebug(
"%"PRIu64
", seq %u ack %u stream->next_seq %u ostream->next_seq %u",
5305 TcpStream *stream = NULL, *ostream = NULL;
5332 if (pkt_win < ostream->window) {
5333 uint32_t diff = ostream->window - pkt_win;
5335 SEQ_GT(ack, ostream->next_seq) &&
5338 SCLogDebug(
"%"PRIu64
", pkt_win %u, stream win %u, diff %u, dsize %u",
5340 SCLogDebug(
"%"PRIu64
", pkt_win %u, stream win %u",
5341 p->
pcap_cnt, pkt_win, ostream->window);
5342 SCLogDebug(
"%"PRIu64
", seq %u ack %u ostream->next_seq %u ostream->last_ack %u, ostream->next_win %u, diff %u (%u)",
5343 p->
pcap_cnt,
seq, ack, ostream->next_seq, ostream->last_ack, ostream->next_win,
5344 ostream->next_seq - ostream->last_ack, stream->
next_seq - stream->
last_ack);
5351 uint32_t adiff = ack - ostream->last_ack;
5352 if (((pkt_win > 1024) && (diff > (adiff + 32))) ||
5353 ((pkt_win <= 1024) && (diff > adiff)))
5355 SCLogDebug(
"pkt ACK %u is %u bytes beyond last_ack %u, shrinks window by %u "
5356 "(allowing 32 bytes extra): pkt WIN %u", ack, adiff, ostream->last_ack, diff, pkt_win);
5357 SCLogDebug(
"%u - %u = %u (state %u)", diff, adiff, diff - adiff, ssn->
state);
5372 static inline int StreamTcpStateDispatch(
5380 SCLogDebug(
"packet received on TCP_SYN_SENT state");
5381 if (StreamTcpPacketStateSynSent(
tv, p, stt, ssn)) {
5386 SCLogDebug(
"packet received on TCP_SYN_RECV state");
5387 if (StreamTcpPacketStateSynRecv(
tv, p, stt, ssn)) {
5392 SCLogDebug(
"packet received on TCP_ESTABLISHED state");
5393 if (StreamTcpPacketStateEstablished(
tv, p, stt, ssn)) {
5398 SCLogDebug(
"packet received on TCP_FIN_WAIT1 state");
5399 if (StreamTcpPacketStateFinWait1(
tv, p, stt, ssn)) {
5404 SCLogDebug(
"packet received on TCP_FIN_WAIT2 state");
5405 if (StreamTcpPacketStateFinWait2(
tv, p, stt, ssn)) {
5410 SCLogDebug(
"packet received on TCP_CLOSING state");
5411 if (StreamTcpPacketStateClosing(
tv, p, stt, ssn)) {
5416 SCLogDebug(
"packet received on TCP_CLOSE_WAIT state");
5417 if (StreamTcpPacketStateCloseWait(
tv, p, stt, ssn)) {
5422 SCLogDebug(
"packet received on TCP_LAST_ACK state");
5423 if (StreamTcpPacketStateLastAck(
tv, p, stt, ssn)) {
5428 SCLogDebug(
"packet received on TCP_TIME_WAIT state");
5429 if (StreamTcpPacketStateTimeWait(
tv, p, stt, ssn)) {
5435 SCLogDebug(
"packet received on closed state");
5437 if (StreamTcpPacketStateClosed(
tv, p, stt, ssn)) {
5443 SCLogDebug(
"packet received on default state");
5493 SCLogDebug(
"ssn %p: removing ASYNC flag as we have packets on both sides", ssn);
5507 if (StreamTcpCheckFlowDrops(p) == 1) {
5517 if (StreamTcpPacketStateNone(
tv, p, stt, ssn) == -1) {
5545 if (StreamTcpPacketIsKeepAlive(ssn, p) == 1) {
5548 if (StreamTcpPacketIsKeepAliveACK(ssn, p) == 1) {
5549 StreamTcpClearKeepAliveFlag(ssn, p);
5552 StreamTcpClearKeepAliveFlag(ssn, p);
5554 const bool is_zwp_ack = StreamTcpPacketIsZeroWindowProbeAck(ssn, p);
5565 if (StreamTcpPacketIsDupAck(ssn, p) ==
true) {
5572 if (StreamTcpPacketIsFinShutdownAck(ssn, p) == 0) {
5573 if (StreamTcpPacketIsWindowUpdate(ssn, p) == 0) {
5574 if (StreamTcpPacketIsBadWindowUpdate(ssn,p))
5576 if (StreamTcpPacketIsOutdatedAck(ssn, p))
5581 int ret = StreamTcpPacketIsSpuriousRetransmission(ssn, p);
5590 if (StreamTcpStateDispatch(
tv, p, stt, ssn, ssn->
state) < 0)
5594 StreamTcpPacketCheckPostRst(ssn, p);
5643 SCLogDebug(
"bypass as stream is dead and we have no rules");
5656 if (StreamTcpInlineDropInvalid()) {
5660 DecodeSetNoPayloadInspectionFlag(p);
5674 static inline int StreamTcpValidateChecksum(
Packet *p)
5684 (uint16_t *)p->
tcph,
5690 (uint16_t *)p->
tcph,
5712 static int TcpSessionPacketIsStreamStarter(
const Packet *p)
5741 SCLogDebug(
"steam starter packet %" PRIu64
", ssn %p null. Reuse.", p->
pcap_cnt, ssn);
5746 ", ssn %p. STREAMTCP_FLAG_TFO_DATA_IGNORED set. Reuse.",
5751 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->
pcap_cnt, ssn);
5755 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5758 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5761 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5771 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5774 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5777 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5790 static int TcpSessionReuseDoneEnoughSynAck(
const Packet *p,
const Flow *f,
const TcpSession *ssn)
5794 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p null. No reuse.", p->
pcap_cnt, ssn);
5798 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->
pcap_cnt, ssn);
5802 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5805 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5808 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5818 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5821 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5824 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5841 return TcpSessionReuseDoneEnoughSyn(p, f, ssn);
5846 return TcpSessionReuseDoneEnoughSynAck(p, f, ssn);
5855 if (p->
proto == IPPROTO_TCP && p->
tcph != NULL) {
5856 if (TcpSessionPacketIsStreamStarter(p) == 1) {
5857 if (TcpSessionReuseDoneEnough(p, f, tcp_ssn) == 1) {
5884 HandleThreadId(
tv, p, stt);
5890 if (StreamTcpValidateChecksum(p) == 0) {
5916 *data = (
void *)stt;
5925 IsStreamTcpSessionMemcapExceptionPolicyStatsValid);
5934 "tcp.midstream_exception_policy.", IsMidstreamExceptionPolicyStatsValid);
5938 "tcp.midstream_exception_policy.", IsMidstreamExceptionPolicyStatsValid);
5953 "tcp.reassembly_exception_policy.", IsReassemblyMemcapExceptionPolicyStatsValid);
5966 SCLogDebug(
"StreamTcp thread specific ctx online at %p, reassembly ctx %p",
5975 StreamTcpSessionPoolAlloc,
5976 StreamTcpSessionPoolInit, NULL,
5977 StreamTcpSessionPoolCleanup, NULL);
5987 SCLogError(
"failed to setup/expand stream session pool. Expand stream.memcap?");
6038 if (!StreamTcpValidateTimestamp(ssn, p)) {
6068 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
6081 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
6094 receiver_stream = &ssn->
server;
6096 receiver_stream = &ssn->
client;
6098 SCLogDebug(
"ssn %p: setting STREAMTCP_STREAM_FLAG_RST_RECV on receiver stream", ssn);
6118 switch (os_policy) {
6122 SCLogDebug(
"reset is Valid! Packet SEQ: %" PRIu32
"",
6126 SCLogDebug(
"reset is not Valid! Packet SEQ: %" PRIu32
" "
6133 SCLogDebug(
"reset is valid! Packet SEQ: %" PRIu32
"",
6137 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" "
6154 SCLogDebug(
"reset is Valid! Packet SEQ: %" PRIu32
"",
6159 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" and"
6171 SCLogDebug(
"reset is Valid! Packet SEQ: %" PRIu32
"",
6176 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" and"
6195 SCLogDebug(
"reset is valid! Packet SEQ: %" PRIu32
"",
6199 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" "
6206 SCLogDebug(
"reset is valid! Packet SEQ: %" PRIu32
" Stream %u",
6210 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" and"
6211 " client SEQ: %" PRIu32
"",
6242 uint8_t check_ts = 1;
6245 sender_stream = &ssn->
client;
6246 receiver_stream = &ssn->
server;
6248 sender_stream = &ssn->
server;
6249 receiver_stream = &ssn->
client;
6260 uint32_t last_pkt_ts = sender_stream->
last_pkt_ts;
6261 uint32_t last_ts = sender_stream->
last_ts;
6311 SCLogDebug(
"ts %"PRIu32
", last_ts %"PRIu32
"",
ts, last_ts);
6315 result = (int32_t) ((
ts - last_ts) + 1);
6317 result = (int32_t) (
ts - last_ts);
6320 SCLogDebug(
"result %" PRIi32
", p->ts(secs) %" PRIuMAX
"", result,
6323 if (last_pkt_ts == 0 &&
6331 "%" PRIu32
" p->tcpvars->ts %" PRIu32
" result "
6332 "%" PRId32
"", last_ts,
ts, result);
6335 }
else if ((sender_stream->
last_ts != 0) &&
6337 SCLogDebug(
"packet is not valid last_pkt_ts "
6338 "%" PRIu32
" p->ts(sec) %" PRIu32
"",
6350 SCLogDebug(
"timestamp considered valid anyway");
6382 uint8_t check_ts = 1;
6385 sender_stream = &ssn->
client;
6386 receiver_stream = &ssn->
server;
6388 sender_stream = &ssn->
server;
6389 receiver_stream = &ssn->
client;
6457 result = (int32_t) ((
ts - sender_stream->
last_ts) + 1);
6459 result = (int32_t) (
ts - sender_stream->
last_ts);
6462 SCLogDebug(
"result %" PRIi32
", p->ts(sec) %" PRIuMAX
"", result,
6472 SCLogDebug(
"timestamp is not valid sender_stream->last_ts "
6473 "%" PRIu32
" p->tcpvars->ts %" PRIu32
" result "
6474 "%" PRId32
"", sender_stream->
last_ts,
ts, result);
6477 }
else if ((sender_stream->
last_ts != 0) &&
6480 SCLogDebug(
"packet is not valid sender_stream->last_pkt_ts "
6481 "%" PRIu32
" p->ts(sec) %" PRIu32
"",
6495 }
else if (ret == 0) {
6505 SCLogDebug(
"timestamp considered valid anyway");
6568 SCLogDebug(
"ACK %"PRIu32
" is before last_ack %"PRIu32
" - window "
6569 "%"PRIu32
" = %"PRIu32, ack, stream->
last_ack,
6593 SCLogDebug(
"default path leading to invalid: ACK %"PRIu32
", last_ack %"PRIu32
6606 const uint32_t progress)
6664 static void StreamTcpPseudoPacketCreateDetectLogFlush(
ThreadVars *
tv,
6683 np->
proto = IPPROTO_TCP;
6684 FlowReference(&np->
flow, f);
6694 DecodeSetNoPacketInspectionFlag(np);
6697 DecodeSetNoPayloadInspectionFlag(np);
6743 np->
ip4h->s_ip_src.s_addr = f->
src.addr_data32[0];
6744 np->
ip4h->s_ip_dst.s_addr = f->
dst.addr_data32[0];
6746 np->
ip4h->s_ip_src.s_addr = f->
dst.addr_data32[0];
6747 np->
ip4h->s_ip_dst.s_addr = f->
src.addr_data32[0];
6779 np->
ip6h->s_ip6_vfc = 0x60;
6780 np->
ip6h->s_ip6_flow = 0;
6781 np->
ip6h->s_ip6_nxt = IPPROTO_TCP;
6782 np->
ip6h->s_ip6_plen = htons(20);
6783 np->
ip6h->s_ip6_hlim = 64;
6785 np->
ip6h->s_ip6_src[0] = f->
src.addr_data32[0];
6786 np->
ip6h->s_ip6_src[1] = f->
src.addr_data32[1];
6787 np->
ip6h->s_ip6_src[2] = f->
src.addr_data32[2];
6788 np->
ip6h->s_ip6_src[3] = f->
src.addr_data32[3];
6789 np->
ip6h->s_ip6_dst[0] = f->
dst.addr_data32[0];
6790 np->
ip6h->s_ip6_dst[1] = f->
dst.addr_data32[1];
6791 np->
ip6h->s_ip6_dst[2] = f->
dst.addr_data32[2];
6792 np->
ip6h->s_ip6_dst[3] = f->
dst.addr_data32[3];
6794 np->
ip6h->s_ip6_src[0] = f->
dst.addr_data32[0];
6795 np->
ip6h->s_ip6_src[1] = f->
dst.addr_data32[1];
6796 np->
ip6h->s_ip6_src[2] = f->
dst.addr_data32[2];
6797 np->
ip6h->s_ip6_src[3] = f->
dst.addr_data32[3];
6798 np->
ip6h->s_ip6_dst[0] = f->
src.addr_data32[0];
6799 np->
ip6h->s_ip6_dst[1] = f->
src.addr_data32[1];
6800 np->
ip6h->s_ip6_dst[2] = f->
src.addr_data32[2];
6801 np->
ip6h->s_ip6_dst[3] = f->
src.addr_data32[3];
6833 np->
ts = parent->
ts;
6841 FlowDeReference(&np->
flow);
6860 StreamTcpPseudoPacketCreateDetectLogFlush(
tv, stt, p, ssn, pq,
ts^0);
6861 StreamTcpPseudoPacketCreateDetectLogFlush(
tv, stt, p, ssn, pq,
ts^1);
6881 if (p->
flow == NULL)
6909 const uint8_t *seg_data;
6910 uint32_t seg_datalen;
6913 int ret = CallbackFunc(p, seg, data, seg_data, seg_datalen);
6941 if (p->
flow == NULL)
6955 if (server_node == NULL && client_node == NULL) {
6959 while (server_node != NULL || client_node != NULL) {
6960 const uint8_t *seg_data;
6961 uint32_t seg_datalen;
6962 if (server_node == NULL) {
6969 &client_stream->
sb, &client_node->
sbseg, &seg_data, &seg_datalen);
6970 ret = CallbackFunc(p, client_node, data, seg_data, seg_datalen);
6975 client_node = TCPSEG_RB_NEXT(client_node);
6976 }
else if (client_node == NULL) {
6983 &server_stream->
sb, &server_node->
sbseg, &seg_data, &seg_datalen);
6984 ret = CallbackFunc(p, server_node, data, seg_data, seg_datalen);
6989 server_node = TCPSEG_RB_NEXT(server_node);
6994 &client_stream->
sb, &client_node->
sbseg, &seg_data, &seg_datalen);
6995 ret = CallbackFunc(p, client_node, data, seg_data, seg_datalen);
7000 client_node = TCPSEG_RB_NEXT(client_node);
7003 &server_stream->
sb, &server_node->
sbseg, &seg_data, &seg_datalen);
7004 ret = CallbackFunc(p, server_node, data, seg_data, seg_datalen);
7009 server_node = TCPSEG_RB_NEXT(server_node);
7046 const char *tcp_state = NULL;
7052 tcp_state =
"syn_sent";
7055 tcp_state =
"syn_recv";
7058 tcp_state =
"established";
7061 tcp_state =
"fin_wait1";
7064 tcp_state =
"fin_wait2";
7067 tcp_state =
"time_wait";
7070 tcp_state =
"last_ack";
7073 tcp_state =
"close_wait";
7076 tcp_state =
"closing";
7079 tcp_state =
"closed";