suricata
host.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2012 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 * Information about hosts.
24 */
25
26#include "suricata-common.h"
27#include "conf.h"
28
29#include "util-debug.h"
30#include "host.h"
31#include "host-storage.h"
32#include "host-bit.h"
33
34#include "util-random.h"
35#include "util-misc.h"
36#include "util-byte.h"
37#include "util-validate.h"
38
39#include "host-queue.h"
40
41#include "detect-tag.h"
42#include "detect-engine-tag.h"
44
45#include "util-hash-lookup3.h"
46
47static Host *HostGetUsedHost(void);
48
49/** host hash table */
50HostHashRow *host_hash;
51/** queue with spare hosts */
52static HostQueue host_spare_q;
54
55SC_ATOMIC_DECLARE(uint64_t,host_memuse);
56SC_ATOMIC_DECLARE(uint32_t,host_counter);
57SC_ATOMIC_DECLARE(uint32_t,host_prune_idx);
58
59/** size of the host object. Maybe updated in HostInitConfig to include
60 * the storage APIs additions. */
61static uint16_t g_host_size = sizeof(Host);
62
63/**
64 * \brief Update memcap value
65 *
66 * \param size new memcap value
67 */
68int HostSetMemcap(uint64_t size)
69{
70 if ((uint64_t)SC_ATOMIC_GET(host_memuse) < size) {
71 SC_ATOMIC_SET(host_config.memcap, size);
72 return 1;
73 }
74
75 return 0;
76}
77
78/**
79 * \brief Return memcap value
80 *
81 * \retval memcap value
82 */
83uint64_t HostGetMemcap(void)
84{
85 uint64_t memcapcopy = SC_ATOMIC_GET(host_config.memcap);
86 return memcapcopy;
87}
88
89/**
90 * \brief Return memuse value
91 *
92 * \retval memuse value
93 */
94uint64_t HostGetMemuse(void)
95{
96 uint64_t memuse = SC_ATOMIC_GET(host_memuse);
97 return memuse;
98}
99
101{
102 HostEnqueue(&host_spare_q, h);
103 (void) SC_ATOMIC_SUB(host_counter, 1);
104}
105
107{
108 if (!(HOST_CHECK_MEMCAP(g_host_size))) {
109 return NULL;
110 }
111 (void) SC_ATOMIC_ADD(host_memuse, g_host_size);
112
113 Host *h = SCCalloc(1, g_host_size);
114 if (unlikely(h == NULL))
115 goto error;
116
117 SCMutexInit(&h->m, NULL);
118 SC_ATOMIC_INIT(h->use_cnt);
119 return h;
120
121error:
122 return NULL;
123}
124
126{
127 if (h != NULL) {
129 SCMutexDestroy(&h->m);
130 SCFree(h);
131 (void) SC_ATOMIC_SUB(host_memuse, g_host_size);
132 }
133}
134
135static Host *HostNew(Address *a)
136{
137 Host *h = HostAlloc();
138 if (h == NULL)
139 goto error;
140
141 /* copy address */
142 COPY_ADDRESS(a, &h->a);
143
144 return h;
145
146error:
147 return NULL;
148}
149
151{
152 if (h->iprep != NULL) {
154 }
155
156 if (HostStorageSize() > 0)
158
159 BUG_ON(SC_ATOMIC_GET(h->use_cnt) > 0);
160}
161
162#define HOST_DEFAULT_HASHSIZE 4096
163#define HOST_DEFAULT_MEMCAP 16777216
164#define HOST_DEFAULT_PREALLOC 1000
165
166/** \brief initialize the configuration
167 * \warning Not thread safe */
168void HostInitConfig(bool quiet)
169{
170 SCLogDebug("initializing host engine...");
171 if (HostStorageSize() > 0) {
172 DEBUG_VALIDATE_BUG_ON(sizeof(Host) + HostStorageSize() > UINT16_MAX);
173 g_host_size = (uint16_t)(sizeof(Host) + HostStorageSize());
174 }
175
176 memset(&host_config, 0, sizeof(host_config));
177 //SC_ATOMIC_INIT(flow_flags);
178 SC_ATOMIC_INIT(host_counter);
179 SC_ATOMIC_INIT(host_memuse);
180 SC_ATOMIC_INIT(host_prune_idx);
182 HostQueueInit(&host_spare_q);
183
184 /* set defaults */
185 host_config.hash_rand = (uint32_t)RandomGet();
189
190 /* Check if we have memcap and hash_size defined at config */
191 const char *conf_val;
192 uint32_t configval = 0;
193
194 /** set config values for memcap, prealloc and hash_size */
195 if ((SCConfGet("host.memcap", &conf_val)) == 1) {
196 uint64_t host_memcap = 0;
197 if (ParseSizeStringU64(conf_val, &host_memcap) < 0) {
198 SCLogError("Error parsing host.memcap "
199 "from conf file - %s. Killing engine",
200 conf_val);
201 exit(EXIT_FAILURE);
202 } else {
203 SC_ATOMIC_SET(host_config.memcap, host_memcap);
204 }
205 }
206 if ((SCConfGet("host.hash-size", &conf_val)) == 1) {
207 if (StringParseUint32(&configval, 10, strlen(conf_val),
208 conf_val) > 0) {
209 host_config.hash_size = configval;
210 }
211 }
212
213 if ((SCConfGet("host.prealloc", &conf_val)) == 1) {
214 if (StringParseUint32(&configval, 10, strlen(conf_val),
215 conf_val) > 0) {
216 host_config.prealloc = configval;
217 } else {
218 WarnInvalidConfEntry("host.prealloc", "%"PRIu32, host_config.prealloc);
219 }
220 }
221 SCLogDebug("Host config from suricata.yaml: memcap: %"PRIu64", hash-size: "
222 "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(host_config.memcap),
224
225 /* alloc hash memory */
226 uint64_t hash_size = host_config.hash_size * sizeof(HostHashRow);
227 if (!(HOST_CHECK_MEMCAP(hash_size))) {
228 SCLogError("allocating host hash failed: "
229 "max host memcap is smaller than projected hash size. "
230 "Memcap: %" PRIu64 ", Hash table size %" PRIu64 ". Calculate "
231 "total hash size by multiplying \"host.hash-size\" with %" PRIuMAX ", "
232 "which is the hash bucket size.",
233 SC_ATOMIC_GET(host_config.memcap), hash_size, (uintmax_t)sizeof(HostHashRow));
234 exit(EXIT_FAILURE);
235 }
236 host_hash = SCMallocAligned(host_config.hash_size * sizeof(HostHashRow), CLS);
237 if (unlikely(host_hash == NULL)) {
238 FatalError("Fatal error encountered in HostInitConfig. Exiting...");
239 }
240 memset(host_hash, 0, host_config.hash_size * sizeof(HostHashRow));
241
242 uint32_t i = 0;
243 for (i = 0; i < host_config.hash_size; i++) {
245 }
246 (void) SC_ATOMIC_ADD(host_memuse, (host_config.hash_size * sizeof(HostHashRow)));
247
248 if (!quiet) {
249 SCLogConfig("allocated %"PRIu64" bytes of memory for the host hash... "
250 "%" PRIu32 " buckets of size %" PRIuMAX "",
251 SC_ATOMIC_GET(host_memuse), host_config.hash_size,
252 (uintmax_t)sizeof(HostHashRow));
253 }
254
255 /* pre allocate hosts */
256 for (i = 0; i < host_config.prealloc; i++) {
257 if (!(HOST_CHECK_MEMCAP(g_host_size))) {
258 SCLogError("preallocating hosts failed: "
259 "max host memcap reached. Memcap %" PRIu64 ", "
260 "Memuse %" PRIu64 ".",
262 ((uint64_t)SC_ATOMIC_GET(host_memuse) + g_host_size));
263 exit(EXIT_FAILURE);
264 }
265
266 Host *h = HostAlloc();
267 if (h == NULL) {
268 SCLogError("preallocating host failed: %s", strerror(errno));
269 exit(EXIT_FAILURE);
270 }
271 HostEnqueue(&host_spare_q,h);
272 }
273
274 if (!quiet) {
275 SCLogConfig("preallocated %" PRIu32 " hosts of size %" PRIu16 "",
276 host_spare_q.len, g_host_size);
277 SCLogConfig("host memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
278 SC_ATOMIC_GET(host_memuse), SC_ATOMIC_GET(host_config.memcap));
279 }
280}
281
282/** \brief print some host stats
283 * \warning Not thread safe */
284void HostPrintStats (void)
285{
286#ifdef HOSTBITS_STATS
287 SCLogPerf("hostbits added: %" PRIu32 ", removed: %" PRIu32 ", max memory usage: %" PRIu32 "",
288 hostbits_added, hostbits_removed, hostbits_memuse_max);
289#endif /* HOSTBITS_STATS */
290 SCLogPerf("host memory usage: %" PRIu64 " bytes, maximum: %" PRIu64, SC_ATOMIC_GET(host_memuse),
291 SC_ATOMIC_GET(host_config.memcap));
292}
293
294/** \brief shutdown the flow engine
295 * \warning Not thread safe */
296void HostShutdown(void)
297{
298 Host *h;
299 uint32_t u;
300
302
303 /* free spare queue */
304 while((h = HostDequeue(&host_spare_q))) {
305 HostFree(h);
306 }
307
308 /* clear and free the hash */
309 if (host_hash != NULL) {
310 for (u = 0; u < host_config.hash_size; u++) {
311 h = host_hash[u].head;
312 while (h) {
313 Host *n = h->hnext;
314 HostFree(h);
315 h = n;
316 }
317
319 }
321 host_hash = NULL;
322 }
323 (void) SC_ATOMIC_SUB(host_memuse, host_config.hash_size * sizeof(HostHashRow));
324 HostQueueDestroy(&host_spare_q);
325}
326
327/** \brief Cleanup the host engine
328 *
329 * Cleanup the host engine from tag and threshold.
330 *
331 */
332void HostCleanup(void)
333{
334 if (host_hash != NULL) {
335 for (uint32_t u = 0; u < host_config.hash_size; u++) {
336 HostHashRow *hb = &host_hash[u];
337 HRLOCK_LOCK(hb);
338 Host *h = host_hash[u].head;
339 while (h) {
340 if ((SC_ATOMIC_GET(h->use_cnt) > 0) && (h->iprep != NULL)) {
341 /* iprep is attached to host only clear local storage */
343 h = h->hnext;
344 } else {
345 Host *n = h->hnext;
346 /* remove from the hash */
347 if (h->hprev != NULL)
348 h->hprev->hnext = h->hnext;
349 if (h->hnext != NULL)
350 h->hnext->hprev = h->hprev;
351 if (hb->head == h)
352 hb->head = h->hnext;
353 if (hb->tail == h)
354 hb->tail = h->hprev;
355 h->hnext = NULL;
356 h->hprev = NULL;
359 h = n;
360 }
361 }
362 HRLOCK_UNLOCK(hb);
363 }
364 }
365}
366
367/* calculate the hash key for this packet
368 *
369 * we're using:
370 * hash_rand -- set at init time
371 * source address
372 */
373static inline uint32_t HostGetKey(Address *a)
374{
375 uint32_t key;
376
377 if (a->family == AF_INET) {
378 uint32_t hash = hashword(&a->addr_data32[0], 1, host_config.hash_rand);
379 key = hash % host_config.hash_size;
380 } else if (a->family == AF_INET6) {
381 uint32_t hash = hashword(a->addr_data32, 4, host_config.hash_rand);
382 key = hash % host_config.hash_size;
383 } else
384 key = 0;
385
386 return key;
387}
388
389static inline int HostCompare(Host *h, Address *a)
390{
391 if (h->a.family == a->family) {
392 switch (a->family) {
393 case AF_INET:
394 return (h->a.addr_data32[0] == a->addr_data32[0]);
395 case AF_INET6:
396 return CMP_ADDR(&h->a, a);
397 }
398 }
399 return 0;
400}
401
402/**
403 * \brief Get a new host
404 *
405 * Get a new host. We're checking memcap first and will try to make room
406 * if the memcap is reached.
407 *
408 * \retval h *LOCKED* host on succes, NULL on error.
409 */
410static Host *HostGetNew(Address *a)
411{
412 Host *h = NULL;
413
414 /* get a host from the spare queue */
415 h = HostDequeue(&host_spare_q);
416 if (h == NULL) {
417 /* If we reached the max memcap, we get a used host */
418 if (!(HOST_CHECK_MEMCAP(g_host_size))) {
419 /* declare state of emergency */
420 //if (!(SC_ATOMIC_GET(host_flags) & HOST_EMERGENCY)) {
421 // SC_ATOMIC_OR(host_flags, HOST_EMERGENCY);
422
423 /* under high load, waking up the flow mgr each time leads
424 * to high cpu usage. Flows are not timed out much faster if
425 * we check a 1000 times a second. */
426 // FlowWakeupFlowManagerThread();
427 //}
428
429 h = HostGetUsedHost();
430 if (h == NULL) {
431 return NULL;
432 }
433
434 /* freed a host, but it's unlocked */
435 } else {
436 /* now see if we can alloc a new host */
437 h = HostNew(a);
438 if (h == NULL) {
439 return NULL;
440 }
441
442 /* host is initialized but *unlocked* */
443 }
444 } else {
445 /* host has been recycled before it went into the spare queue */
446
447 /* host is initialized (recycled) but *unlocked* */
448 }
449
450 (void) SC_ATOMIC_ADD(host_counter, 1);
451 SCMutexLock(&h->m);
452 return h;
453}
454
455static void HostInit(Host *h, Address *a)
456{
457 COPY_ADDRESS(a, &h->a);
458 (void) HostIncrUsecnt(h);
459}
460
462{
463 (void) HostDecrUsecnt(h);
464 SCMutexUnlock(&h->m);
465}
466
468{
469 SCMutexLock(&h->m);
470}
471
473{
474 SCMutexUnlock(&h->m);
475}
476
477
478/* HostGetHostFromHash
479 *
480 * Hash retrieval function for hosts. Looks up the hash bucket containing the
481 * host pointer. Then compares the packet with the found host to see if it is
482 * the host we need. If it isn't, walk the list until the right host is found.
483 *
484 * returns a *LOCKED* host or NULL
485 */
487{
488 Host *h = NULL;
489
490 /* get the key to our bucket */
491 uint32_t key = HostGetKey(a);
492 /* get our hash bucket and lock it */
493 HostHashRow *hb = &host_hash[key];
494 HRLOCK_LOCK(hb);
495
496 /* see if the bucket already has a host */
497 if (hb->head == NULL) {
498 h = HostGetNew(a);
499 if (h == NULL) {
500 HRLOCK_UNLOCK(hb);
501 return NULL;
502 }
503
504 /* host is locked */
505 hb->head = h;
506 hb->tail = h;
507
508 /* got one, now lock, initialize and return */
509 HostInit(h,a);
510
511 HRLOCK_UNLOCK(hb);
512 return h;
513 }
514
515 /* ok, we have a host in the bucket. Let's find out if it is our host */
516 h = hb->head;
517
518 /* see if this is the host we are looking for */
519 if (HostCompare(h, a) == 0) {
520 Host *ph = NULL; /* previous host */
521
522 while (h) {
523 ph = h;
524 h = h->hnext;
525
526 if (h == NULL) {
527 h = ph->hnext = HostGetNew(a);
528 if (h == NULL) {
529 HRLOCK_UNLOCK(hb);
530 return NULL;
531 }
532 hb->tail = h;
533
534 /* host is locked */
535
536 h->hprev = ph;
537
538 /* initialize and return */
539 HostInit(h,a);
540
541 HRLOCK_UNLOCK(hb);
542 return h;
543 }
544
545 if (HostCompare(h, a) != 0) {
546 /* we found our host, lets put it on top of the
547 * hash list -- this rewards active hosts */
548 if (h->hnext) {
549 h->hnext->hprev = h->hprev;
550 }
551 if (h->hprev) {
552 h->hprev->hnext = h->hnext;
553 }
554 if (h == hb->tail) {
555 hb->tail = h->hprev;
556 }
557
558 h->hnext = hb->head;
559 h->hprev = NULL;
560 hb->head->hprev = h;
561 hb->head = h;
562
563 /* found our host, lock & return */
564 SCMutexLock(&h->m);
565 (void) HostIncrUsecnt(h);
566 HRLOCK_UNLOCK(hb);
567 return h;
568 }
569 }
570 }
571
572 /* lock & return */
573 SCMutexLock(&h->m);
574 (void) HostIncrUsecnt(h);
575 HRLOCK_UNLOCK(hb);
576 return h;
577}
578
579/** \brief look up a host in the hash
580 *
581 * \param a address to look up
582 *
583 * \retval h *LOCKED* host or NULL
584 */
586{
587 Host *h = NULL;
588
589 /* get the key to our bucket */
590 uint32_t key = HostGetKey(a);
591 /* get our hash bucket and lock it */
592 HostHashRow *hb = &host_hash[key];
593 HRLOCK_LOCK(hb);
594
595 /* see if the bucket already has a host */
596 if (hb->head == NULL) {
597 HRLOCK_UNLOCK(hb);
598 return h;
599 }
600
601 /* ok, we have a host in the bucket. Let's find out if it is our host */
602 h = hb->head;
603
604 /* see if this is the host we are looking for */
605 if (HostCompare(h, a) == 0) {
606 while (h) {
607 h = h->hnext;
608
609 if (h == NULL) {
610 HRLOCK_UNLOCK(hb);
611 return h;
612 }
613
614 if (HostCompare(h, a) != 0) {
615 /* we found our host, lets put it on top of the
616 * hash list -- this rewards active hosts */
617 if (h->hnext) {
618 h->hnext->hprev = h->hprev;
619 }
620 if (h->hprev) {
621 h->hprev->hnext = h->hnext;
622 }
623 if (h == hb->tail) {
624 hb->tail = h->hprev;
625 }
626
627 h->hnext = hb->head;
628 h->hprev = NULL;
629 hb->head->hprev = h;
630 hb->head = h;
631
632 /* found our host, lock & return */
633 SCMutexLock(&h->m);
634 (void) HostIncrUsecnt(h);
635 HRLOCK_UNLOCK(hb);
636 return h;
637 }
638 }
639 }
640
641 /* lock & return */
642 SCMutexLock(&h->m);
643 (void) HostIncrUsecnt(h);
644 HRLOCK_UNLOCK(hb);
645 return h;
646}
647
648/** \internal
649 * \brief Get a host from the hash directly.
650 *
651 * Called in conditions where the spare queue is empty and memcap is reached.
652 *
653 * Walks the hash until a host can be freed. "host_prune_idx" atomic int makes
654 * sure we don't start at the top each time since that would clear the top of
655 * the hash leading to longer and longer search times under high pressure (observed).
656 *
657 * \retval h host or NULL
658 */
659static Host *HostGetUsedHost(void)
660{
661 uint32_t idx = SC_ATOMIC_GET(host_prune_idx) % host_config.hash_size;
662 uint32_t cnt = host_config.hash_size;
663
664 while (cnt--) {
665 if (++idx >= host_config.hash_size)
666 idx = 0;
667
668 HostHashRow *hb = &host_hash[idx];
669
670 if (HRLOCK_TRYLOCK(hb) != 0)
671 continue;
672
673 Host *h = hb->tail;
674 if (h == NULL) {
675 HRLOCK_UNLOCK(hb);
676 continue;
677 }
678
679 if (SCMutexTrylock(&h->m) != 0) {
680 HRLOCK_UNLOCK(hb);
681 continue;
682 }
683
684 /** never prune a host that is used by a packets
685 * we are currently processing in one of the threads */
686 if (SC_ATOMIC_GET(h->use_cnt) > 0) {
687 HRLOCK_UNLOCK(hb);
688 SCMutexUnlock(&h->m);
689 continue;
690 }
691
692 /* remove from the hash */
693 if (h->hprev != NULL)
694 h->hprev->hnext = h->hnext;
695 if (h->hnext != NULL)
696 h->hnext->hprev = h->hprev;
697 if (hb->head == h)
698 hb->head = h->hnext;
699 if (hb->tail == h)
700 hb->tail = h->hprev;
701
702 h->hnext = NULL;
703 h->hprev = NULL;
704 HRLOCK_UNLOCK(hb);
705
706 HostClearMemory (h);
707
708 SCMutexUnlock(&h->m);
709
710 (void) SC_ATOMIC_ADD(host_prune_idx, (host_config.hash_size - cnt));
711 return h;
712 }
713
714 return NULL;
715}
716
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition conf.c:350
#define CMP_ADDR(a1, a2)
Definition decode.h:222
#define COPY_ADDRESS(a, b)
Definition decode.h:127
HostQueue * HostQueueInit(HostQueue *q)
Definition host-queue.c:33
Host * HostDequeue(HostQueue *q)
remove a host from the queue
Definition host-queue.c:102
void HostQueueDestroy(HostQueue *q)
Destroy a host queue.
Definition host-queue.c:58
void HostEnqueue(HostQueue *q, Host *h)
add a host to a queue
Definition host-queue.c:69
void RegisterHostStorageTests(void)
unsigned int HostStorageSize(void)
void HostFreeStorage(Host *h)
#define HOST_DEFAULT_PREALLOC
Definition host.c:164
uint64_t HostGetMemcap(void)
Return memcap value.
Definition host.c:83
void HostCleanup(void)
Cleanup the host engine.
Definition host.c:332
Host * HostLookupHostFromHash(Address *a)
look up a host in the hash
Definition host.c:585
void HostShutdown(void)
shutdown the flow engine
Definition host.c:296
#define HOST_DEFAULT_MEMCAP
Definition host.c:163
uint64_t HostGetMemuse(void)
Return memuse value.
Definition host.c:94
void HostClearMemory(Host *h)
Definition host.c:150
#define HOST_DEFAULT_HASHSIZE
Definition host.c:162
void HostPrintStats(void)
print some host stats
Definition host.c:284
void HostInitConfig(bool quiet)
initialize the configuration
Definition host.c:168
void HostLock(Host *h)
Definition host.c:467
Host * HostAlloc(void)
Definition host.c:106
Host * HostGetHostFromHash(Address *a)
Definition host.c:486
void HostFree(Host *h)
Definition host.c:125
HostConfig host_config
Definition host.c:53
HostHashRow * host_hash
Definition host.c:50
void HostUnlock(Host *h)
Definition host.c:472
void HostRegisterUnittests(void)
Definition host.c:717
void HostMoveToSpare(Host *h)
Definition host.c:100
void HostRelease(Host *h)
Definition host.c:461
int HostSetMemcap(uint64_t size)
Update memcap value.
Definition host.c:68
#define HOST_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition host.h:109
#define HRLOCK_LOCK(fb)
Definition host.h:51
#define HostDecrUsecnt(h)
Definition host.h:114
#define HRLOCK_UNLOCK(fb)
Definition host.h:53
struct Host_ Host
#define HRLOCK_TRYLOCK(fb)
Definition host.h:52
#define HostIncrUsecnt(h)
Definition host.h:112
#define HRLOCK_INIT(fb)
Definition host.h:49
#define HRLOCK_DESTROY(fb)
Definition host.h:50
void SRepFreeHostData(Host *h)
Definition reputation.c:167
char family
Definition decode.h:113
uint32_t prealloc
Definition host.h:99
uint32_t hash_size
Definition host.h:98
uint32_t hash_rand
Definition host.h:97
uint32_t len
Definition host-queue.h:45
Definition host.h:58
struct Host_ * hprev
Definition host.h:73
Address a
Definition host.h:63
void * iprep
Definition host.h:69
SCMutex m
Definition host.h:60
struct Host_ * hnext
Definition host.h:72
#define BUG_ON(x)
#define CLS
#define SCMutexDestroy
#define SCMutexUnlock(mut)
#define SCMutexTrylock(mut)
#define SCMutexInit(mut, mutattrs)
#define SCMutexLock(mut)
uint32_t cnt
#define SC_ATOMIC_ADD(name, val)
add a value to our atomic variable
#define SC_ATOMIC_INIT(name)
wrapper for initializing an atomic variable.
#define SC_ATOMIC_DECLARE(type, name)
wrapper for declaring atomic variables.
#define SC_ATOMIC_SUB(name, val)
sub a value from our atomic variable
#define SC_ATOMIC_GET(name)
Get the value from the atomic variable.
#define SC_ATOMIC_SET(name, val)
Set the value for the atomic variable.
int StringParseUint32(uint32_t *res, int base, size_t len, const char *str)
Definition util-byte.c:313
#define FatalError(...)
Definition util-debug.h:510
#define SCLogPerf(...)
Definition util-debug.h:234
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267
#define SCLogConfig(...)
Definition util-debug.h:229
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval)
#define SCFreeAligned(p)
Definition util-mem.h:77
#define SCFree(p)
Definition util-mem.h:61
#define SCMallocAligned(size, align)
Definition util-mem.h:68
#define SCCalloc(nm, sz)
Definition util-mem.h:53
int ParseSizeStringU64(const char *size, uint64_t *res)
Definition util-misc.c:190
#define WarnInvalidConfEntry(param_name, format, value)
Generic API that can be used by all to log an invalid conf entry.
Definition util-misc.h:35
#define unlikely(expr)
long int RandomGet(void)
#define DEBUG_VALIDATE_BUG_ON(exp)