• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OISF / suricata / 23374838686

21 Mar 2026 07:29AM UTC coverage: 59.341% (-20.0%) from 79.315%
23374838686

Pull #15075

github

web-flow
Merge 90b4e834f into 6587e363a
Pull Request #15075: Stack 8001 v16.4

38 of 70 new or added lines in 10 files covered. (54.29%)

34165 existing lines in 563 files now uncovered.

119621 of 201584 relevant lines covered (59.34%)

650666.92 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.45
/src/flow.h
1
/* Copyright (C) 2007-2025 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17

18
/**
19
 *  \file
20
 *
21
 *  \author Victor Julien <victor@inliniac.net>
22
 */
23

24
#ifndef SURICATA_FLOW_H
25
#define SURICATA_FLOW_H
26

27
/* forward declaration for macset include */
28
typedef struct FlowStorageId FlowStorageId;
29

30
#include "decode.h"
31
#include "util-time.h"
32
#include "util-exception-policy.h"
33
#include "util-exception-policy-types.h"
34
#include "util-var.h"
35
#include "util-optimize.h"
36
#include "util-validate.h"
37
#include "app-layer-protos.h"
38

39
/* Part of the flow structure, so we declare it here.
40
 * The actual declaration is in app-layer-parser.c */
41
typedef struct AppLayerParserState_ AppLayerParserState;
42

43
#define FLOW_QUIET true
4✔
44

45
#define TOSERVER 0
2,662,943✔
46
#define TOCLIENT 1
1,170,487✔
47

48
/* per flow flags */
49

50
/** At least one packet from the source address was seen */
51
#define FLOW_TO_SRC_SEEN BIT_U64(0)
798,055✔
52
/** At least one packet from the destination address was seen */
53
#define FLOW_TO_DST_SEEN BIT_U64(1)
966,704✔
54

55
/** next packet in toclient direction will act on updated app-layer state */
56
#define FLOW_TC_APP_UPDATE_NEXT BIT_U64(2)
1,071,527✔
57

58
/** Flow is marked an elephant flow */
59
#define FLOW_IS_ELEPHANT_TOSERVER BIT_U64(3)
9,384✔
60
#define FLOW_IS_ELEPHANT_TOCLIENT BIT_U64(4)
9,384✔
61

62
/** All packets in this flow should be accepted */
63
#define FLOW_ACTION_ACCEPT BIT_U64(5)
33,550✔
64

65
/** Packet payloads belonging to this flow should not be inspected */
66
#define FLOW_NOPAYLOAD_INSPECTION BIT_U64(6)
1,863,060✔
67

68
/** All packets in this flow should be dropped */
69
#define FLOW_ACTION_DROP BIT_U64(7)
3,821,701✔
70

71
/** Sgh for toserver direction set (even if it's NULL) */
72
#define FLOW_SGH_TOSERVER BIT_U64(8)
922,422✔
73
/** Sgh for toclient direction set (even if it's NULL) */
74
#define FLOW_SGH_TOCLIENT BIT_U64(9)
2,096,996✔
75

76
/** packet to server direction has been logged in drop file (only in IPS mode) */
UNCOV
77
#define FLOW_TOSERVER_DROP_LOGGED BIT_U64(10)
×
78
/** packet to client direction has been logged in drop file (only in IPS mode) */
UNCOV
79
#define FLOW_TOCLIENT_DROP_LOGGED BIT_U64(11)
×
80

81
/** flow has alerts */
82
#define FLOW_HAS_ALERTS BIT_U64(12)
86,887✔
83

84
/** Pattern matcher alproto detection done */
85
#define FLOW_TS_PM_ALPROTO_DETECT_DONE BIT_U64(13)
174,386✔
86
/** Probing parser alproto detection done */
87
#define FLOW_TS_PP_ALPROTO_DETECT_DONE BIT_U64(14)
88,630✔
88
/** Expectation alproto detection done */
89
#define FLOW_TS_PE_ALPROTO_DETECT_DONE BIT_U64(15)
49,242✔
90
/** Pattern matcher alproto detection done */
91
#define FLOW_TC_PM_ALPROTO_DETECT_DONE BIT_U64(16)
102,835✔
92
/** Probing parser alproto detection done */
93
#define FLOW_TC_PP_ALPROTO_DETECT_DONE BIT_U64(17)
72,530✔
94
/** Expectation alproto detection done */
95
#define FLOW_TC_PE_ALPROTO_DETECT_DONE BIT_U64(18)
34,039✔
96
#define FLOW_TIMEOUT_REASSEMBLY_DONE   BIT_U64(19)
17,923✔
97

