Project

General

Profile

Actions

Documentation #6404

open

flow.reason value is misleading?

Added by Sascha Steinbiss about 1 year ago. Updated 6 months ago.

Status:
New
Priority:
Normal
Assignee:
Target version:
Affected Versions:
Effort:
Difficulty:
Label:

Description

Just noticed that we have flow EVE events with flow.reason being timeout for traffic that should not have timeouted (and according to the stats likely didn't), with flow.state@s ranging from @new over closed, established to bypassed. What values would normally be expected here? I can confirm that we can see traffic from both directions on the machines in question.

Maybe I am misunderstanding something. Let's reproduce it: Consider https://storage.googleapis.com/tenzir-datasets/M57/PCAP/data.pcap replayed via a dummy interface:

$ sudo ip link add dummy0 type dummy 

$ sudo tcpreplay -i dummy0 -M500 ~/Downloads/data.pcap
[...]
Actual: 6402440 packets (3816702597 bytes) sent in 61.47 seconds
Rated: 62087462.7 Bps, 496.69 Mbps, 104150.44 pps
Flows: 656212 flows, 10674.78 fps, 6340962 unique flow packets, 55491 unique non-flow packets
Statistics for network device: dummy0
    Successful packets:        6402440
    Failed packets:            4363
    Truncated packets:         0
    Retried packets (ENOBUFS): 0
    Retried packets (EAGAIN):  0

and with default settings (and waiting 600s after finishing the replay) we get (for 6.x branch):
$ rm eve.json; sudo ./src/.libs/suricata -c suricata.yaml -i dummy0 -l .
[...]

6.0.14:
$ cat eve.json | jq 'select(.event_type == "flow") .flow.reason' | sort | uniq -c 
   1134 "shutdown" 
 563737 "timeout" 

6.0.2:
 $ cat eve.json | jq 'select(.event_type == "flow") .flow.reason' | sort | uniq -c
   1290 "shutdown" 
  49865 "timeout" 
 513718 "unknown" 

7.0.1:
$ cat eve.json | jq 'select(.event_type == "flow") .flow.reason' | sort | uniq -c
 455350 "timeout" 

Looking at https://github.com/OISF/suricata/blob/master/src/output-json-flow.c#L260:

    const char *reason = NULL;
    if (f->flow_end_flags & FLOW_END_FLAG_FORCED)
        reason = "forced";
    else if (f->flow_end_flags & FLOW_END_FLAG_SHUTDOWN)
        reason = "shutdown";
    else if (f->flow_end_flags & FLOW_END_FLAG_TIMEOUT)
        reason = "timeout";
    else
        reason = "unknown";

    jb_set_string(jb, "reason", reason);

there are only these four, none of which sound like they describe a flow that ended up, say, in a closed state due to being correctly closed through TCP means. (For UDP, I could understand that such a "flow" would always be closed through timeout, since there is no connection state to consider).

Are reason and state always supposed to be read together, and the value of reason only makes sense for specific state values? Maybe someone could give some background.

Actions

Also available in: Atom PDF