suricata
ippair.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 ippairs.
24 */
25
26#include "suricata-common.h"
27#include "conf.h"
28
29#include "util-debug.h"
30#include "ippair.h"
31#include "ippair-storage.h"
32
33#include "util-random.h"
34#include "util-misc.h"
35#include "util-byte.h"
36#include "util-validate.h"
37
38#include "ippair-queue.h"
39
40#include "detect-tag.h"
41#include "detect-engine-tag.h"
43
44#include "util-hash-lookup3.h"
45
46static IPPair *IPPairGetUsedIPPair(void);
47
48/** ippair hash table */
49IPPairHashRow *ippair_hash;
50/** queue with spare ippairs */
51static IPPairQueue ippair_spare_q;
53SC_ATOMIC_DECLARE(uint64_t,ippair_memuse);
54SC_ATOMIC_DECLARE(uint32_t,ippair_counter);
55SC_ATOMIC_DECLARE(uint32_t,ippair_prune_idx);
56
57/** size of the ippair object. Maybe updated in IPPairInitConfig to include
58 * the storage APIs additions. */
59static uint16_t g_ippair_size = sizeof(IPPair);
60
61/**
62 * \brief Update memcap value
63 *
64 * \param size new memcap value
65 */
66int IPPairSetMemcap(uint64_t size)
67{
68 if ((uint64_t)SC_ATOMIC_GET(ippair_memuse) < size) {
69 SC_ATOMIC_SET(ippair_config.memcap, size);
70 return 1;
71 }
72
73 return 0;
74}
75
76/**
77 * \brief Return memcap value
78 *
79 * \retval memcap value
80 */
81uint64_t IPPairGetMemcap(void)
82{
83 uint64_t memcapcopy = SC_ATOMIC_GET(ippair_config.memcap);
84 return memcapcopy;
85}
86
87/**
88 * \brief Return memuse value
89 *
90 * \retval memuse value
91 */
92uint64_t IPPairGetMemuse(void)
93{
94 uint64_t memusecopy = SC_ATOMIC_GET(ippair_memuse);
95 return memusecopy;
96}
97
99{
100 IPPairEnqueue(&ippair_spare_q, h);
101 (void) SC_ATOMIC_SUB(ippair_counter, 1);
102}
103
105{
106 if (!(IPPAIR_CHECK_MEMCAP(g_ippair_size))) {
107 return NULL;
108 }
109
110 (void) SC_ATOMIC_ADD(ippair_memuse, g_ippair_size);
111
112 IPPair *h = SCCalloc(1, g_ippair_size);
113 if (unlikely(h == NULL))
114 goto error;
115
116 SCMutexInit(&h->m, NULL);
117 SC_ATOMIC_INIT(h->use_cnt);
118 return h;
119
120error:
121 return NULL;
122}
123
125{
126 if (h != NULL) {
128 SCMutexDestroy(&h->m);
129 SCFree(h);
130 (void) SC_ATOMIC_SUB(ippair_memuse, g_ippair_size);
131 }
132}
133
134static IPPair *IPPairNew(Address *a, Address *b)
135{
136 IPPair *p = IPPairAlloc();
137 if (p == NULL)
138 goto error;
139
140 /* copy addresses */
141 COPY_ADDRESS(a, &p->a[0]);
142 COPY_ADDRESS(b, &p->a[1]);
143
144 return p;
145
146error:
147 return NULL;
148}
149
151{
152 if (IPPairStorageSize() > 0)
154}
155
156#define IPPAIR_DEFAULT_HASHSIZE 4096
157#define IPPAIR_DEFAULT_MEMCAP 16777216
158#define IPPAIR_DEFAULT_PREALLOC 1000
159
160/** \brief initialize the configuration
161 * \warning Not thread safe */
162void IPPairInitConfig(bool quiet)
163{
164 SCLogDebug("initializing ippair engine...");
165 if (IPPairStorageSize() > 0) {
166 DEBUG_VALIDATE_BUG_ON(sizeof(IPPair) + IPPairStorageSize() > UINT16_MAX);
167 g_ippair_size = (uint16_t)(sizeof(IPPair) + IPPairStorageSize());
168 }
169
170 memset(&ippair_config, 0, sizeof(ippair_config));
171 //SC_ATOMIC_INIT(flow_flags);
172 SC_ATOMIC_INIT(ippair_counter);
173 SC_ATOMIC_INIT(ippair_memuse);
174 SC_ATOMIC_INIT(ippair_prune_idx);
176 IPPairQueueInit(&ippair_spare_q);
177
178 /* set defaults */
179 ippair_config.hash_rand = (uint32_t)RandomGet();
183
184 /* Check if we have memcap and hash_size defined at config */
185 const char *conf_val;
186 uint32_t configval = 0;
187
188 /** set config values for memcap, prealloc and hash_size */
189 uint64_t ippair_memcap;
190 if ((SCConfGet("ippair.memcap", &conf_val)) == 1) {
191 if (ParseSizeStringU64(conf_val, &ippair_memcap) < 0) {
192 SCLogError("Error parsing ippair.memcap "
193 "from conf file - %s. Killing engine",
194 conf_val);
195 exit(EXIT_FAILURE);
196 } else {
197 SC_ATOMIC_SET(ippair_config.memcap, ippair_memcap);
198 }
199 }
200 if ((SCConfGet("ippair.hash-size", &conf_val)) == 1) {
201 if (StringParseUint32(&configval, 10, strlen(conf_val),
202 conf_val) > 0) {
203 ippair_config.hash_size = configval;
204 }
205 }
206
207 if ((SCConfGet("ippair.prealloc", &conf_val)) == 1) {
208 if (StringParseUint32(&configval, 10, strlen(conf_val),
209 conf_val) > 0) {
210 ippair_config.prealloc = configval;
211 } else {
212 WarnInvalidConfEntry("ippair.prealloc", "%"PRIu32, ippair_config.prealloc);
213 }
214 }
215 SCLogDebug("IPPair config from suricata.yaml: memcap: %"PRIu64", hash-size: "
216 "%"PRIu32", prealloc: %"PRIu32, SC_ATOMIC_GET(ippair_config.memcap),
218
219 /* alloc hash memory */
220 uint64_t hash_size = ippair_config.hash_size * sizeof(IPPairHashRow);
221 if (!(IPPAIR_CHECK_MEMCAP(hash_size))) {
222 SCLogError("allocating ippair hash failed: "
223 "max ippair memcap is smaller than projected hash size. "
224 "Memcap: %" PRIu64 ", Hash table size %" PRIu64 ". Calculate "
225 "total hash size by multiplying \"ippair.hash-size\" with %" PRIuMAX ", "
226 "which is the hash bucket size.",
227 SC_ATOMIC_GET(ippair_config.memcap), hash_size, (uintmax_t)sizeof(IPPairHashRow));
228 exit(EXIT_FAILURE);
229 }
230 ippair_hash = SCMallocAligned(ippair_config.hash_size * sizeof(IPPairHashRow), CLS);
231 if (unlikely(ippair_hash == NULL)) {
232 FatalError("Fatal error encountered in IPPairInitConfig. Exiting...");
233 }
234 memset(ippair_hash, 0, ippair_config.hash_size * sizeof(IPPairHashRow));
235
236 uint32_t i = 0;
237 for (i = 0; i < ippair_config.hash_size; i++) {
239 }
240 (void) SC_ATOMIC_ADD(ippair_memuse, (ippair_config.hash_size * sizeof(IPPairHashRow)));
241
242 if (!quiet) {
243 SCLogConfig("allocated %"PRIu64" bytes of memory for the ippair hash... "
244 "%" PRIu32 " buckets of size %" PRIuMAX "",
245 SC_ATOMIC_GET(ippair_memuse), ippair_config.hash_size,
246 (uintmax_t)sizeof(IPPairHashRow));
247 }
248
249 /* pre allocate ippairs */
250 for (i = 0; i < ippair_config.prealloc; i++) {
251 if (!(IPPAIR_CHECK_MEMCAP(g_ippair_size))) {
252 SCLogError("preallocating ippairs failed: "
253 "max ippair memcap reached. Memcap %" PRIu64 ", "
254 "Memuse %" PRIu64 ".",
256 ((uint64_t)SC_ATOMIC_GET(ippair_memuse) + g_ippair_size));
257 exit(EXIT_FAILURE);
258 }
259
260 IPPair *h = IPPairAlloc();
261 if (h == NULL) {
262 SCLogError("preallocating ippair failed: %s", strerror(errno));
263 exit(EXIT_FAILURE);
264 }
265 IPPairEnqueue(&ippair_spare_q,h);
266 }
267
268 if (!quiet) {
269 SCLogConfig("preallocated %" PRIu32 " ippairs of size %" PRIu16 "",
270 ippair_spare_q.len, g_ippair_size);
271 SCLogConfig("ippair memory usage: %"PRIu64" bytes, maximum: %"PRIu64,
272 SC_ATOMIC_GET(ippair_memuse), SC_ATOMIC_GET(ippair_config.memcap));
273 }
274}
275
276/** \brief print some ippair stats
277 * \warning Not thread safe */
279{
280#ifdef IPPAIRBITS_STATS
281 SCLogPerf("ippairbits added: %" PRIu32 ", removed: %" PRIu32 ", max memory usage: %" PRIu32 "",
282 ippairbits_added, ippairbits_removed, ippairbits_memuse_max);
283#endif /* IPPAIRBITS_STATS */
284 SCLogPerf("ippair memory usage: %" PRIu64 " bytes, maximum: %" PRIu64,
285 SC_ATOMIC_GET(ippair_memuse), SC_ATOMIC_GET(ippair_config.memcap));
286}
287
288/** \brief shutdown the flow engine
289 * \warning Not thread safe */
291{
292 IPPair *h;
293 uint32_t u;
294
296
297 /* free spare queue */
298 while((h = IPPairDequeue(&ippair_spare_q))) {
299 BUG_ON(SC_ATOMIC_GET(h->use_cnt) > 0);
300 IPPairFree(h);
301 }
302
303 /* clear and free the hash */
304 if (ippair_hash != NULL) {
305 for (u = 0; u < ippair_config.hash_size; u++) {
306 h = ippair_hash[u].head;
307 while (h) {
308 IPPair *n = h->hnext;
309 IPPairFree(h);
310 h = n;
311 }
312
314 }
316 ippair_hash = NULL;
317 }
318 (void) SC_ATOMIC_SUB(ippair_memuse, ippair_config.hash_size * sizeof(IPPairHashRow));
319 IPPairQueueDestroy(&ippair_spare_q);
320}
321
322/** \brief Cleanup the ippair engine
323 *
324 * Cleanup the ippair engine from tag and threshold.
325 *
326 */
328{
329 if (ippair_hash != NULL) {
330 for (uint32_t u = 0; u < ippair_config.hash_size; u++) {
331 IPPairHashRow *hb = &ippair_hash[u];
332 HRLOCK_LOCK(hb);
333 IPPair *h = ippair_hash[u].head;
334 while (h) {
335 if ((SC_ATOMIC_GET(h->use_cnt) > 0)) {
336 /* iprep is attached to ippair only clear local storage */
338 h = h->hnext;
339 } else {
340 IPPair *n = h->hnext;
341 /* remove from the hash */
342 if (h->hprev != NULL)
343 h->hprev->hnext = h->hnext;
344 if (h->hnext != NULL)
345 h->hnext->hprev = h->hprev;
346 if (hb->head == h)
347 hb->head = h->hnext;
348 if (hb->tail == h)
349 hb->tail = h->hprev;
350 h->hnext = NULL;
351 h->hprev = NULL;
354 h = n;
355 }
356 }
357 HRLOCK_UNLOCK(hb);
358 }
359 }
360}
361
362/** \brief compare two raw ipv6 addrs
363 *
364 * \note we don't care about the real ipv6 ip's, this is just
365 * to consistently fill the FlowHashKey6 struct, without all
366 * the SCNtohl calls.
367 *
368 * \warning do not use elsewhere unless you know what you're doing.
369 * detect-engine-address-ipv6.c's AddressIPv6GtU32 is likely
370 * what you are looking for.
371 * Copied from FlowHashRawAddressIPv6GtU32
372 */
373static inline int IPPairHashRawAddressIPv6GtU32(const uint32_t *a, const uint32_t *b)
374{
375 int i;
376
377 for (i = 0; i < 4; i++) {
378 if (a[i] > b[i])
379 return 1;
380 if (a[i] < b[i])
381 break;
382 }
383
384 return 0;
385}
386
387/* calculate the hash key for this packet
388 *
389 * we're using:
390 * hash_rand -- set at init time
391 * source address
392 */
393static uint32_t IPPairGetKey(Address *a, Address *b)
394{
395 uint32_t key;
396
397 if (a->family == AF_INET) {
398 uint32_t addrs[2] = { MIN(a->addr_data32[0], b->addr_data32[0]),
399 MAX(a->addr_data32[0], b->addr_data32[0]) };
400 uint32_t hash = hashword(addrs, 2, ippair_config.hash_rand);
401 key = hash % ippair_config.hash_size;
402 } else if (a->family == AF_INET6) {
403 uint32_t addrs[8];
404 if (IPPairHashRawAddressIPv6GtU32(&a->addr_data32[0],&b->addr_data32[0])) {
405 addrs[0] = b->addr_data32[0];
406 addrs[1] = b->addr_data32[1];
407 addrs[2] = b->addr_data32[2];
408 addrs[3] = b->addr_data32[3];
409 addrs[4] = a->addr_data32[0];
410 addrs[5] = a->addr_data32[1];
411 addrs[6] = a->addr_data32[2];
412 addrs[7] = a->addr_data32[3];
413 } else {
414 addrs[0] = a->addr_data32[0];
415 addrs[1] = a->addr_data32[1];
416 addrs[2] = a->addr_data32[2];
417 addrs[3] = a->addr_data32[3];
418 addrs[4] = b->addr_data32[0];
419 addrs[5] = b->addr_data32[1];
420 addrs[6] = b->addr_data32[2];
421 addrs[7] = b->addr_data32[3];
422 }
423 uint32_t hash = hashword(addrs, 8, ippair_config.hash_rand);
424 key = hash % ippair_config.hash_size;
425 } else
426 key = 0;
427
428 return key;
429}
430
431/* Since two or more ippairs can have the same hash key, we need to compare
432 * the ippair with the current addresses. */
433static inline int IPPairCompare(IPPair *p, Address *a, Address *b)
434{
435 /* compare in both directions */
436 if ((CMP_ADDR(&p->a[0], a) && CMP_ADDR(&p->a[1], b)) ||
437 (CMP_ADDR(&p->a[0], b) && CMP_ADDR(&p->a[1], a)))
438 return 1;
439 return 0;
440}
441
442/**
443 * \brief Get a new ippair
444 *
445 * Get a new ippair. We're checking memcap first and will try to make room
446 * if the memcap is reached.
447 *
448 * \retval h *LOCKED* ippair on succes, NULL on error.
449 */
450static IPPair *IPPairGetNew(Address *a, Address *b)
451{
452 IPPair *h = NULL;
453
454 /* get a ippair from the spare queue */
455 h = IPPairDequeue(&ippair_spare_q);
456 if (h == NULL) {
457 /* If we reached the max memcap, we get a used ippair */
458 if (!(IPPAIR_CHECK_MEMCAP(g_ippair_size))) {
459 /* declare state of emergency */
460 //if (!(SC_ATOMIC_GET(ippair_flags) & IPPAIR_EMERGENCY)) {
461 // SC_ATOMIC_OR(ippair_flags, IPPAIR_EMERGENCY);
462
463 /* under high load, waking up the flow mgr each time leads
464 * to high cpu usage. Flows are not timed out much faster if
465 * we check a 1000 times a second. */
466 // FlowWakeupFlowManagerThread();
467 //}
468
469 h = IPPairGetUsedIPPair();
470 if (h == NULL) {
471 return NULL;
472 }
473
474 /* freed a ippair, but it's unlocked */
475 } else {
476 /* now see if we can alloc a new ippair */
477 h = IPPairNew(a,b);
478 if (h == NULL) {
479 return NULL;
480 }
481
482 /* ippair is initialized but *unlocked* */
483 }
484 } else {
485 /* ippair has been recycled before it went into the spare queue */
486
487 /* ippair is initialized (recycled) but *unlocked* */
488 }
489
490 (void) SC_ATOMIC_ADD(ippair_counter, 1);
491 SCMutexLock(&h->m);
492 return h;
493}
494
495static void IPPairInit(IPPair *h, Address *a, Address *b)
496{
497 COPY_ADDRESS(a, &h->a[0]);
498 COPY_ADDRESS(b, &h->a[1]);
499 (void) IPPairIncrUsecnt(h);
500}
501
503{
504 (void) IPPairDecrUsecnt(h);
505 SCMutexUnlock(&h->m);
506}
507
509{
510 SCMutexUnlock(&h->m);
511}
512
513/* IPPairGetIPPairFromHash
514 *
515 * Hash retrieval function for ippairs. Looks up the hash bucket containing the
516 * ippair pointer. Then compares the packet with the found ippair to see if it is
517 * the ippair we need. If it isn't, walk the list until the right ippair is found.
518 *
519 * returns a *LOCKED* ippair or NULL
520 */
522{
523 IPPair *h = NULL;
524
525 /* get the key to our bucket */
526 uint32_t key = IPPairGetKey(a, b);
527 /* get our hash bucket and lock it */
528 IPPairHashRow *hb = &ippair_hash[key];
529 HRLOCK_LOCK(hb);
530
531 /* see if the bucket already has a ippair */
532 if (hb->head == NULL) {
533 h = IPPairGetNew(a,b);
534 if (h == NULL) {
535 HRLOCK_UNLOCK(hb);
536 return NULL;
537 }
538
539 /* ippair is locked */
540 hb->head = h;
541 hb->tail = h;
542
543 /* got one, now lock, initialize and return */
544 IPPairInit(h,a,b);
545
546 HRLOCK_UNLOCK(hb);
547 return h;
548 }
549
550 /* ok, we have a ippair in the bucket. Let's find out if it is our ippair */
551 h = hb->head;
552
553 /* see if this is the ippair we are looking for */
554 if (IPPairCompare(h, a, b) == 0) {
555 IPPair *ph = NULL; /* previous ippair */
556
557 while (h) {
558 ph = h;
559 h = h->hnext;
560
561 if (h == NULL) {
562 h = ph->hnext = IPPairGetNew(a,b);
563 if (h == NULL) {
564 HRLOCK_UNLOCK(hb);
565 return NULL;
566 }
567 hb->tail = h;
568
569 /* ippair is locked */
570
571 h->hprev = ph;
572
573 /* initialize and return */
574 IPPairInit(h,a,b);
575
576 HRLOCK_UNLOCK(hb);
577 return h;
578 }
579
580 if (IPPairCompare(h, a, b) != 0) {
581 /* we found our ippair, lets put it on top of the
582 * hash list -- this rewards active ippairs */
583 if (h->hnext) {
584 h->hnext->hprev = h->hprev;
585 }
586 if (h->hprev) {
587 h->hprev->hnext = h->hnext;
588 }
589 if (h == hb->tail) {
590 hb->tail = h->hprev;
591 }
592
593 h->hnext = hb->head;
594 h->hprev = NULL;
595 hb->head->hprev = h;
596 hb->head = h;
597
598 /* found our ippair, lock & return */
599 SCMutexLock(&h->m);
600 (void) IPPairIncrUsecnt(h);
601 HRLOCK_UNLOCK(hb);
602 return h;
603 }
604 }
605 }
606
607 /* lock & return */
608 SCMutexLock(&h->m);
609 (void) IPPairIncrUsecnt(h);
610 HRLOCK_UNLOCK(hb);
611 return h;
612}
613
614/** \brief look up a ippair in the hash
615 *
616 * \param a address to look up
617 *
618 * \retval h *LOCKED* ippair or NULL
619 */
621{
622 IPPair *h = NULL;
623
624 /* get the key to our bucket */
625 uint32_t key = IPPairGetKey(a, b);
626 /* get our hash bucket and lock it */
627 IPPairHashRow *hb = &ippair_hash[key];
628 HRLOCK_LOCK(hb);
629
630 /* see if the bucket already has a ippair */
631 if (hb->head == NULL) {
632 HRLOCK_UNLOCK(hb);
633 return h;
634 }
635
636 /* ok, we have a ippair in the bucket. Let's find out if it is our ippair */
637 h = hb->head;
638
639 /* see if this is the ippair we are looking for */
640 if (IPPairCompare(h, a, b) == 0) {
641 while (h) {
642 h = h->hnext;
643
644 if (h == NULL) {
645 HRLOCK_UNLOCK(hb);
646 return h;
647 }
648
649 if (IPPairCompare(h, a, b) != 0) {
650 /* we found our ippair, lets put it on top of the
651 * hash list -- this rewards active ippairs */
652 if (h->hnext) {
653 h->hnext->hprev = h->hprev;
654 }
655 if (h->hprev) {
656 h->hprev->hnext = h->hnext;
657 }
658 if (h == hb->tail) {
659 hb->tail = h->hprev;
660 }
661
662 h->hnext = hb->head;
663 h->hprev = NULL;
664 hb->head->hprev = h;
665 hb->head = h;
666
667 /* found our ippair, lock & return */
668 SCMutexLock(&h->m);
669 (void) IPPairIncrUsecnt(h);
670 HRLOCK_UNLOCK(hb);
671 return h;
672 }
673 }
674 }
675
676 /* lock & return */
677 SCMutexLock(&h->m);
678 (void) IPPairIncrUsecnt(h);
679 HRLOCK_UNLOCK(hb);
680 return h;
681}
682
683/** \internal
684 * \brief Get a ippair from the hash directly.
685 *
686 * Called in conditions where the spare queue is empty and memcap is reached.
687 *
688 * Walks the hash until a ippair can be freed. "ippair_prune_idx" atomic int makes
689 * sure we don't start at the top each time since that would clear the top of
690 * the hash leading to longer and longer search times under high pressure (observed).
691 *
692 * \retval h ippair or NULL
693 */
694static IPPair *IPPairGetUsedIPPair(void)
695{
696 uint32_t idx = SC_ATOMIC_GET(ippair_prune_idx) % ippair_config.hash_size;
697 uint32_t cnt = ippair_config.hash_size;
698
699 while (cnt--) {
700 if (++idx >= ippair_config.hash_size)
701 idx = 0;
702
703 IPPairHashRow *hb = &ippair_hash[idx];
704
705 if (HRLOCK_TRYLOCK(hb) != 0)
706 continue;
707
708 IPPair *h = hb->tail;
709 if (h == NULL) {
710 HRLOCK_UNLOCK(hb);
711 continue;
712 }
713
714 if (SCMutexTrylock(&h->m) != 0) {
715 HRLOCK_UNLOCK(hb);
716 continue;
717 }
718
719 /** never prune a ippair that is used by a packets
720 * we are currently processing in one of the threads */
721 if (SC_ATOMIC_GET(h->use_cnt) > 0) {
722 HRLOCK_UNLOCK(hb);
723 SCMutexUnlock(&h->m);
724 continue;
725 }
726
727 /* remove from the hash */
728 if (h->hprev != NULL)
729 h->hprev->hnext = h->hnext;
730 if (h->hnext != NULL)
731 h->hnext->hprev = h->hprev;
732 if (hb->head == h)
733 hb->head = h->hnext;
734 if (hb->tail == h)
735 hb->tail = h->hprev;
736
737 h->hnext = NULL;
738 h->hprev = NULL;
739 HRLOCK_UNLOCK(hb);
740
742
743 SCMutexUnlock(&h->m);
744
745 (void) SC_ATOMIC_ADD(ippair_prune_idx, (ippair_config.hash_size - cnt));
746 return h;
747 }
748
749 return NULL;
750}
751
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
#define HRLOCK_LOCK(fb)
Definition host.h:51
#define HRLOCK_UNLOCK(fb)
Definition host.h:53
#define HRLOCK_TRYLOCK(fb)
Definition host.h:52
#define HRLOCK_INIT(fb)
Definition host.h:49
#define HRLOCK_DESTROY(fb)
Definition host.h:50
void IPPairEnqueue(IPPairQueue *q, IPPair *h)
add a ippair to a queue
void IPPairQueueDestroy(IPPairQueue *q)
Destroy a ippair queue.
IPPairQueue * IPPairQueueInit(IPPairQueue *q)
IPPair * IPPairDequeue(IPPairQueue *q)
remove a ippair from the queue
void IPPairFreeStorage(IPPair *h)
void RegisterIPPairStorageTests(void)
unsigned int IPPairStorageSize(void)
IPPairHashRow * ippair_hash
Definition ippair.c:49
int IPPairSetMemcap(uint64_t size)
Update memcap value.
Definition ippair.c:66
void IPPairUnlock(IPPair *h)
Definition ippair.c:508
void IPPairCleanup(void)
Cleanup the ippair engine.
Definition ippair.c:327
void IPPairRegisterUnittests(void)
Definition ippair.c:752
void IPPairRelease(IPPair *h)
Definition ippair.c:502
void IPPairInitConfig(bool quiet)
initialize the configuration
Definition ippair.c:162
void IPPairClearMemory(IPPair *h)
Definition ippair.c:150
IPPairConfig ippair_config
Definition ippair.c:52
void IPPairShutdown(void)
shutdown the flow engine
Definition ippair.c:290
#define IPPAIR_DEFAULT_HASHSIZE
Definition ippair.c:156
#define IPPAIR_DEFAULT_PREALLOC
Definition ippair.c:158
void IPPairFree(IPPair *h)
Definition ippair.c:124
uint64_t IPPairGetMemuse(void)
Return memuse value.
Definition ippair.c:92
IPPair * IPPairGetIPPairFromHash(Address *a, Address *b)
Definition ippair.c:521
void IPPairMoveToSpare(IPPair *h)
Definition ippair.c:98
IPPair * IPPairLookupIPPairFromHash(Address *a, Address *b)
look up a ippair in the hash
Definition ippair.c:620
#define IPPAIR_DEFAULT_MEMCAP
Definition ippair.c:157
void IPPairPrintStats(void)
print some ippair stats
Definition ippair.c:278
IPPair * IPPairAlloc(void)
Definition ippair.c:104
uint64_t IPPairGetMemcap(void)
Return memcap value.
Definition ippair.c:81
struct IPPair_ IPPair
#define IPPairIncrUsecnt(h)
Definition ippair.h:108
#define IPPAIR_CHECK_MEMCAP(size)
check if a memory alloc would fit in the memcap
Definition ippair.h:105
#define IPPairDecrUsecnt(h)
Definition ippair.h:110
char family
Definition decode.h:113
uint32_t hash_size
Definition ippair.h:94
uint32_t prealloc
Definition ippair.h:95
uint32_t hash_rand
Definition ippair.h:93
uint32_t len
Address a[2]
Definition ippair.h:63
struct IPPair_ * hprev
Definition ippair.h:70
SCMutex m
Definition ippair.h:60
struct IPPair_ * hnext
Definition ippair.h:69
#define BUG_ON(x)
#define MIN(x, y)
#define MAX(x, y)
#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)