98
/** flow is ipv4 */
99
#define FLOW_IPV4 BIT_U64(20)
212,454✔
100
/** flow is ipv6 */
101
#define FLOW_IPV6 BIT_U64(21)
18,046✔
102

103
#define FLOW_PROTO_DETECT_TS_DONE BIT_U64(22)
778,217✔
104
#define FLOW_PROTO_DETECT_TC_DONE BIT_U64(23)
630,080✔
105

106
/** Indicate that alproto detection for flow should be done again */
107
#define FLOW_CHANGE_PROTO BIT_U64(24)
3,735,205✔
108

109
#define FLOW_WRONG_THREAD BIT_U64(25)
1,102,396✔
110
/** Protocol detection told us flow is picked up in wrong direction (midstream) */
111
#define FLOW_DIR_REVERSED BIT_U64(26)
3,405,688✔
112
/** Indicate that the flow did trigger an expectation creation */
113
#define FLOW_HAS_EXPECTATION BIT_U64(27)
170✔
114

115
/** All packets in this flow should be passed */
116
#define FLOW_ACTION_PASS BIT_U64(28)
1,299,306✔
117

118
#define FLOW_TS_APP_UPDATED BIT_U64(29)
4,513,181✔
119
#define FLOW_TC_APP_UPDATED BIT_U64(30)
3,863,450✔
120

121
/** next packet in toserver direction will act on updated app-layer state */
122
#define FLOW_TS_APP_UPDATE_NEXT BIT_U64(31)
1,120,174✔
123

124
/* File flags */
125

126
#define FLOWFILE_INIT                   0
101,055✔
127

128
/** no magic on files in this flow */
129
#define FLOWFILE_NO_MAGIC_TS            BIT_U16(0)
463,985✔
130
#define FLOWFILE_NO_MAGIC_TC            BIT_U16(1)
387,294✔
131

132
/** even if the flow has files, don't store 'm */
133
#define FLOWFILE_NO_STORE_TS            BIT_U16(2)
790,441✔
134
#define FLOWFILE_NO_STORE_TC            BIT_U16(3)
610,340✔
135
/** no md5 on files in this flow */
136
#define FLOWFILE_NO_MD5_TS              BIT_U16(4)
467,583✔
137
#define FLOWFILE_NO_MD5_TC              BIT_U16(5)
390,892✔
138

139
/** no sha1 on files in this flow */
140
#define FLOWFILE_NO_SHA1_TS             BIT_U16(6)
467,583✔
141
#define FLOWFILE_NO_SHA1_TC             BIT_U16(7)
390,892✔
142

143
/** no sha256 on files in this flow */
144
#define FLOWFILE_NO_SHA256_TS           BIT_U16(8)
467,584✔
145
#define FLOWFILE_NO_SHA256_TC           BIT_U16(9)
390,893✔
146

147
// vacancy(2)
148

149
/** store files in the flow */
150
#define FLOWFILE_STORE_TS BIT_U16(12)
658,724✔
151
#define FLOWFILE_STORE_TC BIT_U16(13)
451,904✔
152

153
#define FLOWFILE_NONE_TS                                                                           \
154
    (FLOWFILE_NO_MAGIC_TS | FLOWFILE_NO_STORE_TS | FLOWFILE_NO_MD5_TS | FLOWFILE_NO_SHA1_TS |      \
82,781✔
155
            FLOWFILE_NO_SHA256_TS)
82,781✔
156
#define FLOWFILE_NONE_TC                                                                           \
157
    (FLOWFILE_NO_MAGIC_TC | FLOWFILE_NO_STORE_TC | FLOWFILE_NO_MD5_TC | FLOWFILE_NO_SHA1_TC |      \
109,500✔
158
            FLOWFILE_NO_SHA256_TC)
