#include "suricata-common.h"
#include "host-storage.h"
-#include "util-unittests.h"
+#include "util-unittest.h"
+
+unsigned int HostStorageSize(void) {
+ return StorageGetSize(STORAGE_HOST);
+}
void *HostGetStorageById(Host *h, int id) {
- return StorageGetById(h->storage, STORAGE_HOST, id);
+ return StorageGetById((Storage *)(h + HostStorageSize()), STORAGE_HOST, id);
}
void *HostAllocStorageById(Host *h, int id) {
- return StorageAllocById(&h->storage, STORAGE_HOST, id);
+ return StorageAllocById((Storage **)&h + HostStorageSize(), STORAGE_HOST, id);
}
void HostFreeStorageById(Host *h, int id) {
- StorageFreeById(h->storage, STORAGE_HOST, id);
+ StorageFreeById((Storage *)(h + HostStorageSize()), STORAGE_HOST, id);
}
void HostFreeStorage(Host *h) {
- StorageFree(&h->storage, STORAGE_HOST);
+ StorageFreeAll((Storage *)(h + HostStorageSize()), STORAGE_HOST);
}
#ifdef UNITTESTS
-
+static int HostStorageTest01(void) {
+ return 1;
+}
#endif
void RegisterHostStorageTests(void) {
#ifdef UNITTESTS
-
+ UtRegisterTest("HostStorageTest01", HostStorageTest01, 1);
#endif
}
* Host wrapper around storage api
*/
+#ifndef __HOST_STORAGE_H__
+#define __HOST_STORAGE_H__
+
#include "util-storage.h"
#include "host.h"
+unsigned int HostStorageSize(void);
+
void *HostGetStorageById(Host *h, int id);
void *HostAllocStorageById(Host *h, int id);
void HostFreeStorageById(Host *h, int id);
void HostFreeStorage(Host *h);
+
+void RegisterHostStorageTests(void);
+
+#endif /* __HOST_STORAGE_H__ */
#include "util-debug.h"
#include "host.h"
+#include "host-storage.h"
#include "util-random.h"
#include "util-misc.h"
}
Host *HostAlloc(void) {
- if (!(HOST_CHECK_MEMCAP(sizeof(Host)))) {
+ size_t size = sizeof(Host) + HostStorageSize();
+
+ if (!(HOST_CHECK_MEMCAP(size))) {
return NULL;
}
- (void) SC_ATOMIC_ADD(host_memuse, sizeof(Host));
+ (void) SC_ATOMIC_ADD(host_memuse, size);
- Host *h = SCMalloc(sizeof(Host));
+ Host *h = SCMalloc(size);
if (unlikely(h == NULL))
goto error;
- memset(h, 0x00, sizeof(Host));
+ memset(h, 0x00, size);
SCMutexInit(&h->m, NULL);
SC_ATOMIC_INIT(h->use_cnt);
SC_ATOMIC_DESTROY(h->use_cnt);
SCMutexDestroy(&h->m);
SCFree(h);
- (void) SC_ATOMIC_SUB(host_memuse, sizeof(Host));
+ (void) SC_ATOMIC_SUB(host_memuse, (sizeof(Host) + HostStorageSize()));
}
}
SCFree(h->iprep);
h->iprep = NULL;
}
+
+ if (HostStorageSize() > 0)
+ HostFreeStorage(h);
}
#define HOST_DEFAULT_HASHSIZE 4096
return NULL;
}
+void HostRegisterUnittests(void) {
+ RegisterHostStorageTests();
+}
const char *name;
StorageEnum type; // host, flow, tx, stream, ssn, etc
unsigned int size;
- int (*Init)(void *);
+ void *(*Init)(unsigned int);
void (*Free)(void *);
} StorageMapping;
storage_list = NULL;
}
-int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, int (*Init)(void *), void (*Free)(void *)) {
+int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Init)(unsigned int), void (*Free)(void *)) {
if (storage_registraton_closed)
return -1;
return 0;
}
-void *StorageGetById(Storage *storage, StorageEnum type, int id) {
+unsigned int StorageGetCnt(StorageEnum type) {
+ return storage_max_id[type];
+}
+
+/** \brief get the size of the void array used to store
+ * the pointers
+ * \retval size size in bytes, can return 0 if not storage is needed
+ *
+ * \todo we could return -1 when registration isn't closed yet, however
+ * this will break lots of tests currently, so not doing it now */
+unsigned int StorageGetSize(StorageEnum type) {
+ return storage_max_id[type] * sizeof(void *);
+}
+
+void *StorageGetById(const Storage *storage, const StorageEnum type, const int id) {
SCLogDebug("storage %p id %d", storage, id);
if (storage == NULL)
return NULL;
SCLogDebug("store %p", store);
if (store[id] == NULL) {
- store[id] = SCMalloc(map->size);
+ store[id] = map->Init(map->size);
if (store[id] == NULL) {
SCFree(store);
*storage = NULL;
}
}
- if (map->Init(store[id]) < 0) {
- SCFree(store);
- *storage = NULL;
- return NULL;
- }
-
*storage = store;
return store[id];
}
SCLogDebug("store %p", store);
if (store[id] != NULL) {
map->Free(store[id]);
- SCFree(store[id]);
store[id] = NULL;
}
}
}
+void StorageFreeAll(Storage *storage, StorageEnum type) {
+ if (*storage == NULL)
+ return;
+
+ Storage *store = storage;
+ int i;
+ for (i = 0; i < storage_max_id[type]; i++) {
+ StorageMapping *map = &storage_map[type][i];
+ if (store[i] != NULL) {
+ map->Free(store[i]);
+ store[i] = NULL;
+ }
+ }
+}
+
void StorageFree(Storage **storage, StorageEnum type) {
if (*storage == NULL)
return;
StorageMapping *map = &storage_map[type][i];
if (store[i] != NULL) {
map->Free(store[i]);
- SCFree(store[i]);
store[i] = NULL;
}
}
#ifdef UNITTESTS
-static int StorageTestInit(void *x) {
- return 0;
+static void *StorageTestInit(unsigned int size) {
+ void *x = SCMalloc(size);
+ return x;
}
void StorageTestFree(void *x) {
+ if (x)
+ SCFree(x);
}
static int StorageTest01(void) {
int abc;
};
-static int StorageTest02Init(void *x) {
- struct StorageTest02Data *data = (struct StorageTest02Data *)x;
- data->abc = 1234;
- return 0;
+static void *StorageTest02Init(unsigned int size) {
+ struct StorageTest02Data *data = (struct StorageTest02Data *)SCMalloc(size);
+ if (data != NULL)
+ data->abc = 1234;
+ return (void *)data;
}
static int StorageTest02(void) {
void StorageInit(void);
void StorageCleanup(void);
-int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, int (*Init)(void *), void (*Free)(void *));
+int StorageRegister(const StorageEnum type, const char *name, const unsigned int size, void *(*Init)(unsigned int), void (*Free)(void *));
int StorageFinalize(void);
-void *StorageGetById(Storage *storage, StorageEnum type, int id);
-void *StorageAllocById(Storage **storage, StorageEnum type, int id);
-void StorageFreeById(Storage *storage, StorageEnum type, int id);
-void StorageFree(Storage **storage, StorageEnum type);
+unsigned int StorageGetCnt(const StorageEnum type);
+unsigned int StorageGetSize(const StorageEnum type);
+
+void *StorageGetById(const Storage *storage, const StorageEnum type, const int id);
+void *StorageAllocById(Storage **storage, const StorageEnum type, const int id);
+void StorageFreeById(Storage *storage, const StorageEnum type, const int id);
+void StorageFreeAll(Storage *storage, const StorageEnum type);
+void StorageFree(Storage **storage, const StorageEnum type);
void StorageRegisterTests(void);
#endif