fort_SOURCES += data_structure/array_list.h
fort_SOURCES += data_structure/common.h
fort_SOURCES += data_structure/uthash.h
+fort_SOURCES += data_structure/uthash_nonfatal.h
fort_SOURCES += object/certificate.h object/certificate.c
fort_SOURCES += object/crl.h object/crl.c
#include <pthread.h>
#include "common.h"
#include "log.h"
-#include "data_structure/uthash.h"
+#include "data_structure/uthash_nonfatal.h"
-/*
- * TODO uthash panics on memory allocations...
- * http://troydhanson.github.io/uthash/userguide.html#_out_of_memory
- */
#define SADDR_IN(addr) ((struct sockaddr_in *) addr)
#define SADDR_IN6(addr) ((struct sockaddr_in6 *) addr)
HASH_FIND_INT(table, &fd, old_client);
if (old_client == NULL) {
+ errno = 0;
HASH_ADD_INT(table, meat.fd, new_client);
+ if (errno) {
+ rwlock_unlock(&lock);
+ free(new_client);
+ return -pr_errno(errno, "Couldn't create client");
+ }
new_client = NULL;
} else {
/*
--- /dev/null
+#ifndef SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_
+#define SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_
+
+#include <errno.h>
+
+/*
+ * "To enable "returning a failure" if memory cannot be allocated, define the
+ * macro HASH_NONFATAL_OOM before including the uthash.h header file."
+ * (http://troydhanson.github.io/uthash/userguide.html#_out_of_memory)
+ *
+ * The errno variable will be set to ENOMEM, so that the caller can detect the
+ * error.
+ *
+ * This validation (check for errno) must be done on ops that allocate memory,
+ * so set 'errno' to 0 before this ops are made. The 'obj' won't be freed,
+ * this is the caller's responsibility.
+ */
+#define HASH_NONFATAL_OOM 1
+#define uthash_nonfatal_oom(obj) \
+ errno = ENOMEM; \
+
+#include "data_structure/uthash.h"
+
+#endif /* SRC_DATA_STRUCTURE_UTHASH_NONFATAL_H_ */
#include "rtr/db/roa_table.h"
-#include "data_structure/uthash.h"
+#include "data_structure/uthash_nonfatal.h"
struct hashable_roa {
/*
{
struct hashable_roa *old;
+ errno = 0;
HASH_REPLACE(hh, table->roas, data, sizeof(new->data), new, old);
+ if (errno)
+ return -pr_errno(errno, "ROA couldn't be added to hash table");
if (old != NULL)
free(old);
struct ipv4_prefix const *prefix4, uint8_t max_length)
{
struct hashable_roa *roa;
+ int error;
roa = create_roa(asn, max_length);
if (roa == NULL)
roa->data.prefix_length = prefix4->len;
roa->data.addr_fam = AF_INET;
- return add_roa(table, roa);
+ error = add_roa(table, roa);
+ if (error)
+ free(roa);
+ return error;
}
int
struct ipv6_prefix const *prefix6, uint8_t max_length)
{
struct hashable_roa *roa;
+ int error;
roa = create_roa(asn, max_length);
if (roa == NULL)
roa->data.prefix_length = prefix6->len;
roa->data.addr_fam = AF_INET6;
- return add_roa(table, roa);
+ error = add_roa(table, roa);
+ if (error)
+ free(roa);
+ return error;
}
static int