109,500✔
159
#define FLOWFILE_NONE    (FLOWFILE_NONE_TS|FLOWFILE_NONE_TC)
45,613✔
160

161
#define FLOW_IS_IPV4(f) \
162
    (((f)->flags & FLOW_IPV4) == FLOW_IPV4)
73,581✔
163
#define FLOW_IS_IPV6(f) \
164
    (((f)->flags & FLOW_IPV6) == FLOW_IPV6)
2,267✔
165

166
#define FLOW_GET_SP(f)  \
167
    ((f)->flags & FLOW_DIR_REVERSED) ? (f)->dp : (f)->sp;
54,764✔
168
#define FLOW_GET_DP(f)  \
169
    ((f)->flags & FLOW_DIR_REVERSED) ? (f)->sp : (f)->dp;
54,415✔
170

171
#define FLOW_COPY_IPV4_ADDR_TO_PACKET(fa, pa) do {      \
38,008✔
172
        (pa)->family = AF_INET;                         \
38,008✔
173
        (pa)->addr_data32[0] = (fa)->addr_data32[0];    \
38,008✔
174
    } while (0)
38,008✔
175

176
#define FLOW_COPY_IPV6_ADDR_TO_PACKET(fa, pa) do {      \
868✔
177
        (pa)->family = AF_INET6;                        \
868✔
178
        (pa)->addr_data32[0] = (fa)->addr_data32[0];    \
868✔
179
        (pa)->addr_data32[1] = (fa)->addr_data32[1];    \
868✔
180
        (pa)->addr_data32[2] = (fa)->addr_data32[2];    \
868✔
181
        (pa)->addr_data32[3] = (fa)->addr_data32[3];    \
868✔
182
    } while (0)
868✔
183

184
/* Set the IPv4 addressesinto the Addrs of the Packet.
185
 * Make sure p->ip4h is initialized and validated.
186
 *
187
 * We set the rest of the struct to 0 so we can
188
 * prevent using memset. */
189
#define FLOW_SET_IPV4_SRC_ADDR_FROM_PACKET(ip4h, a)                                                \
190
    do {                                                                                           \
57,558✔
191
        (a)->addr_data32[0] = (uint32_t)(ip4h)->s_ip_src.s_addr;                                   \
57,558✔
192
        (a)->addr_data32[1] = 0;                                                                   \
57,558✔
193
        (a)->addr_data32[2] = 0;                                                                   \
57,558✔
194
        (a)->addr_data32[3] = 0;                                                                   \
57,558✔
195
    } while (0)
57,558✔
196

197
#define FLOW_SET_IPV4_DST_ADDR_FROM_PACKET(ip4h, a)                                                \
198
    do {                                                                                           \
57,558✔
199
        (a)->addr_data32[0] = (uint32_t)(ip4h)->s_ip_dst.s_addr;                                   \
57,558✔
200
        (a)->addr_data32[1] = 0;                                                                   \
57,558✔
201
        (a)->addr_data32[2] = 0;                                                                   \
57,558✔
202
        (a)->addr_data32[3] = 0;                                                                   \
57,558✔
203
    } while (0)
57,558✔
204

205
/* Set the IPv6 addressesinto the Addrs of the Packet.
206
 * Make sure p->ip6h is initialized and validated. */
207
#define FLOW_SET_IPV6_SRC_ADDR_FROM_PACKET(ip6h, a)                                                \
208
    do {                                                                                           \
5,778✔
209
        (a)->addr_data32[0] = (ip6h)->s_ip6_src[0];                                                \
5,778✔
210
        (a)->addr_data32[1] = (ip6h)->s_ip6_src[1];                                                \
5,778✔
211
        (a)->addr_data32[2] = (ip6h)->s_ip6_src[2];                                                \
5,778✔
212
        (a)->addr_data32[3] = (ip6h)->s_ip6_src[3];                                                \
5,778✔
213
    } while (0)
5,778✔
214

