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