]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
flow/stream: 'wrong thread' as stream event & counter
authorVictor Julien <victor@inliniac.net>
Fri, 5 Oct 2018 18:38:10 +0000 (20:38 +0200)
committerVictor Julien <victor@inliniac.net>
Sun, 21 Oct 2018 13:27:29 +0000 (15:27 +0200)
Set event at most once per flow, for the first 'wrong' packet.

Add 'tcp.pkt_on_wrong_thread' counter. This is incremented for each
'wrong' packet. Note that the first packet for a flow determines
what thread is 'correct'.

rules/stream-events.rules
src/decode-events.c
src/decode-events.h
src/flow.h
src/output-json-flow.c
src/stream-tcp.c
src/stream-tcp.h

index 65991013935c248ff8f512f1eb30370d0938ec28..7ea3261862b7e12fab27c59dc065bd7c30449bef 100644 (file)
@@ -88,6 +88,8 @@ alert tcp any any -> any any (msg:"SURICATA STREAM reassembly segment before bas
 alert tcp any any -> any any (msg:"SURICATA STREAM Packet is retransmission"; stream-event:pkt_retransmission; flowint:tcp.retransmission.count,+,1; noalert; classtype:protocol-command-decode; sid:2210053; rev:1;)
 # rule to alert if a stream has excessive retransmissions
 alert tcp any any -> any any (msg:"SURICATA STREAM excessive retransmissions"; flowbits:isnotset,tcp.retransmission.alerted; flowint:tcp.retransmission.count,>=,10; flowbits:set,tcp.retransmission.alerted; classtype:protocol-command-decode; sid:2210054; rev:1;)
+# Packet on wrong thread. Fires at most once per flow.
+alert tcp any any -> any any (msg:"SURICATA STREAM pkt seen on wrong thread"; stream-event:wrong_thread; sid:2210059; rev:1;)
 
-# next sid 2210059
+# next sid 2210060
 
index 54d47f3d94c4c215dacbaa2fc966d67c5f6efa6e..4da27aee30cd263c3ada42b5f9442f65eb5728d0 100644 (file)
@@ -240,6 +240,7 @@ const struct DecodeEvents_ DEvents[] = {
     { "stream.pkt_bad_window_update", STREAM_PKT_BAD_WINDOW_UPDATE, },
 
     { "stream.suspected_rst_inject", STREAM_SUSPECTED_RST_INJECT, },
+    { "stream.wrong_thread", STREAM_WRONG_THREAD, },
 
     { "stream.reassembly_segment_before_base_seq", STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ, },
     { "stream.reassembly_no_segment", STREAM_REASSEMBLY_NO_SEGMENT, },
index 40cfa73f19fa49e0ed29bfe2443f5c28fb0fcc1f..3afe4b51f484f3f20595240321138b1993f71f74 100644 (file)
@@ -250,6 +250,7 @@ enum {
     STREAM_PKT_BAD_WINDOW_UPDATE,
 
     STREAM_SUSPECTED_RST_INJECT,
+    STREAM_WRONG_THREAD,
 
     STREAM_REASSEMBLY_SEGMENT_BEFORE_BASE_SEQ,
     STREAM_REASSEMBLY_NO_SEGMENT,
index 008ee01ad70c987c56b8b3d18b5578799fa9dda6..0262f74bed94bad2d33c3109adf07ee75f96bb87 100644 (file)
@@ -100,6 +100,8 @@ typedef struct AppLayerParserState_ AppLayerParserState;
 /** Indicate that alproto detection for flow should be done again */
 #define FLOW_CHANGE_PROTO               BIT_U32(24)
 
+#define FLOW_WRONG_THREAD               BIT_U32(25)
+
 /* File flags */
 
 /** no magic on files in this flow */
index d5a34a22b266aea981dbafe8ae546c4b888104e2..0eb31145c0910bea67de06f1234fbc407c8befac 100644 (file)
@@ -274,6 +274,8 @@ static void JsonFlowLogJSON(JsonFlowLogThread *aft, json_t *js, Flow *f)
             json_string(reason));
 
     json_object_set_new(hjs, "alerted", json_boolean(FlowHasAlerts(f)));
+    if (f->flags & FLOW_WRONG_THREAD)
+        json_object_set_new(hjs, "wrong_thread", json_true());
 
     json_object_set_new(js, "flow", hjs);
 
index d3b6aaec4174c6c061bad45108f1767544277d54..0be74760a97bbb997dc18e4a521a5fca1c059032 100644 (file)
@@ -4679,10 +4679,15 @@ int StreamTcpPacket (ThreadVars *tv, Packet *p, StreamTcpThread *stt,
     /* assign the thread id to the flow */
     if (unlikely(p->flow->thread_id == 0)) {
         p->flow->thread_id = (FlowThreadId)tv->id;
-#ifdef DEBUG
     } else if (unlikely((FlowThreadId)tv->id != p->flow->thread_id)) {
         SCLogDebug("wrong thread: flow has %u, we are %d", p->flow->thread_id, tv->id);
-#endif
+        if (p->pkt_src == PKT_SRC_WIRE) {
+            StatsIncr(tv, stt->counter_tcp_wrong_thread);
+            if ((p->flow->flags & FLOW_WRONG_THREAD) == 0) {
+                p->flow->flags |= FLOW_WRONG_THREAD;
+                StreamTcpSetEvent(p, STREAM_WRONG_THREAD);
+            }
+        }
     }
 
     TcpSession *ssn = (TcpSession *)p->flow->protoctx;
@@ -5144,6 +5149,7 @@ TmEcode StreamTcpThreadInit(ThreadVars *tv, void *initdata, void **data)
     stt->counter_tcp_synack = StatsRegisterCounter("tcp.synack", tv);
     stt->counter_tcp_rst = StatsRegisterCounter("tcp.rst", tv);
     stt->counter_tcp_midstream_pickups = StatsRegisterCounter("tcp.midstream_pickups", tv);
+    stt->counter_tcp_wrong_thread = StatsRegisterCounter("tcp.pkt_on_wrong_thread", tv);
 
     /* init reassembly ctx */
     stt->ra_ctx = StreamTcpReassembleInitThreadCtx(tv);
index 7aae41f584e6fed8577dde0a4414215c1fd8679e..bf383ff0f237fb1887a06f0843266661b2f41582 100644 (file)
@@ -96,6 +96,8 @@ typedef struct StreamTcpThread_ {
     uint16_t counter_tcp_rst;
     /** midstream pickups */
     uint16_t counter_tcp_midstream_pickups;
+    /** wrong thread */
+    uint16_t counter_tcp_wrong_thread;
 
     /** tcp reassembly thread data */
     TcpReassemblyThreadCtx *ra_ctx;