215
#define FLOW_SET_IPV6_DST_ADDR_FROM_PACKET(ip6h, a)                                                \
216
    do {                                                                                           \
5,778✔
217
        (a)->addr_data32[0] = (ip6h)->s_ip6_dst[0];                                                \
5,778✔
218
        (a)->addr_data32[1] = (ip6h)->s_ip6_dst[1];                                                \
5,778✔
219
        (a)->addr_data32[2] = (ip6h)->s_ip6_dst[2];                                                \
5,778✔
220
        (a)->addr_data32[3] = (ip6h)->s_ip6_dst[3];                                                \
5,778✔
221
    } while (0)
5,778✔
222

223
/* pkt flow flags */
224
#define FLOW_PKT_TOSERVER               0x01
24,230,559✔
225
#define FLOW_PKT_TOCLIENT               0x02
9,388,270✔
226
#define FLOW_PKT_ESTABLISHED            0x04
1,115,138✔
227
#define FLOW_PKT_TOSERVER_FIRST         0x08
1,335,878✔
228
#define FLOW_PKT_TOCLIENT_FIRST         0x10
1,303,988✔
229
/** last pseudo packet in the flow. Can be used to trigger final clean,
230
 *  logging, etc. */
231
#define FLOW_PKT_LAST_PSEUDO 0x20
736,089✔
232

233
#define FLOW_END_FLAG_EMERGENCY 0x01
9,384✔
234
#define FLOW_END_FLAG_TIMEOUT   0x02
27,602✔
235
#define FLOW_END_FLAG_FORCED    0x04
8,834✔
236
#define FLOW_END_FLAG_SHUTDOWN  0x08
8,834✔
237
#define FLOW_END_FLAG_TCPREUSE  0x10
9,934✔
238

239
/** Mutex or RWLocks for the flow. */
240
//#define FLOWLOCK_RWLOCK
241
#define FLOWLOCK_MUTEX
242

243
#ifdef FLOWLOCK_RWLOCK
244
    #ifdef FLOWLOCK_MUTEX
245
        #error Cannot enable both FLOWLOCK_RWLOCK and FLOWLOCK_MUTEX
246
    #endif
247
#endif
248

249
#ifdef FLOWLOCK_RWLOCK
250
    #define FLOWLOCK_INIT(fb) SCRWLockInit(&(fb)->r, NULL)
251
    #define FLOWLOCK_DESTROY(fb) SCRWLockDestroy(&(fb)->r)
252
    #define FLOWLOCK_RDLOCK(fb) SCRWLockRDLock(&(fb)->r)
253
    #define FLOWLOCK_WRLOCK(fb) SCRWLockWRLock(&(fb)->r)
254
    #define FLOWLOCK_TRYRDLOCK(fb) SCRWLockTryRDLock(&(fb)->r)
255
    #define FLOWLOCK_TRYWRLOCK(fb) SCRWLockTryWRLock(&(fb)->r)
256
    #define FLOWLOCK_UNLOCK(fb) SCRWLockUnlock(&(fb)->r)
257
#elif defined FLOWLOCK_MUTEX
258
    #define FLOWLOCK_INIT(fb) SCMutexInit(&(fb)->m, NULL)
63,952✔
259
    #define FLOWLOCK_DESTROY(fb) SCMutexDestroy(&(fb)->m)
65,542✔
260
    #define FLOWLOCK_RDLOCK(fb) SCMutexLock(&(fb)->m)
261
    #define FLOWLOCK_WRLOCK(fb) SCMutexLock(&(fb)->m)
1,282,921✔
262
    #define FLOWLOCK_TRYRDLOCK(fb) SCMutexTrylock(&(fb)->m)
263
    #define FLOWLOCK_TRYWRLOCK(fb) SCMutexTrylock(&(fb)->m)
×
264
    #define FLOWLOCK_UNLOCK(fb) SCMutexUnlock(&(fb)->m)
1,282,921✔
265
#else
266
    #error Enable FLOWLOCK_RWLOCK or FLOWLOCK_MUTEX
267
#endif
268

