f->fb = NULL;
FBLOCK_UNLOCK(fb);
+ int state = FlowGetFlowState(f);
+ if (state == FLOW_STATE_NEW)
+ f->flow_end_flags |= FLOW_END_FLAG_STATE_NEW;
+ else if (state == FLOW_STATE_ESTABLISHED)
+ f->flow_end_flags |= FLOW_END_FLAG_STATE_ESTABLISHED;
+ else if (state == FLOW_STATE_CLOSED)
+ f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED;
+
+ f->flow_end_flags |= FLOW_END_FLAG_FORCED;
+
+ if (SC_ATOMIC_GET(flow_flags) & FLOW_EMERGENCY)
+ f->flow_end_flags |= FLOW_END_FLAG_EMERGENCY;
+
/* invoke flow log api */
if (dtv && dtv->output_flow_thread_data)
(void)OutputFlowLog(tv, dtv->output_flow_thread_data, f);
f->hnext = NULL;
f->hprev = NULL;
+ if (state == FLOW_STATE_NEW)
+ f->flow_end_flags |= FLOW_END_FLAG_STATE_NEW;
+ else if (state == FLOW_STATE_ESTABLISHED)
+ f->flow_end_flags |= FLOW_END_FLAG_STATE_ESTABLISHED;
+ else if (state == FLOW_STATE_CLOSED)
+ f->flow_end_flags |= FLOW_END_FLAG_STATE_CLOSED;
+
+ if (emergency)
+ f->flow_end_flags |= FLOW_END_FLAG_EMERGENCY;
+ f->flow_end_flags |= FLOW_END_FLAG_TIMEOUT;
+
// FlowClearMemory (f, f->protomap);
/* no one is referring to this flow, use_cnt 0, removed from hash
(f)->lastts.tv_usec = 0; \
FLOWLOCK_INIT((f)); \
(f)->protoctx = NULL; \
+ (f)->flow_end_flags = 0; \
(f)->alproto = 0; \
(f)->alproto_ts = 0; \
(f)->alproto_tc = 0; \
(f)->lastts.tv_sec = 0; \
(f)->lastts.tv_usec = 0; \
(f)->protoctx = NULL; \
+ (f)->flow_end_flags = 0; \
(f)->alparser = NULL; \
(f)->alstate = NULL; \
(f)->alproto = 0; \
/** \todo only used by flow keyword internally. */
#define FLOW_PKT_ONLYSTREAM 0x80
+#define FLOW_END_FLAG_STATE_NEW 0x01
+#define FLOW_END_FLAG_STATE_ESTABLISHED 0x02
+#define FLOW_END_FLAG_STATE_CLOSED 0x04
+#define FLOW_END_FLAG_EMERGENCY 0x08
+#define FLOW_END_FLAG_TIMEOUT 0x10
+#define FLOW_END_FLAG_FORCED 0x20
+
/** Mutex or RWLocks for the flow. */
//#define FLOWLOCK_RWLOCK
#define FLOWLOCK_MUTEX
/** mapping to Flow's protocol specific protocols for timeouts
and state and free functions. */
uint8_t protomap;
- uint8_t pad0;
+
+ uint8_t flow_end_flags;
+ /* coccinelle: Flow:flow_end_flags:FLOW_END_FLAG_ */
AppProto alproto; /**< \brief application level protocol */
AppProto alproto_ts;
json_object_set_new(hjs, "age",
json_integer(age));
+ if (f->flow_end_flags & FLOW_END_FLAG_EMERGENCY)
+ json_object_set_new(hjs, "emergency", json_true());
+ const char *state = NULL;
+ if (f->flow_end_flags & FLOW_END_FLAG_STATE_NEW)
+ state = "new";
+ else if (f->flow_end_flags & FLOW_END_FLAG_STATE_ESTABLISHED)
+ state = "established";
+ else if (f->flow_end_flags & FLOW_END_FLAG_STATE_CLOSED)
+ state = "closed";
+
+ json_object_set_new(hjs, "state",
+ json_string(state));
+
+ const char *reason = NULL;
+ if (f->flow_end_flags & FLOW_END_FLAG_TIMEOUT)
+ reason = "timeout";
+ else if (f->flow_end_flags & FLOW_END_FLAG_FORCED)
+ reason = "forced";
+
+ json_object_set_new(hjs, "reason",
+ json_string(reason));
json_object_set_new(js, "flow", hjs);