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
103 static int StreamTcpStateDispatch(
112 static uint64_t ssn_pool_cnt = 0;
133 #if defined(DEBUG_VALIDATION) && defined(UNITTESTS)
136 BUG_ON(presize > UINT_MAX);
142 #if defined(DEBUG_VALIDATION) && defined(UNITTESTS)
145 BUG_ON(postsize > presize);
167 if (memcapcopy == 0 || size +
SC_ATOMIC_GET(st_memuse) <= memcapcopy)
179 if (size == 0 || (uint64_t)
SC_ATOMIC_GET(st_memuse) < size) {
200 if (stream != NULL) {
207 static void StreamTcp3wsFreeQueue(
TcpSession *ssn)
234 StreamTcp3wsFreeQueue(ssn);
295 static void *StreamTcpSessionPoolAlloc(
void)
309 static int StreamTcpSessionPoolInit(
void *data,
void* initdata)
319 static void StreamTcpSessionPoolCleanup(
void *s)
333 static inline bool StreamTcpInlineDropInvalid(
void)
342 static int RandomGetWrap(
void)
348 }
while(r >= ULONG_MAX - (ULONG_MAX % RAND_MAX));
362 uint16_t rdrange = 10;
371 if ((
ConfGetInt(
"stream.max-sessions", &value)) == 1) {
373 "Number of concurrent sessions is now only limited by Flow and "
374 "TCP stream engine memcaps.");
377 if ((
ConfGetInt(
"stream.prealloc-sessions", &value)) == 1) {
384 if (
ConfGetNode(
"stream.prealloc-sessions") != NULL) {
392 SCLogConfig(
"stream \"prealloc-sessions\": %"PRIu32
" (per thread)",
396 const char *temp_stream_memcap_str;
397 if (
ConfGet(
"stream.memcap", &temp_stream_memcap_str) == 1) {
398 uint64_t stream_memcap_copy;
401 "from conf file - %s. Killing engine",
402 temp_stream_memcap_str);
416 (void)
ConfGetBool(
"stream.midstream", &imidstream);
424 (void)
ConfGetBool(
"stream.async-oneside", &async_oneside);
433 if ((
ConfGetBool(
"stream.checksum-validation", &csum)) == 1) {
445 "enabled" :
"disabled");
448 const char *temp_stream_inline_str;
449 if (
ConfGet(
"stream.inline", &temp_stream_inline_str) == 1) {
454 if (strcmp(temp_stream_inline_str,
"auto") == 0) {
458 }
else if (
ConfGetBool(
"stream.inline", &inl) == 1) {
477 ?
"enabled" :
"disabled");
481 if ((
ConfGetBool(
"stream.bypass", &bypass)) == 1) {
490 ?
"enabled" :
"disabled");
493 int drop_invalid = 0;
494 if ((
ConfGetBool(
"stream.drop-invalid", &drop_invalid)) == 1) {
495 if (drop_invalid == 1) {
502 if ((
ConfGetInt(
"stream.max-syn-queued", &value)) == 1) {
503 if (value >= 0 && value <= 255) {
515 if ((
ConfGetInt(
"stream.max-synack-queued", &value)) == 1) {
516 if (value >= 0 && value <= 255) {
528 const char *temp_stream_reassembly_memcap_str;
529 if (
ConfGet(
"stream.reassembly.memcap", &temp_stream_reassembly_memcap_str) == 1) {
530 uint64_t stream_reassembly_memcap_copy;
532 &stream_reassembly_memcap_copy) < 0) {
534 "stream.reassembly.memcap "
535 "from conf file - %s. Killing engine",
536 temp_stream_reassembly_memcap_str);
546 SCLogConfig(
"stream.reassembly \"memcap\": %"PRIu64
"",
550 const char *temp_stream_reassembly_depth_str;
551 if (
ConfGet(
"stream.reassembly.depth", &temp_stream_reassembly_depth_str) == 1) {
555 "stream.reassembly.depth "
556 "from conf file - %s. Killing engine",
557 temp_stream_reassembly_depth_str);
569 if ((
ConfGetBool(
"stream.reassembly.randomize-chunk-size", &randomize)) == 0) {
577 const char *temp_rdrange;
578 if (
ConfGet(
"stream.reassembly.randomize-chunk-range", &temp_rdrange) == 1) {
581 "stream.reassembly.randomize-chunk-range "
582 "from conf file - %s. Killing engine",
585 }
else if (rdrange >= 100) {
586 FatalError(
"stream.reassembly.randomize-chunk-range "
587 "must be lower than 100");
592 const char *temp_stream_reassembly_toserver_chunk_size_str;
593 if (
ConfGet(
"stream.reassembly.toserver-chunk-size",
594 &temp_stream_reassembly_toserver_chunk_size_str) == 1) {
598 "stream.reassembly.toserver-chunk-size "
599 "from conf file - %s. Killing engine",
600 temp_stream_reassembly_toserver_chunk_size_str);
609 long int r = RandomGetWrap();
614 const char *temp_stream_reassembly_toclient_chunk_size_str;
615 if (
ConfGet(
"stream.reassembly.toclient-chunk-size",
616 &temp_stream_reassembly_toclient_chunk_size_str) == 1) {
620 "stream.reassembly.toclient-chunk-size "
621 "from conf file - %s. Killing engine",
622 temp_stream_reassembly_toclient_chunk_size_str);
631 long int r = RandomGetWrap();
637 SCLogConfig(
"stream.reassembly \"toserver-chunk-size\": %"PRIu16,
639 SCLogConfig(
"stream.reassembly \"toclient-chunk-size\": %"PRIu16,
644 if (
ConfGetBool(
"stream.reassembly.raw", &enable_raw) == 1) {
652 SCLogConfig(
"stream.reassembly.raw: %s", enable_raw ?
"enabled" :
"disabled");
656 int liberal_timestamps = 0;
657 if (
ConfGetBool(
"stream.liberal-timestamps", &liberal_timestamps) == 1) {
661 SCLogConfig(
"stream.liberal-timestamps: %s", liberal_timestamps ?
"enabled" :
"disabled");
681 StreamTcpSessionPoolAlloc,
682 StreamTcpSessionPoolInit, NULL,
683 StreamTcpSessionPoolCleanup, NULL);
702 SCLogDebug(
"ssn_pool_cnt %"PRIu64
"", ssn_pool_cnt);
740 if (
unlikely((g_eps_stream_ssn_memcap != UINT64_MAX &&
741 g_eps_stream_ssn_memcap ==
t_pcapcnt))) {
849 #define StreamTcpUpdateLastAck(ssn, stream, ack) { \
850 if (SEQ_GT((ack), (stream)->last_ack)) \
852 SCLogDebug("ssn %p: last_ack set to %"PRIu32", moved %u forward", (ssn), (ack), (ack) - (stream)->last_ack); \
853 if ((SEQ_LEQ((stream)->last_ack, (stream)->next_seq) && SEQ_GT((ack),(stream)->next_seq))) { \
854 SCLogDebug("last_ack just passed next_seq: %u (was %u) > %u", (ack), (stream)->last_ack, (stream)->next_seq); \
856 SCLogDebug("next_seq (%u) <> last_ack now %d", (stream)->next_seq, (int)(stream)->next_seq - (ack)); \
858 (stream)->last_ack = (ack); \
859 StreamTcpSackPruneList((stream)); \
861 SCLogDebug("ssn %p: no update: ack %u, last_ack %"PRIu32", next_seq %u (state %u)", \
862 (ssn), (ack), (stream)->last_ack, (stream)->next_seq, (ssn)->state); \
866 #define StreamTcpAsyncLastAckUpdate(ssn, stream) { \
867 if ((ssn)->flags & STREAMTCP_FLAG_ASYNC) { \
868 if (SEQ_GT((stream)->next_seq, (stream)->last_ack)) { \
869 uint32_t ack_diff = (stream)->next_seq - (stream)->last_ack; \
870 (stream)->last_ack += ack_diff; \
871 SCLogDebug("ssn %p: ASYNC last_ack set to %"PRIu32", moved %u forward", \
872 (ssn), (stream)->next_seq, ack_diff); \
877 #define StreamTcpUpdateNextSeq(ssn, stream, seq) { \
878 (stream)->next_seq = seq; \
879 SCLogDebug("ssn %p: next_seq %" PRIu32, (ssn), (stream)->next_seq); \
880 StreamTcpAsyncLastAckUpdate((ssn), (stream)); \
890 #define StreamTcpUpdateNextWin(ssn, stream, win) { \
891 uint32_t sacked_size__ = StreamTcpSackedSize((stream)); \
892 if (SEQ_GT(((win) + sacked_size__), (stream)->next_win)) { \
893 (stream)->next_win = ((win) + sacked_size__); \
894 SCLogDebug("ssn %p: next_win set to %"PRIu32, (ssn), (stream)->next_win); \
902 SCLogDebug(
"ssn %p: (state: %s) Reset received and state changed to "
906 static int StreamTcpPacketIsRetransmission(
TcpStream *stream,
Packet *p)
948 static int StreamTcpPacketStateNone(
953 SCLogDebug(
"RST packet received, no session setup");
962 SCLogDebug(
"FIN packet received, no session setup");
968 SCLogDebug(
"FIN packet received, no session setup");
985 SCLogDebug(
"ssn %p: =~ midstream picked ssn state is now "
1017 SCLogDebug(
"ssn %p: ssn->client.next_win %" PRIu32
", "
1018 "ssn->server.next_win %" PRIu32
"",
1020 SCLogDebug(
"ssn %p: ssn->client.last_ack %" PRIu32
", "
1021 "ssn->server.last_ack %" PRIu32
"",
1029 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1030 "ssn->client.last_ts %" PRIu32
"",
1049 SCLogDebug(
"ssn %p: assuming SACK permitted for both sides", ssn);
1057 SCLogDebug(
"Midstream not enabled, so won't pick up a session");
1062 SCLogDebug(
"Midstream policy not permissive, so won't pick up a session");
1085 SCLogDebug(
"ssn %p: =~ midstream picked ssn state is now "
1086 "TCP_SYN_RECV", ssn);
1117 SCLogDebug(
"ssn %p: wscale enabled. client %u server %u",
1121 SCLogDebug(
"ssn %p: ssn->client.isn %"PRIu32
", ssn->client.next_seq"
1122 " %"PRIu32
", ssn->client.last_ack %"PRIu32
"", ssn,
1125 SCLogDebug(
"ssn %p: ssn->server.isn %"PRIu32
", ssn->server.next_seq"
1126 " %"PRIu32
", ssn->server.last_ack %"PRIu32
"", ssn,
1135 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1136 "ssn->client.last_ts %" PRIu32
"", ssn,
1154 SCLogDebug(
"ssn %p: SYN/ACK with SACK permitted, assuming "
1155 "SACK permitted for both sides", ssn);
1173 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_SYN_SENT", ssn);
1206 SCLogDebug(
"ssn %p: SACK permitted on SYN packet", ssn);
1213 SCLogDebug(
"ssn: %p (TFO) [len: %d] isn %u base_seq %u next_seq %u payload len %u",
1219 SCLogDebug(
"ssn %p: ssn->client.isn %" PRIu32
", "
1220 "ssn->client.next_seq %" PRIu32
", ssn->client.last_ack "
1229 SCLogDebug(
"Midstream not enabled, so won't pick up a session");
1234 SCLogDebug(
"Midstream policy not permissive, so won't pick up a session");
1251 SCLogDebug(
"ssn %p: =~ midstream picked ssn state is now "
1252 "TCP_ESTABLISHED", ssn);
1273 SCLogDebug(
"ssn %p: ssn->client.isn %u, ssn->client.next_seq %u",
1282 SCLogDebug(
"ssn %p: ssn->client.next_win %"PRIu32
", "
1283 "ssn->server.next_win %"PRIu32
"", ssn,
1285 SCLogDebug(
"ssn %p: ssn->client.last_ack %"PRIu32
", "
1286 "ssn->server.last_ack %"PRIu32
"", ssn,
1294 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1295 "ssn->client.last_ts %" PRIu32
"", ssn,
1314 SCLogDebug(
"ssn %p: assuming SACK permitted for both sides", ssn);
1357 StreamTcp3whsSynAckToStateQueue(p, &search);
1365 search.
ts == q->
ts) {
1378 if (StreamTcp3whsFindSynAckBySynAck(ssn, p) != NULL)
1382 SCLogDebug(
"ssn %p: =~ SYN/ACK queue limit reached", ssn);
1388 SCLogDebug(
"ssn %p: =~ SYN/ACK queue failed: stream memcap reached", ssn);
1394 SCLogDebug(
"ssn %p: =~ SYN/ACK queue failed: alloc failed", ssn);
1399 StreamTcp3whsSynAckToStateQueue(p, q);
1447 StreamTcp3whsSynAckToStateQueue(p, &update);
1454 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_SYN_RECV", ssn);
1470 SCLogDebug(
"ssn %p: ssn->server.last_ts %" PRIu32
" "
1471 "ssn->client.last_ts %" PRIu32
"", ssn,
1499 SCLogDebug(
"ssn %p: SACK permitted for session", ssn);
1506 SCLogDebug(
"ssn %p: ssn->server.next_win %" PRIu32
"", ssn,
1508 SCLogDebug(
"ssn %p: ssn->client.next_win %" PRIu32
"", ssn,
1510 SCLogDebug(
"ssn %p: ssn->server.isn %" PRIu32
", "
1511 "ssn->server.next_seq %" PRIu32
", "
1512 "ssn->server.last_ack %" PRIu32
" "
1513 "(ssn->client.last_ack %" PRIu32
")", ssn,
1520 SCLogDebug(
"ssn %p: STREAMTCP_FLAG_4WHS unset, normal SYN/ACK"
1521 " so considering 3WHS", ssn);
1532 static inline bool StateSynSentValidateTimestamp(
TcpSession *ssn,
Packet *p)
1542 if (receiver_stream->
last_ts != 0 && ts_echo != 0 &&
1543 ts_echo != receiver_stream->
last_ts)
1545 SCLogDebug(
"ssn %p: BAD TSECR echo %u recv %u", ssn,
1546 ts_echo, receiver_stream->
last_ts);
1550 if (receiver_stream->
last_ts == 0 && ts_echo != 0) {
1551 SCLogDebug(
"ssn %p: BAD TSECR echo %u recv %u", ssn,
1552 ts_echo, receiver_stream->
last_ts);
1562 memset(q, 0,
sizeof(*q));
1582 SCLogDebug(
"ssn %p: state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq, q->
win,
1588 #if defined(DEBUG_VALIDATION) || defined(DEBUG)
1592 memset(q, 0,
sizeof(*q));
1610 SCLogDebug(
"ssn %p: state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq, q->
win,
1617 #if defined(DEBUG_VALIDATION) || defined(DEBUG)
1624 memset(q, 0,
sizeof(*q));
1642 SCLogDebug(
"ssn %p: state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq, q->
win,
1652 SCLogDebug(
"ssn %p: search state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, s, s->
seq, s->
win,
1656 SCLogDebug(
"ssn %p: queue state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u", ssn, q, q->
seq,
1670 TcpStateQueueInitFromSsnSyn(ssn, &search);
1673 if (ssn->
queue != NULL && StreamTcp3whsFindSyn(ssn, &search) != NULL)
1677 SCLogDebug(
"ssn %p: =~ SYN queue limit reached", ssn);
1683 SCLogDebug(
"ssn %p: =~ SYN queue failed: stream memcap reached", ssn);
1689 SCLogDebug(
"ssn %p: =~ SYN queue failed: alloc failed", ssn);
1736 static int StreamTcpPacketStateSynSent(
1745 SCLogDebug(
"ssn %p: SYN/ACK on SYN_SENT state for packet %" PRIu64, ssn, p->
pcap_cnt);
1752 SCLogDebug(
"ssn %p: ACK mismatch, packet ACK %" PRIu32
" != "
1759 SCLogDebug(
"ssn %p: (TFO) ACK matches next_seq, packet ACK %" PRIu32
" == "
1760 "%" PRIu32
" from stream",
1763 SCLogDebug(
"ssn %p: (TFO) ACK matches ISN+1, packet ACK %" PRIu32
" == "
1764 "%" PRIu32
" from stream",
1772 SCLogDebug(
"ssn %p: (TFO) ACK mismatch, packet ACK %" PRIu32
" != "
1781 const bool ts_mismatch = !StateSynSentValidateTimestamp(ssn, p);
1786 TcpStateQueueInitFromPktSynAck(p, &search);
1788 const TcpStateQueue *q = StreamTcp3whsFindSyn(ssn, &search);
1794 SCLogDebug(
"ssn %p: found queued SYN state:%p, isn:%u/win:%u/has_ts:%s/tsval:%u",
1798 StreamTcp3whsStoreSynApplyToSsn(ssn, q);
1808 StreamTcp3wsFreeQueue(ssn);
1810 StreamTcp3whsSynAckUpdate(ssn, p, NULL);
1817 SCLogDebug(
"ssn %p: SYN/ACK received in the wrong direction", ssn);
1821 SCLogDebug(
"ssn %p: SYN/ACK received on 4WHS session", ssn);
1828 SCLogDebug(
"ssn %p: 4WHS ACK mismatch, packet ACK %" PRIu32
""
1829 " != %" PRIu32
" from stream",
1839 SCLogDebug(
"ssn %p: 4WHS SEQ mismatch, packet SEQ %" PRIu32
""
1840 " != %" PRIu32
" from *first* SYN pkt",
1847 SCLogDebug(
"ssn %p: =~ 4WHS ssn state is now TCP_SYN_RECV", ssn);
1861 SCLogDebug(
"ssn %p: 4WHS ssn->client.last_ts %" PRIu32
" "
1862 "ssn->server.last_ts %" PRIu32
"",
1887 SCLogDebug(
"ssn %p: SACK permitted for 4WHS session", ssn);
1894 SCLogDebug(
"ssn %p: 4WHS ssn->client.isn %" PRIu32
", "
1895 "ssn->client.next_seq %" PRIu32
", "
1896 "ssn->client.last_ack %" PRIu32
" "
1897 "(ssn->server.last_ack %" PRIu32
")",
1906 if (StateSynSentValidateTimestamp(ssn, p) ==
false) {
1914 if (!StreamTcpValidateRst(ssn, p))
1920 SCLogDebug(
"ssn->server.flags |= STREAMTCP_STREAM_FLAG_RST_RECV");
1922 StreamTcpCloseSsnWithReset(p, ssn);
1923 StreamTcp3wsFreeQueue(ssn);
1927 SCLogDebug(
"ssn->client.flags |= STREAMTCP_STREAM_FLAG_RST_RECV");
1928 StreamTcpCloseSsnWithReset(p, ssn);
1929 StreamTcp3wsFreeQueue(ssn);
1937 SCLogDebug(
"ssn %p: SYN packet on state SYN_SENT... resent", ssn);
1939 SCLogDebug(
"ssn %p: SYN packet on state SYN_SENT... resent of "
1952 SCLogDebug(
"ssn %p: STREAMTCP_FLAG_4WHS flag set", ssn);
1989 SCLogDebug(
"ssn %p: 4WHS ssn->server.isn %" PRIu32
", "
1990 "ssn->server.next_seq %" PRIu32
", "
1991 "ssn->server.last_ack %"PRIu32
"", ssn,
1994 SCLogDebug(
"ssn %p: 4WHS ssn->client.isn %" PRIu32
", "
1995 "ssn->client.next_seq %" PRIu32
", "
1996 "ssn->client.last_ack %"PRIu32
"", ssn,
2005 TcpStateQueueInitFromPktSyn(p, &syn_pkt);
2006 TcpStateQueueInitFromSsnSyn(ssn, &syn_ssn);
2008 if (memcmp(&syn_pkt, &syn_ssn,
sizeof(
TcpStateQueue)) != 0) {
2010 StreamTcp3whsStoreSyn(ssn, p);
2011 SCLogDebug(
"ssn %p: Retransmitted SYN. Updating ssn from packet %" PRIu64
2012 ". Stored previous state",
2015 StreamTcp3whsStoreSynApplyToSsn(ssn, &syn_pkt);
2031 SCLogDebug(
"ssn %p: SEQ mismatch, packet SEQ %" PRIu32
" != "
2039 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2040 StreamTcp3wsFreeQueue(ssn);
2053 SCLogDebug(
"ssn %p: synsent => Asynchronous stream, packet SEQ"
2054 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2055 "ssn->client.next_seq %" PRIu32
""
2104 static int StreamTcpPacketStateSynRecv(
2110 if (!StreamTcpValidateRst(ssn, p))
2127 SCLogDebug(
"Detection evasion has been attempted, so"
2128 " not resetting the connection !!");
2136 SCLogDebug(
"Detection evasion has been attempted, so"
2137 " not resetting the connection !!");
2143 StreamTcpCloseSsnWithReset(p, ssn);
2146 StreamTcpHandleTimestamp(ssn, p);
2153 if (!StreamTcpValidateTimestamp(ssn, p))
2157 if ((StreamTcpHandleFin(
tv, stt, ssn, p)) == -1)
2162 SCLogDebug(
"ssn %p: SYN/ACK packet on state SYN_RECV. resent", ssn);
2165 SCLogDebug(
"ssn %p: SYN/ACK-pkt to server in SYN_RECV state", ssn);
2174 SCLogDebug(
"ssn %p: ACK mismatch, packet ACK %" PRIu32
" != "
2185 SCLogDebug(
"ssn %p: SEQ mismatch, packet SEQ %" PRIu32
" != "
2189 if (StreamTcp3whsQueueSynAck(ssn, p) == -1)
2191 SCLogDebug(
"ssn %p: queued different SYN/ACK", ssn);
2195 SCLogDebug(
"ssn %p: SYN packet on state SYN_RECV... resent", ssn);
2198 SCLogDebug(
"ssn %p: SYN-pkt to client in SYN_RECV state", ssn);
2205 SCLogDebug(
"ssn %p: SYN with different SEQ on SYN_RECV state", ssn);
2213 SCLogDebug(
"ssn %p: checking ACK against queued SYN/ACKs", ssn);
2216 SCLogDebug(
"ssn %p: here we update state against queued SYN/ACK", ssn);
2217 StreamTcp3whsSynAckUpdate(ssn, p, q);
2219 SCLogDebug(
"ssn %p: none found, now checking ACK against original SYN/ACK (state)", ssn);
2229 if (!(StreamTcpValidateTimestamp(ssn, p))) {
2235 SCLogDebug(
"ssn %p: ACK received on 4WHS session",ssn);
2238 SCLogDebug(
"ssn %p: 4WHS wrong seq nr on packet", ssn);
2243 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
2244 SCLogDebug(
"ssn %p: 4WHS invalid ack nr on packet", ssn);
2250 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
2251 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
2255 StreamTcpHandleTimestamp(ssn, p);
2264 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2268 SCLogDebug(
"ssn %p: ssn->client.next_win %" PRIu32
", "
2269 "ssn->client.last_ack %"PRIu32
"", ssn,
2274 bool ack_indicates_missed_3whs_ack_packet =
false;
2284 SCLogDebug(
"ssn %p: ACK received on midstream SYN/ACK "
2285 "pickup session",ssn);
2288 SCLogDebug(
"ssn %p: ACK received on TFO session",ssn);
2306 SCLogDebug(
"ssn %p: possible data injection", ssn);
2311 SCLogDebug(
"ssn %p: ACK received in the wrong direction",
2316 ack_indicates_missed_3whs_ack_packet =
true;
2320 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ %" PRIu32
""
2333 StreamTcpHandleTimestamp(ssn, p);
2357 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2374 StreamTcpHandleTimestamp(ssn, p);
2387 SCLogDebug(
"ssn %p: synrecv => Asynchronous stream, packet SEQ"
2388 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2389 "ssn->server.next_seq %" PRIu32
2394 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2403 SCLogDebug(
"ssn %p: wrong ack nr on packet, possible evasion!!",
2413 SCLogDebug(
"ssn %p: ACK for missing data", ssn);
2416 StreamTcpHandleTimestamp(ssn, p);
2422 SCLogDebug(
"ssn %p: ACK for missing data: ssn->server.next_seq %u", ssn,
2432 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2441 SCLogDebug(
"ssn %p: ACK for missing data", ssn);
2444 StreamTcpHandleTimestamp(ssn, p);
2466 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2471 }
else if ((ack_indicates_missed_3whs_ack_packet ||
2475 if (ack_indicates_missed_3whs_ack_packet) {
2476 SCLogDebug(
"ssn %p: packet fits perfectly after a missed 3whs-ACK", ssn);
2478 SCLogDebug(
"ssn %p: (TFO) expected packet fits perfectly after SYN/ACK", ssn);
2487 SCLogDebug(
"ssn %p: =~ ssn state is now TCP_ESTABLISHED", ssn);
2492 SCLogDebug(
"ssn %p: wrong seq nr on packet", ssn);
2498 SCLogDebug(
"ssn %p: ssn->server.next_win %" PRIu32
", "
2499 "ssn->server.last_ack %"PRIu32
"", ssn,
2521 static int HandleEstablishedPacketToServer(
2524 SCLogDebug(
"ssn %p: =+ pkt (%" PRIu32
") is to server: SEQ %" PRIu32
","
2525 "ACK %" PRIu32
", WIN %"PRIu16
"", ssn, p->
payload_len,
2528 const bool has_ack = (p->
tcph->th_flags &
TH_ACK) != 0;
2531 SCLogDebug(
"ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn);
2534 }
else if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
2535 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
2544 SCLogDebug(
"ssn %p: pkt is keep alive", ssn);
2549 SCLogDebug(
"ssn %p: server => Asynchronous stream, packet SEQ"
2550 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2551 " ssn->client.last_ack %" PRIu32
", ssn->client.next_win"
2552 "%" PRIu32
"(%" PRIu32
")",
2563 SCLogDebug(
"ssn %p: server => Asynchronous stream, packet SEQ."
2564 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2565 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2579 SCLogDebug(
"ssn %p: server => Asynchronous stream, packet SEQ"
2580 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2581 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2598 SCLogDebug(
"ssn %p: PKT SEQ %" PRIu32
" payload_len %" PRIu16
2599 " before last_ack %" PRIu32
", after next_seq %" PRIu32
":"
2600 " acked data that we haven't seen before",
2604 SCLogDebug(
"ssn %p: server => SEQ before last_ack, packet SEQ"
2605 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"), "
2606 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2612 SCLogDebug(
"ssn %p: rejecting because pkt before last_ack", ssn);
2618 int zerowindowprobe = 0;
2621 SCLogDebug(
"ssn %p: zero window probe", ssn);
2622 zerowindowprobe = 1;
2632 if (zerowindowprobe) {
2633 SCLogDebug(
"ssn %p: zero window probe, skipping oow check", ssn);
2637 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->client.next_win "
2641 SCLogDebug(
"ssn %p: ssn->server.window %"PRIu32
"", ssn,
2657 StreamTcpHandleTimestamp(ssn, p);
2669 SCLogDebug(
"ssn %p: toserver => SEQ out of window, packet SEQ "
2670 "%" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2671 "ssn->client.last_ack %" PRIu32
", ssn->client.next_win "
2677 StreamTcpSackedSize(&ssn->
client));
2697 static int HandleEstablishedPacketToClient(
2700 SCLogDebug(
"ssn %p: =+ pkt (%" PRIu32
") is to client: SEQ %" PRIu32
","
2701 " ACK %" PRIu32
", WIN %"PRIu16
"", ssn, p->
payload_len,
2704 const bool has_ack = (p->
tcph->th_flags &
TH_ACK) != 0;
2707 SCLogDebug(
"ssn %p: accepting ACK as it ACKs the one byte from the ZWP", ssn);
2710 }
else if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
2711 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
2725 SCLogDebug(
"ssn %p: adjusted midstream ssn->server.next_win to "
2732 SCLogDebug(
"ssn %p: pkt is keep alive", ssn);
2738 SCLogDebug(
"ssn %p: client => Asynchronous stream, packet SEQ"
2739 " %" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2740 " ssn->client.last_ack %" PRIu32
", ssn->client.next_win"
2741 " %" PRIu32
"(%" PRIu32
")",
2754 SCLogDebug(
"ssn %p: PKT SEQ %" PRIu32
" payload_len %" PRIu16
2755 " before last_ack %" PRIu32
", after next_seq %" PRIu32
":"
2756 " acked data that we haven't seen before",
2760 SCLogDebug(
"ssn %p: PKT SEQ %"PRIu32
" payload_len %"PRIu16
2761 " before last_ack %"PRIu32
". next_seq %"PRIu32,
2768 int zerowindowprobe = 0;
2771 SCLogDebug(
"ssn %p: zero window probe", ssn);
2772 zerowindowprobe = 1;
2783 if (zerowindowprobe) {
2784 SCLogDebug(
"ssn %p: zero window probe, skipping oow check", ssn);
2788 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->server.next_win "
2791 SCLogDebug(
"ssn %p: ssn->client.window %"PRIu32
"", ssn,
2804 StreamTcpHandleTimestamp(ssn, p);
2813 SCLogDebug(
"ssn %p: client => SEQ out of window, packet SEQ"
2814 "%" PRIu32
", payload size %" PRIu32
" (%" PRIu32
"),"
2815 " ssn->server.last_ack %" PRIu32
", ssn->server.next_win "
2838 static inline uint32_t StreamTcpResetGetMaxAck(
TcpStream *stream, uint32_t
seq)
2844 if (
SEQ_GT(tail_seq, ack)) {
2852 static bool StreamTcpPacketIsZeroWindowProbeAck(
const TcpSession *ssn,
const Packet *p)
2877 if (pkt_win != rcv->
window)
2884 SCLogDebug(
"ssn %p: packet %" PRIu64
" is a Zero Window Probe ACK", ssn, p->
pcap_cnt);
2891 static bool StreamTcpPacketIsDupAck(
const TcpSession *ssn,
const Packet *p)
2910 if (pkt_win == 0 || rcv->
window == 0)
2912 if (pkt_win != rcv->
window)
2920 SCLogDebug(
"ssn %p: packet:%" PRIu64
" seq:%u ack:%u win:%u snd %u:%u:%u rcv %u:%u:%u", ssn,
2994 static int StreamTcpPacketIsSpuriousRetransmission(
const TcpSession *ssn,
Packet *p)
3010 "ssn %p: spurious retransmission; packet entirely before base_seq: SEQ %u(%u) "
3011 "last_ack %u base_seq %u",
3020 SCLogDebug(
"ssn %p: spurious retransmission; packet entirely before last_ack: SEQ %u(%u) "
3027 SCLogDebug(
"ssn %p: NOT spurious retransmission; packet NOT entirely before last_ack: SEQ "
3028 "%u(%u) last_ack %u, base_seq %u",
3045 static int StreamTcpPacketStateEstablished(
3051 if (!StreamTcpValidateRst(ssn, p))
3055 StreamTcpCloseSsnWithReset(p, ssn);
3059 SCLogDebug(
"ssn %p: ssn->server.next_seq %" PRIu32
"", ssn,
3063 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
3071 StreamTcpHandleTimestamp(ssn, p);
3075 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3083 StreamTcpCloseSsnWithReset(p, ssn);
3088 SCLogDebug(
"ssn %p: ssn->server.next_seq %" PRIu32
"", ssn,
3092 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
3100 StreamTcpHandleTimestamp(ssn, p);
3104 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3115 if (!StreamTcpValidateTimestamp(ssn, p))
3120 " %" PRIu32
", last ACK %" PRIu32
", next win %"PRIu32
","
3125 if ((StreamTcpHandleFin(
tv, stt, ssn, p)) == -1)
3130 SCLogDebug(
"ssn %p: SYN/ACK packet on state ESTABLISHED... resent",
3134 SCLogDebug(
"ssn %p: SYN/ACK-pkt to server in ESTABLISHED state", ssn);
3143 SCLogDebug(
"ssn %p: ACK mismatch, packet ACK %" PRIu32
" != "
3154 SCLogDebug(
"ssn %p: SEQ mismatch, packet SEQ %" PRIu32
" != "
3168 SCLogDebug(
"ssn %p: SYN/ACK packet on state ESTABLISHED... resent. "
3169 "Likely due server not receiving final ACK in 3whs", ssn);
3173 SCLogDebug(
"ssn %p: SYN packet on state ESTABLISHED... resent", ssn);
3175 SCLogDebug(
"ssn %p: SYN-pkt to client in EST state", ssn);
3182 SCLogDebug(
"ssn %p: SYN with different SEQ on SYN_RECV state", ssn);
3203 if (!StreamTcpValidateTimestamp(ssn, p))
3209 HandleEstablishedPacketToServer(
tv, ssn, p, stt);
3211 SCLogDebug(
"ssn %p: next SEQ %" PRIu32
", last ACK %" PRIu32
","
3212 " next win %" PRIu32
", win %" PRIu32
"", ssn,
3219 SCLogDebug(
"3whs is now confirmed by server");
3223 HandleEstablishedPacketToClient(
tv, ssn, p, stt);
3225 SCLogDebug(
"ssn %p: next SEQ %" PRIu32
", last ACK %" PRIu32
","
3226 " next win %" PRIu32
", win %" PRIu32
"", ssn,
3252 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ %" PRIu32
","
3256 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3257 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3269 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
" != "
3283 SCLogDebug(
"ssn %p: state changed to TCP_CLOSE_WAIT", ssn);
3288 SCLogDebug(
"ssn %p: ssn->client.next_seq %" PRIu32
"", ssn,
3293 StreamTcpHandleTimestamp(ssn, p);
3306 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK %" PRIu32
"",
3309 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ %" PRIu32
", "
3313 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3314 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3326 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
" != "
3327 "%" PRIu32
" from stream (last_ack %u win %u = %u)", ssn,
TCP_GET_SEQ(p),
3335 SCLogDebug(
"ssn %p: state changed to TCP_FIN_WAIT1", ssn);
3344 StreamTcpHandleTimestamp(ssn, p);
3357 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK %" PRIu32
"",
3377 static int StreamTcpPacketStateFinWait1(
3383 if (!StreamTcpValidateRst(ssn, p))
3386 StreamTcpCloseSsnWithReset(p, ssn);
3389 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
3397 StreamTcpHandleTimestamp(ssn, p);
3402 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
3410 StreamTcpHandleTimestamp(ssn, p);
3418 if (!StreamTcpValidateTimestamp(ssn, p))
3423 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3424 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3426 int retransmission = 0;
3428 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3429 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3435 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3436 " != %" PRIu32
" from stream", ssn,
3442 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3443 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3448 if (!retransmission) {
3450 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
3456 StreamTcpHandleTimestamp(ssn, p);
3472 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3476 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3477 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3479 int retransmission = 0;
3481 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3482 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3488 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3494 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3495 " != %" PRIu32
" from stream", ssn,
3501 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3502 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3508 StreamTcpHandleTimestamp(ssn, p);
3511 if (!retransmission) {
3513 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
3531 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3538 if (!StreamTcpValidateTimestamp(ssn, p))
3543 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3544 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3546 int retransmission = 0;
3548 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3549 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3555 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3556 " != %" PRIu32
" from stream", ssn,
3562 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3563 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3568 if (!retransmission) {
3570 SCLogDebug(
"ssn %p: state changed to TCP_CLOSING", ssn);
3576 StreamTcpHandleTimestamp(ssn, p);
3593 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3597 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3598 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3601 int retransmission = 0;
3603 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3604 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3610 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3611 " != %" PRIu32
" from stream", ssn,
3617 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3618 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3623 if (!retransmission) {
3625 SCLogDebug(
"ssn %p: state changed to TCP_CLOSING", ssn);
3631 StreamTcpHandleTimestamp(ssn, p);
3648 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3653 SCLogDebug(
"ssn (%p): SYN pkt on FinWait1", ssn);
3659 if (!StreamTcpValidateTimestamp(ssn, p))
3664 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3665 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3667 int retransmission = 0;
3669 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3670 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3675 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3676 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3684 }
else if (!retransmission) {
3688 SCLogDebug(
"ssn %p: seq %" PRIu32
" in window, ssn->client.next_win "
3695 SCLogDebug(
"ssn %p: state changed to TCP_FIN_WAIT2", ssn);
3698 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3699 " != %" PRIu32
" from stream",
3711 StreamTcpHandleTimestamp(ssn, p);
3732 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3738 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3739 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3742 int retransmission = 0;
3744 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3745 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3750 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3751 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3756 if (!retransmission) {
3760 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->server.next_win "
3765 SCLogDebug(
"ssn %p: state changed to TCP_FIN_WAIT2", ssn);
3768 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
3769 " != %" PRIu32
" from stream", ssn,
3779 StreamTcpHandleTimestamp(ssn, p);
3800 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3821 static int StreamTcpPacketStateFinWait2(
3827 if (!StreamTcpValidateRst(ssn, p))
3830 StreamTcpCloseSsnWithReset(p, ssn);
3833 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
3841 StreamTcpHandleTimestamp(ssn, p);
3846 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
3854 StreamTcpHandleTimestamp(ssn, p);
3862 if (!StreamTcpValidateTimestamp(ssn, p))
3867 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3868 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3870 int retransmission = 0;
3877 }
else if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
3878 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3885 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ "
3886 "%" PRIu32
" != %" PRIu32
" from stream", ssn,
3892 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
3893 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3898 if (!retransmission) {
3900 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
3910 StreamTcpHandleTimestamp(ssn, p);
3923 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3927 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
3928 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3930 int retransmission = 0;
3937 }
else if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
3938 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
3945 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ "
3946 "%" PRIu32
" != %" PRIu32
" from stream", ssn,
3952 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
3953 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
3958 if (!retransmission) {
3960 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
3966 StreamTcpHandleTimestamp(ssn, p);
3978 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
3984 SCLogDebug(
"ssn (%p): SYN pkt on FinWait2", ssn);
3990 if (!StreamTcpValidateTimestamp(ssn, p))
3995 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
3996 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
3998 int retransmission = 0;
4000 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4001 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4006 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4007 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4012 if (!retransmission) {
4016 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->client.next_win "
4020 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4021 " != %" PRIu32
" from stream", ssn,
4031 StreamTcpHandleTimestamp(ssn, p);
4047 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4051 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4052 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4054 int retransmission = 0;
4056 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4057 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4062 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4063 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4068 if (!retransmission) {
4072 SCLogDebug(
"ssn %p: seq %"PRIu32
" in window, ssn->server.next_win "
4075 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4076 " != %" PRIu32
" from stream", ssn,
4086 StreamTcpHandleTimestamp(ssn, p);
4102 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4123 static int StreamTcpPacketStateClosing(
4129 if (!StreamTcpValidateRst(ssn, p))
4132 StreamTcpCloseSsnWithReset(p, ssn);
4135 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
4143 StreamTcpHandleTimestamp(ssn, p);
4148 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
4156 StreamTcpHandleTimestamp(ssn, p);
4163 SCLogDebug(
"ssn (%p): SYN pkt on Closing", ssn);
4169 if (!StreamTcpValidateTimestamp(ssn, p))
4174 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4175 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4177 int retransmission = 0;
4178 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4179 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4185 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4186 " != %" PRIu32
" from stream", ssn,
4192 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4193 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4198 if (!retransmission) {
4200 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
4206 StreamTcpHandleTimestamp(ssn, p);
4216 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4220 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4221 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4223 int retransmission = 0;
4224 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4225 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4231 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4232 " != %" PRIu32
" from stream", ssn,
4238 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4239 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4244 if (!retransmission) {
4246 SCLogDebug(
"ssn %p: state changed to TCP_TIME_WAIT", ssn);
4252 StreamTcpHandleTimestamp(ssn, p);
4263 SCLogDebug(
"StreamTcpPacketStateClosing (%p): =+ next SEQ "
4264 "%" PRIu32
", last ACK %" PRIu32
"", ssn,
4284 static int StreamTcpPacketStateCloseWait(
4292 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4293 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4296 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4297 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4302 if (!StreamTcpValidateRst(ssn, p))
4305 StreamTcpCloseSsnWithReset(p, ssn);
4308 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
4316 StreamTcpHandleTimestamp(ssn, p);
4321 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
4329 StreamTcpHandleTimestamp(ssn, p);
4337 if (!StreamTcpValidateTimestamp(ssn, p))
4342 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4343 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4346 int retransmission = 0;
4347 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4348 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4353 if (!retransmission) {
4357 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4358 " != %" PRIu32
" from stream", ssn,
4365 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4366 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4373 if (!retransmission)
4377 StreamTcpHandleTimestamp(ssn, p);
4389 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4393 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4394 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4397 int retransmission = 0;
4398 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4399 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4404 if (!retransmission) {
4408 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4409 " != %" PRIu32
" from stream", ssn,
4416 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4417 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4422 if (!retransmission) {
4424 SCLogDebug(
"ssn %p: state changed to TCP_LAST_ACK", ssn);
4430 StreamTcpHandleTimestamp(ssn, p);
4442 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4448 SCLogDebug(
"ssn (%p): SYN pkt on CloseWait", ssn);
4454 if (!StreamTcpValidateTimestamp(ssn, p))
4459 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4460 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4463 int retransmission = 0;
4464 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4465 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4471 SCLogDebug(
"ssn %p: -> retransmission", ssn);
4477 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4478 " != %" PRIu32
" from stream", ssn,
4484 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4485 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4490 if (!retransmission) {
4495 StreamTcpHandleTimestamp(ssn, p);
4509 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4513 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4514 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4516 int retransmission = 0;
4517 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4518 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4524 SCLogDebug(
"ssn %p: -> retransmission", ssn);
4530 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4531 " != %" PRIu32
" from stream", ssn,
4537 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4538 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4543 if (!retransmission) {
4548 StreamTcpHandleTimestamp(ssn, p);
4562 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4583 static int StreamTcpPacketStateLastAck(
4589 if (!StreamTcpValidateRst(ssn, p))
4592 StreamTcpCloseSsnWithReset(p, ssn);
4595 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
4603 StreamTcpHandleTimestamp(ssn, p);
4608 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
4616 StreamTcpHandleTimestamp(ssn, p);
4624 SCLogDebug(
"ssn (%p): FIN pkt on LastAck", ssn);
4627 SCLogDebug(
"ssn (%p): SYN pkt on LastAck", ssn);
4633 if (!StreamTcpValidateTimestamp(ssn, p))
4638 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4639 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4642 int retransmission = 0;
4643 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4644 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4649 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4650 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4655 if (!retransmission) {
4657 SCLogDebug(
"ssn %p: not updating state as packet is before next_seq", ssn);
4659 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4660 " != %" PRIu32
" from stream", ssn,
4666 SCLogDebug(
"ssn %p: state changed to TCP_CLOSED", ssn);
4673 StreamTcpHandleTimestamp(ssn, p);
4684 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4705 static int StreamTcpPacketStateTimeWait(
4711 if (!StreamTcpValidateRst(ssn, p))
4714 StreamTcpCloseSsnWithReset(p, ssn);
4717 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
server, p) == 0)
4725 StreamTcpHandleTimestamp(ssn, p);
4730 if ((p->
tcph->th_flags &
TH_ACK) && StreamTcpValidateAck(ssn, &ssn->
client, p) == 0)
4738 StreamTcpHandleTimestamp(ssn, p);
4748 SCLogDebug(
"ssn (%p): SYN pkt on TimeWait", ssn);
4754 if (!StreamTcpValidateTimestamp(ssn, p))
4759 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to server: SEQ "
4760 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4762 int retransmission = 0;
4763 if (StreamTcpPacketIsRetransmission(&ssn->
client, p)) {
4764 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4769 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4770 " != %" PRIu32
" from stream", ssn,
4776 if (StreamTcpValidateAck(ssn, &ssn->
server, p) == -1) {
4777 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4782 if (!retransmission) {
4784 SCLogDebug(
"ssn %p: state changed to TCP_CLOSED", ssn);
4790 StreamTcpHandleTimestamp(ssn, p);
4801 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4805 SCLogDebug(
"ssn %p: pkt (%" PRIu32
") is to client: SEQ "
4806 "%" PRIu32
", ACK %" PRIu32
"", ssn, p->
payload_len,
4808 int retransmission = 0;
4809 if (StreamTcpPacketIsRetransmission(&ssn->
server, p)) {
4810 SCLogDebug(
"ssn %p: packet is retransmission", ssn);
4816 SCLogDebug(
"ssn %p: -> retransmission", ssn);
4819 SCLogDebug(
"ssn %p: -> SEQ mismatch, packet SEQ %" PRIu32
""
4820 " != %" PRIu32
" from stream", ssn,
4827 if (StreamTcpValidateAck(ssn, &ssn->
client, p) == -1) {
4828 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
4833 if (!retransmission) {
4835 SCLogDebug(
"ssn %p: state changed to TCP_CLOSED", ssn);
4841 StreamTcpHandleTimestamp(ssn, p);
4852 SCLogDebug(
"ssn %p: =+ next SEQ %" PRIu32
", last ACK "
4864 static int StreamTcpPacketStateClosed(
4874 TcpStream *stream = NULL, *ostream = NULL;
4891 if (StreamTcpStateDispatch(
tv, p, stt, ssn, ssn->
pstate) < 0)
4919 SCLogDebug(
"regular packet %"PRIu64
" from same sender as "
4920 "the previous RST. Looks like it injected!", p->
pcap_cnt);
4951 TcpStream *stream = NULL, *ostream = NULL;
4962 if (ack == ostream->last_ack &&
seq == (stream->
next_seq - 1)) {
4978 TcpStream *stream = NULL, *ostream = NULL;
5007 if (pkt_win != ostream->window)
5016 SCLogDebug(
"seq %u (%u), ack %u (%u) FLAG_KEEPALIVE: %s",
seq, stream->
next_seq, ack, ostream->last_ack,
5046 TcpStream *stream = NULL, *ostream = NULL;
5078 if (pkt_win == ostream->window)
5081 if (ack == ostream->last_ack &&
seq == stream->
next_seq) {
5096 TcpStream *stream = NULL, *ostream = NULL;
5120 SCLogDebug(
"%"PRIu64
", seq %u ack %u stream->next_seq %u ostream->next_seq %u",
5148 TcpStream *stream = NULL, *ostream = NULL;
5175 if (pkt_win < ostream->window) {
5176 uint32_t diff = ostream->window - pkt_win;
5178 SEQ_GT(ack, ostream->next_seq) &&
5181 SCLogDebug(
"%"PRIu64
", pkt_win %u, stream win %u, diff %u, dsize %u",
5183 SCLogDebug(
"%"PRIu64
", pkt_win %u, stream win %u",
5184 p->
pcap_cnt, pkt_win, ostream->window);
5185 SCLogDebug(
"%"PRIu64
", seq %u ack %u ostream->next_seq %u ostream->last_ack %u, ostream->next_win %u, diff %u (%u)",
5186 p->
pcap_cnt,
seq, ack, ostream->next_seq, ostream->last_ack, ostream->next_win,
5187 ostream->next_seq - ostream->last_ack, stream->
next_seq - stream->
last_ack);
5194 uint32_t adiff = ack - ostream->last_ack;
5195 if (((pkt_win > 1024) && (diff > (adiff + 32))) ||
5196 ((pkt_win <= 1024) && (diff > adiff)))
5198 SCLogDebug(
"pkt ACK %u is %u bytes beyond last_ack %u, shrinks window by %u "
5199 "(allowing 32 bytes extra): pkt WIN %u", ack, adiff, ostream->last_ack, diff, pkt_win);
5200 SCLogDebug(
"%u - %u = %u (state %u)", diff, adiff, diff - adiff, ssn->
state);
5215 static inline int StreamTcpStateDispatch(
5223 SCLogDebug(
"packet received on TCP_SYN_SENT state");
5224 if (StreamTcpPacketStateSynSent(
tv, p, stt, ssn)) {
5229 SCLogDebug(
"packet received on TCP_SYN_RECV state");
5230 if (StreamTcpPacketStateSynRecv(
tv, p, stt, ssn)) {
5235 SCLogDebug(
"packet received on TCP_ESTABLISHED state");
5236 if (StreamTcpPacketStateEstablished(
tv, p, stt, ssn)) {
5241 SCLogDebug(
"packet received on TCP_FIN_WAIT1 state");
5242 if (StreamTcpPacketStateFinWait1(
tv, p, stt, ssn)) {
5247 SCLogDebug(
"packet received on TCP_FIN_WAIT2 state");
5248 if (StreamTcpPacketStateFinWait2(
tv, p, stt, ssn)) {
5253 SCLogDebug(
"packet received on TCP_CLOSING state");
5254 if (StreamTcpPacketStateClosing(
tv, p, stt, ssn)) {
5259 SCLogDebug(
"packet received on TCP_CLOSE_WAIT state");
5260 if (StreamTcpPacketStateCloseWait(
tv, p, stt, ssn)) {
5265 SCLogDebug(
"packet received on TCP_LAST_ACK state");
5266 if (StreamTcpPacketStateLastAck(
tv, p, stt, ssn)) {
5271 SCLogDebug(
"packet received on TCP_TIME_WAIT state");
5272 if (StreamTcpPacketStateTimeWait(
tv, p, stt, ssn)) {
5278 SCLogDebug(
"packet received on closed state");
5280 if (StreamTcpPacketStateClosed(
tv, p, stt, ssn)) {
5286 SCLogDebug(
"packet received on default state");
5336 SCLogDebug(
"ssn %p: removing ASYNC flag as we have packets on both sides", ssn);
5350 if (StreamTcpCheckFlowDrops(p) == 1) {
5360 if (StreamTcpPacketStateNone(
tv, p, stt, ssn) == -1) {
5388 if (StreamTcpPacketIsKeepAlive(ssn, p) == 1) {
5391 if (StreamTcpPacketIsKeepAliveACK(ssn, p) == 1) {
5392 StreamTcpClearKeepAliveFlag(ssn, p);
5395 StreamTcpClearKeepAliveFlag(ssn, p);
5397 const bool is_zwp_ack = StreamTcpPacketIsZeroWindowProbeAck(ssn, p);
5408 if (StreamTcpPacketIsDupAck(ssn, p) ==
true) {
5415 if (StreamTcpPacketIsFinShutdownAck(ssn, p) == 0) {
5416 if (StreamTcpPacketIsWindowUpdate(ssn, p) == 0) {
5417 if (StreamTcpPacketIsBadWindowUpdate(ssn,p))
5419 if (StreamTcpPacketIsOutdatedAck(ssn, p))
5424 int ret = StreamTcpPacketIsSpuriousRetransmission(ssn, p);
5433 if (StreamTcpStateDispatch(
tv, p, stt, ssn, ssn->
state) < 0)
5437 StreamTcpPacketCheckPostRst(ssn, p);
5486 SCLogDebug(
"bypass as stream is dead and we have no rules");
5499 if (StreamTcpInlineDropInvalid()) {
5503 DecodeSetNoPayloadInspectionFlag(p);
5517 static inline int StreamTcpValidateChecksum(
Packet *p)
5527 (uint16_t *)p->
tcph,
5533 (uint16_t *)p->
tcph,
5555 static int TcpSessionPacketIsStreamStarter(
const Packet *p)
5584 SCLogDebug(
"steam starter packet %" PRIu64
", ssn %p null. Reuse.", p->
pcap_cnt, ssn);
5589 ", ssn %p. STREAMTCP_FLAG_TFO_DATA_IGNORED set. Reuse.",
5594 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->
pcap_cnt, ssn);
5598 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5601 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5604 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5614 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5617 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5620 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5633 static int TcpSessionReuseDoneEnoughSynAck(
const Packet *p,
const Flow *f,
const TcpSession *ssn)
5637 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p null. No reuse.", p->
pcap_cnt, ssn);
5641 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p. Packet SEQ == Stream ISN. Retransmission. Don't reuse.", p->
pcap_cnt, ssn);
5645 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5648 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5651 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5661 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state >= TCP_LAST_ACK (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5664 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state == TCP_NONE (%u). Reuse.", p->
pcap_cnt, ssn, ssn->
state);
5667 SCLogDebug(
"steam starter packet %"PRIu64
", ssn %p state < TCP_LAST_ACK (%u). Don't reuse.", p->
pcap_cnt, ssn, ssn->
state);
5684 return TcpSessionReuseDoneEnoughSyn(p, f, ssn);
5689 return TcpSessionReuseDoneEnoughSynAck(p, f, ssn);
5698 if (p->
proto == IPPROTO_TCP && p->
tcph != NULL) {
5699 if (TcpSessionPacketIsStreamStarter(p) == 1) {
5700 if (TcpSessionReuseDoneEnough(p, f, tcp_ssn) == 1) {
5727 HandleThreadId(
tv, p, stt);
5733 if (StreamTcpValidateChecksum(p) == 0) {
5759 *data = (
void *)stt;
5790 SCLogDebug(
"StreamTcp thread specific ctx online at %p, reassembly ctx %p",
5799 StreamTcpSessionPoolAlloc,
5800 StreamTcpSessionPoolInit, NULL,
5801 StreamTcpSessionPoolCleanup, NULL);
5811 SCLogError(
"failed to setup/expand stream session pool. Expand stream.memcap?");
5862 if (!StreamTcpValidateTimestamp(ssn, p)) {
5892 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
5905 SCLogDebug(
"ssn %p: rejecting because of invalid ack value", ssn);
5918 receiver_stream = &ssn->
server;
5920 receiver_stream = &ssn->
client;
5922 SCLogDebug(
"ssn %p: setting STREAMTCP_STREAM_FLAG_RST_RECV on receiver stream", ssn);
5942 switch (os_policy) {
5946 SCLogDebug(
"reset is Valid! Packet SEQ: %" PRIu32
"",
5950 SCLogDebug(
"reset is not Valid! Packet SEQ: %" PRIu32
" "
5957 SCLogDebug(
"reset is valid! Packet SEQ: %" PRIu32
"",
5961 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" "
5978 SCLogDebug(
"reset is Valid! Packet SEQ: %" PRIu32
"",
5983 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" and"
5995 SCLogDebug(
"reset is Valid! Packet SEQ: %" PRIu32
"",
6000 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" and"
6019 SCLogDebug(
"reset is valid! Packet SEQ: %" PRIu32
"",
6023 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" "
6030 SCLogDebug(
"reset is valid! Packet SEQ: %" PRIu32
" Stream %u",
6034 SCLogDebug(
"reset is not valid! Packet SEQ: %" PRIu32
" and"
6035 " client SEQ: %" PRIu32
"",
6066 uint8_t check_ts = 1;
6069 sender_stream = &ssn->
client;
6070 receiver_stream = &ssn->
server;
6072 sender_stream = &ssn->
server;
6073 receiver_stream = &ssn->
client;
6084 uint32_t last_pkt_ts = sender_stream->
last_pkt_ts;
6085 uint32_t last_ts = sender_stream->
last_ts;
6135 SCLogDebug(
"ts %"PRIu32
", last_ts %"PRIu32
"",
ts, last_ts);
6139 result = (int32_t) ((
ts - last_ts) + 1);
6141 result = (int32_t) (
ts - last_ts);
6144 SCLogDebug(
"result %" PRIi32
", p->ts(secs) %" PRIuMAX
"", result,
6147 if (last_pkt_ts == 0 &&
6155 "%" PRIu32
" p->tcpvars->ts %" PRIu32
" result "
6156 "%" PRId32
"", last_ts,
ts, result);
6159 }
else if ((sender_stream->
last_ts != 0) &&
6161 SCLogDebug(
"packet is not valid last_pkt_ts "
6162 "%" PRIu32
" p->ts(sec) %" PRIu32
"",
6174 SCLogDebug(
"timestamp considered valid anyway");
6206 uint8_t check_ts = 1;
6209 sender_stream = &ssn->
client;
6210 receiver_stream = &ssn->
server;
6212 sender_stream = &ssn->
server;
6213 receiver_stream = &ssn->
client;
6281 result = (int32_t) ((
ts - sender_stream->
last_ts) + 1);
6283 result = (int32_t) (
ts - sender_stream->
last_ts);
6286 SCLogDebug(
"result %" PRIi32
", p->ts(sec) %" PRIuMAX
"", result,
6296 SCLogDebug(
"timestamp is not valid sender_stream->last_ts "
6297 "%" PRIu32
" p->tcpvars->ts %" PRIu32
" result "
6298 "%" PRId32
"", sender_stream->
last_ts,
ts, result);
6301 }
else if ((sender_stream->
last_ts != 0) &&
6304 SCLogDebug(
"packet is not valid sender_stream->last_pkt_ts "
6305 "%" PRIu32
" p->ts(sec) %" PRIu32
"",
6319 }
else if (ret == 0) {
6329 SCLogDebug(
"timestamp considered valid anyway");
6392 SCLogDebug(
"ACK %"PRIu32
" is before last_ack %"PRIu32
" - window "
6393 "%"PRIu32
" = %"PRIu32, ack, stream->
last_ack,
6417 SCLogDebug(
"default path leading to invalid: ACK %"PRIu32
", last_ack %"PRIu32
6430 const uint32_t progress)
6488 static void StreamTcpPseudoPacketCreateDetectLogFlush(
ThreadVars *
tv,
6507 np->
proto = IPPROTO_TCP;
6508 FlowReference(&np->
flow, f);
6518 DecodeSetNoPacketInspectionFlag(np);
6521 DecodeSetNoPayloadInspectionFlag(np);
6567 np->
ip4h->s_ip_src.s_addr = f->
src.addr_data32[0];
6568 np->
ip4h->s_ip_dst.s_addr = f->
dst.addr_data32[0];
6570 np->
ip4h->s_ip_src.s_addr = f->
dst.addr_data32[0];
6571 np->
ip4h->s_ip_dst.s_addr = f->
src.addr_data32[0];
6603 np->
ip6h->s_ip6_vfc = 0x60;
6604 np->
ip6h->s_ip6_flow = 0;
6605 np->
ip6h->s_ip6_nxt = IPPROTO_TCP;
6606 np->
ip6h->s_ip6_plen = htons(20);
6607 np->
ip6h->s_ip6_hlim = 64;
6609 np->
ip6h->s_ip6_src[0] = f->
src.addr_data32[0];
6610 np->
ip6h->s_ip6_src[1] = f->
src.addr_data32[1];
6611 np->
ip6h->s_ip6_src[2] = f->
src.addr_data32[2];
6612 np->
ip6h->s_ip6_src[3] = f->
src.addr_data32[3];
6613 np->
ip6h->s_ip6_dst[0] = f->
dst.addr_data32[0];
6614 np->
ip6h->s_ip6_dst[1] = f->
dst.addr_data32[1];
6615 np->
ip6h->s_ip6_dst[2] = f->
dst.addr_data32[2];
6616 np->
ip6h->s_ip6_dst[3] = f->
dst.addr_data32[3];
6618 np->
ip6h->s_ip6_src[0] = f->
dst.addr_data32[0];
6619 np->
ip6h->s_ip6_src[1] = f->
dst.addr_data32[1];
6620 np->
ip6h->s_ip6_src[2] = f->
dst.addr_data32[2];
6621 np->
ip6h->s_ip6_src[3] = f->
dst.addr_data32[3];
6622 np->
ip6h->s_ip6_dst[0] = f->
src.addr_data32[0];
6623 np->
ip6h->s_ip6_dst[1] = f->
src.addr_data32[1];
6624 np->
ip6h->s_ip6_dst[2] = f->
src.addr_data32[2];
6625 np->
ip6h->s_ip6_dst[3] = f->
src.addr_data32[3];
6634 np->
tcph->th_offx2 = 0x50;
6636 np->
tcph->th_win = 10;
6637 np->
tcph->th_urp = 0;
6641 np->
tcph->th_sport = htons(f->
sp);
6642 np->
tcph->th_dport = htons(f->
dp);
6649 np->
tcph->th_sport = htons(f->
dp);
6650 np->
tcph->th_dport = htons(f->
sp);
6657 np->
ts = parent->
ts;
6665 FlowDeReference(&np->
flow);
6684 StreamTcpPseudoPacketCreateDetectLogFlush(
tv, stt, p, ssn, pq,
ts^0);
6685 StreamTcpPseudoPacketCreateDetectLogFlush(
tv, stt, p, ssn, pq,
ts^1);
6705 if (p->
flow == NULL)
6733 const uint8_t *seg_data;
6734 uint32_t seg_datalen;
6737 int ret = CallbackFunc(p, seg, data, seg_data, seg_datalen);
6765 if (p->
flow == NULL)
6779 if (server_node == NULL && client_node == NULL) {
6783 while (server_node != NULL || client_node != NULL) {
6784 const uint8_t *seg_data;
6785 uint32_t seg_datalen;
6786 if (server_node == NULL) {
6793 &client_stream->
sb, &client_node->
sbseg, &seg_data, &seg_datalen);
6794 ret = CallbackFunc(p, client_node, data, seg_data, seg_datalen);
6799 client_node = TCPSEG_RB_NEXT(client_node);
6800 }
else if (client_node == NULL) {
6807 &server_stream->
sb, &server_node->
sbseg, &seg_data, &seg_datalen);
6808 ret = CallbackFunc(p, server_node, data, seg_data, seg_datalen);
6813 server_node = TCPSEG_RB_NEXT(server_node);
6818 &client_stream->
sb, &client_node->
sbseg, &seg_data, &seg_datalen);
6819 ret = CallbackFunc(p, client_node, data, seg_data, seg_datalen);
6824 client_node = TCPSEG_RB_NEXT(client_node);
6827 &server_stream->
sb, &server_node->
sbseg, &seg_data, &seg_datalen);
6828 ret = CallbackFunc(p, server_node, data, seg_data, seg_datalen);
6833 server_node = TCPSEG_RB_NEXT(server_node);
6870 const char *tcp_state = NULL;
6876 tcp_state =
"syn_sent";
6879 tcp_state =
"syn_recv";
6882 tcp_state =
"established";
6885 tcp_state =
"fin_wait1";
6888 tcp_state =
"fin_wait2";
6891 tcp_state =
"time_wait";
6894 tcp_state =
"last_ack";
6897 tcp_state =
"close_wait";
6900 tcp_state =
"closing";
6903 tcp_state =
"closed";