269
#define FLOW_IS_PM_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags & FLOW_TS_PM_ALPROTO_DETECT_DONE) : ((f)->flags & FLOW_TC_PM_ALPROTO_DETECT_DONE))
335,598✔
270
#define FLOW_IS_PP_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags & FLOW_TS_PP_ALPROTO_DETECT_DONE) : ((f)->flags & FLOW_TC_PP_ALPROTO_DETECT_DONE))
223,354✔
271
#define FLOW_IS_PE_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags & FLOW_TS_PE_ALPROTO_DETECT_DONE) : ((f)->flags & FLOW_TC_PE_ALPROTO_DETECT_DONE))
50,203✔
272

273
#define FLOW_SET_PM_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags |= FLOW_TS_PM_ALPROTO_DETECT_DONE) : ((f)->flags |= FLOW_TC_PM_ALPROTO_DETECT_DONE))
76,014✔
274
#define FLOW_SET_PP_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags |= FLOW_TS_PP_ALPROTO_DETECT_DONE) : ((f)->flags |= FLOW_TC_PP_ALPROTO_DETECT_DONE))
25,716✔
275
#define FLOW_SET_PE_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags |= FLOW_TS_PE_ALPROTO_DETECT_DONE) : ((f)->flags |= FLOW_TC_PE_ALPROTO_DETECT_DONE))
29,971✔
276

277
#define FLOW_RESET_PM_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags &= ~FLOW_TS_PM_ALPROTO_DETECT_DONE) : ((f)->flags &= ~FLOW_TC_PM_ALPROTO_DETECT_DONE))
3,107✔
278
#define FLOW_RESET_PP_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags &= ~FLOW_TS_PP_ALPROTO_DETECT_DONE) : ((f)->flags &= ~FLOW_TC_PP_ALPROTO_DETECT_DONE))
3,767✔
279
#define FLOW_RESET_PE_DONE(f, dir) (((dir) & STREAM_TOSERVER) ? ((f)->flags &= ~FLOW_TS_PE_ALPROTO_DETECT_DONE) : ((f)->flags &= ~FLOW_TC_PE_ALPROTO_DETECT_DONE))
3,107✔
280

281
/* global flow config */
282
typedef struct FlowCnf_
283
{
284
    uint32_t hash_rand;
285
    uint32_t hash_size;
286
    uint32_t prealloc;
287

288
    uint32_t timeout_new;
289
    uint32_t timeout_est;
290

291
    uint32_t emergency_recovery;
292

293
    enum ExceptionPolicy memcap_policy;
294

295
    SC_ATOMIC_DECLARE(uint64_t, memcap);
296
} FlowConfig;
297

298
/* Hash key for the flow hash */
299
typedef struct FlowKey_
300
{
301
    Address src, dst;
302
    Port sp, dp;
303
    uint8_t proto;
304
    uint8_t recursion_level;
305
    uint16_t livedev_id;
306
    uint16_t vlan_id[VLAN_MAX_LAYERS];
307
} FlowKey;
308

309
typedef struct FlowAddress_ {
310
    union {
311
        uint32_t       address_un_data32[4]; /* type-specific field */
312
        uint16_t       address_un_data16[8]; /* type-specific field */
313
        uint8_t        address_un_data8[16]; /* type-specific field */
314
    } address;
315
} FlowAddress;
316

317
#define addr_data32 address.address_un_data32
103,821,181✔
318
#define addr_data16 address.address_un_data16
319
#define addr_data8  address.address_un_data8
320

321
typedef unsigned short FlowStateType;
322

323
/** Local Thread ID */
324
typedef uint16_t FlowThreadId;
325

326
#include "util-storage.h"
327

328
/**
329
 *  \brief Flow data structure.
330
 *
331
 *  The flow is a global data structure that is created for new packets of a
332
 *  flow and then looked up for the following packets of a flow.
333
 *
334
 *  Locking
335
 *
336
 *  The flow is updated/used by multiple packets at the same time. This is why
337
 *  there is a flow-mutex. It's a mutex and not a spinlock because some
338
 *  operations on the flow can be quite expensive, thus spinning would be
339
 *  too expensive.
340
 *
341
 *  The flow "header" (addresses, ports, proto, recursion level) are static
342
 *  after the initialization and remain read-only throughout the entire live
343
 *  of a flow. This is why we can access those without protection of the lock.
344
 */
345

346
typedef struct Flow_
347
{
348
    /* flow "header", used for hashing and flow lookup. Static after init,
349
     * so safe to look at without lock */
350
    FlowAddress src, dst;
351
    union {
352
        Port sp;        /**< tcp/udp source port */
353
        struct {
354
            uint8_t type;   /**< icmp type */
355
            uint8_t code;   /**< icmp code */
356
        } icmp_s;
357

358
        struct {
359
            uint32_t spi; /**< esp spi */
360
        } esp;
361
    };
362
    union {
363
        Port dp;        /**< tcp/udp destination port */
364
        struct {
365
            uint8_t type;   /**< icmp type */
366
            uint8_t code;   /**< icmp code */
367
        } icmp_d;
368
    };
369
    uint8_t proto; /**< ip proto of the flow */
370
    uint8_t recursion_level;
371
    uint16_t vlan_id[VLAN_MAX_LAYERS];
372

373
    uint8_t vlan_idx;
374

375
    /* track toserver/toclient flow timeout needs */
376
    union {
377
        struct {
378
            uint8_t ffr_ts:4;
379
            uint8_t ffr_tc:4;
380
        };
381
        uint8_t ffr;
382
    };
383

384
    /** Thread ID for the stream/detect portion of this flow */
385
    FlowThreadId thread_id[2];
386

387
    /** flow hash - the flow hash before hash table size mod. Used for calculating
388
     *  the flow_id. */
389
    uint32_t flow_hash;
390

391
    /** Incoming interface */
392
    struct LiveDevice_ *livedev;
393

394
    struct Flow_ *next; /* (hash) list next */
395

396
    uint64_t flags; /**< generic flags */
397

398
    uint16_t file_flags; /**< file tracking/extraction flags */
399

400
    /** destination port to be used in protocol detection. This is meant
401
     *  for use with STARTTLS and HTTP CONNECT detection */
402
    uint16_t protodetect_dp; /**< 0 if not used */
403

404
    /** timeout in seconds by policy, add to Flow::lastts to get actual time this times out.
405
     *  Ignored in emergency mode. */
406
    uint32_t timeout_policy;
407

408
    /** time stamp of last update (last packet). Set/updated under the
409
     *  flow and flow hash row locks, safe to read under either the
410
     *  flow lock or flow hash row lock. */
411
    SCTime_t lastts;
412

413
    FlowStateType flow_state;
414

415
    /** flow tenant id, used to setup flow timeout and stream pseudo
416
     *  packets with the correct tenant id set */
417
    uint32_t tenant_id;
418

419
    uint32_t probing_parser_toserver_alproto_masks;
420
    uint32_t probing_parser_toclient_alproto_masks;
421

422
    /* Parent flow id for protocol like ftp */
423
    int64_t parent_id;
424

425
    /** protocol specific data pointer, e.g. for TcpSession */
426
    void *protoctx;
427

428
#ifdef FLOWLOCK_RWLOCK
429
    SCRWLock r;
430
#elif defined FLOWLOCK_MUTEX
431
    SCMutex m;
432
#else
433
    #error Enable FLOWLOCK_RWLOCK or FLOWLOCK_MUTEX
434
#endif
435

436
    /** mapping to Flow's protocol specific protocols for timeouts
437
        and state and free functions. */
438
    uint8_t protomap;
439

440
    uint8_t flow_end_flags;
441
    /* coccinelle: Flow:flow_end_flags:FLOW_END_FLAG_ */
442

443
    AppProto alproto; /**< \brief application level protocol */
444
    AppProto alproto_ts;
445
    AppProto alproto_tc;
446

447
    /** original application level protocol. Used to indicate the previous
448
       protocol when changing to another protocol , e.g. with STARTTLS. */
449
    AppProto alproto_orig;
450
    /** expected app protocol: used in protocol change/upgrade like in
451
     *  STARTTLS. */
452
    AppProto alproto_expect;
453

454
    /** detection engine ctx version used to inspect this flow. Set at initial
455
     *  inspection. If it doesn't match the currently in use de_ctx, the
456
     *  stored sgh ptrs are reset. */
457
    uint32_t de_ctx_version;
458

459
    /** ttl tracking */
460
    uint8_t min_ttl_toserver;
461
    uint8_t max_ttl_toserver;
462
    uint8_t min_ttl_toclient;
463
    uint8_t max_ttl_toclient;
464

465
    /** which exception policies were applied, if any */
466
    uint8_t applied_exception_policy;
467

468
    /** application level storage ptrs.
469
     *
470
     */
471
    AppLayerParserState *alparser;     /**< parser internal state */
472
    void *alstate;      /**< application layer state */
473

474
    /** toclient sgh for this flow. Only use when FLOW_SGH_TOCLIENT flow flag
475
     *  has been set. */
476
    const struct SigGroupHead_ *sgh_toclient;
477
    /** toserver sgh for this flow. Only use when FLOW_SGH_TOSERVER flow flag
478
     *  has been set. */
479
    const struct SigGroupHead_ *sgh_toserver;
480

481
    /* pointer to the var list */
482
    GenericVar *flowvar;
483

484
    struct FlowBucket_ *fb;
485

486
    SCTime_t startts;
487

488
    uint32_t todstpktcnt;
489
    uint32_t tosrcpktcnt;
490
    uint64_t todstbytecnt;
491
    uint64_t tosrcbytecnt;
492

493
    Storage storage[];
494
} Flow;
495

496
enum FlowState {
497
    FLOW_STATE_NEW = 0,
498
    FLOW_STATE_ESTABLISHED,
499
    FLOW_STATE_CLOSED,
500
    FLOW_STATE_LOCAL_BYPASSED,
501
#ifdef CAPTURE_OFFLOAD
502
    FLOW_STATE_CAPTURE_BYPASSED,
503
#endif
504
};
505
#ifdef CAPTURE_OFFLOAD
506
#define FLOW_STATE_SIZE 5
507
#else
508
#define FLOW_STATE_SIZE 4
5✔
509
#endif
510

511
typedef struct FlowProtoTimeout_ {
512
    uint32_t new_timeout;
513
    uint32_t est_timeout;
514
    uint32_t closed_timeout;
515
    uint32_t bypassed_timeout;
516
} FlowProtoTimeout;
517

518
typedef struct FlowProtoFreeFunc_ {
519
    void (*Freefunc)(void *);
520
} FlowProtoFreeFunc;
521

522
typedef struct FlowBypassInfo_ {
523
    bool (* BypassUpdate)(Flow *f, void *data, time_t tsec);
524
    void (* BypassFree)(void *data);
525
    void *bypass_data;
526
    uint64_t tosrcpktcnt;
527
    uint64_t tosrcbytecnt;
528
    uint64_t todstpktcnt;
529
    uint64_t todstbytecnt;
530
} FlowBypassInfo;
531

532
#include "flow-queue.h"
533

534
typedef struct FlowLookupStruct_ // TODO name
535
{
536
    /** thread store of spare queues */
537
    FlowQueuePrivate spare_queue;
538
    DecodeThreadVars *dtv;
539
    FlowQueuePrivate work_queue;
540
    uint32_t emerg_spare_sync_stamp;
541
} FlowLookupStruct;
542

543
/** \brief prepare packet for a life with flow
544
 *  Set PKT_WANTS_FLOW flag to indicate workers should do a flow lookup
545
 *  and calc the hash value to be used in the lookup and autofp flow
546
 *  balancing. */
547
void FlowSetupPacket(Packet *p);
548
void FlowHandlePacket (ThreadVars *, FlowLookupStruct *, Packet *);
549
void FlowInitConfig(bool);
550
void FlowReset(void);
551
void FlowShutdown(void);
552
void FlowSetHasAlertsFlag(Flow *);
553
int FlowHasAlerts(const Flow *);
554
void FlowSetChangeProtoFlag(Flow *);
555
void FlowUnsetChangeProtoFlag(Flow *);
556
int FlowChangeProto(Flow *);
557
void FlowSwap(Flow *);
558

559
void FlowRegisterTests(void);
560
int FlowSetProtoFreeFunc(uint8_t, void (*Free)(void *));
561

562
static inline void FlowSetNoPayloadInspectionFlag(Flow *);
563

564
int FlowGetPacketDirection(const Flow *, const Packet *);
565

566
void FlowCleanupAppLayer(Flow *);
567

568
void FlowUpdateState(Flow *f, enum FlowState s);
569

570
int FlowSetMemcap(uint64_t size);
571
uint64_t FlowGetMemcap(void);
572
uint64_t FlowGetMemuse(void);
573
enum ExceptionPolicy FlowGetMemcapExceptionPolicy(void);
574

575
FlowStorageId GetFlowBypassInfoID(void);
576
void RegisterFlowBypassInfo(void);
577

578
/** ----- Inline functions ----- */
579

580
static inline AppProto FlowGetAppProtocol(const Flow *f)
581
{
1,277,785✔
582
    return f->alproto;
1,277,785✔
583
}
1,277,785✔
584

585
static inline void *FlowGetAppState(const Flow *f)
586
{
103,858✔
587
    return f->alstate;
103,858✔
588
}
103,858✔
589

590
/** \brief Set the No payload inspection Flag without locking the flow.
591
 *
592
 * \param f Flow to set the flag in
593
 */
594
static inline void FlowSetNoPayloadInspectionFlag(Flow *f)
595
{
2,091✔
596
    SCEnter();
2,091✔
597

598
    SCLogDebug("flow %p", f);
2,091✔
599
    f->flags |= FLOW_NOPAYLOAD_INSPECTION;
2,091✔
600

601
    SCReturn;
2,091✔
602
}
2,091✔
603

604
/** \brief Reference the flow
605
 *  \note This should only be called once for a destination
606
 *        pointer */
607
static inline void FlowReference(Flow **d, Flow *f)
608
{
1,279,155✔
609
    if (likely(f != NULL)) {
1,279,155✔
610
        DEBUG_VALIDATE_BUG_ON(*d == f);
1,279,155✔
611
        if (*d == f)
1,279,155✔
612
            return;
×
613
        *d = f;
1,279,155✔
614
    }
1,279,155✔
615
}
1,279,155✔
616

617
static inline void FlowDeReference(Flow **d)
618
{
4,410,758✔
619
    if (likely(*d != NULL)) {
4,410,758✔
620
        *d = NULL;
1,279,155✔
621
    }
1,279,155✔
622
}
4,410,758✔
623

624
/** \brief create a flow id that is as unique as possible
625
 *  \retval flow_id unsigned 64bit id
626
 */
627
static inline uint64_t FlowGetId(const Flow *f)
628
{
555,199✔
629
    uint64_t id = (uint64_t)(SCTIME_SECS(f->startts) & 0xFFFF) << 48 |
555,199✔
630
                  (uint64_t)(SCTIME_USECS(f->startts) & 0xFFFF) << 32 | (uint64_t)f->flow_hash;
555,199✔
631
    /* reduce to 51 bits as JavaScript and even JSON often seem to
632
     * max out there. */
633
    id &= 0x7ffffffffffffLL;
555,199✔
634
    return id;
555,199✔
635
}
555,199✔
636

637
static inline bool FlowIsBypassed(const Flow *f)
638
{
1,267,363✔
639
    if (
1,267,363✔
640
#ifdef CAPTURE_OFFLOAD
641
            f->flow_state == FLOW_STATE_CAPTURE_BYPASSED ||
642
#endif
643
            f->flow_state == FLOW_STATE_LOCAL_BYPASSED) {
1,267,363✔
644
        return true;
11✔
645
    }
11✔
646
    return false;
1,267,352✔
647
}
1,267,363✔
648

649
int FlowClearMemory(Flow *,uint8_t );
650

651
AppProto FlowGetAppProtocol(const Flow *f);
652
void *FlowGetAppState(const Flow *f);
653
uint8_t FlowGetDisruptionFlags(const Flow *f, uint8_t flags);
654

655
void FlowHandlePacketUpdate(Flow *f, Packet *p, ThreadVars *tv, DecodeThreadVars *dtv);
656

657
#endif /* SURICATA_FLOW_H */
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc