Skip to content

Commit

Permalink
Refactoring of "map" ADT
Browse files Browse the repository at this point in the history
Some improvements to make the map container a bit more type-safe and
include more consistently named getter/setter functions. Also make it
more intuitive what allocated and unallocated pointers are.
  • Loading branch information
johndoe31415 committed Dec 1, 2017
1 parent 9d78dec commit 24bc884
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 122 deletions.
4 changes: 2 additions & 2 deletions certforgery.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ bool certforgery_init(void) {
}
log_cert(LLVL_DEBUG, root_ca, "Used root certificate");
}
server_certificates = map_init();
server_certificates = map_new();
if (!server_certificates) {
logmsg(LLVL_FATAL, "Failed to create server_certificates map.");
return false;
Expand Down Expand Up @@ -223,7 +223,7 @@ X509 *forge_certificate_for_server(const char *hostname, uint32_t ipv4_nbo) {
}
certificate = openssl_create_certificate(&certspec);
if (certificate) {
map_set(server_certificates, key, keylen, certificate, 0);
map_set_ptr(server_certificates, key, keylen, certificate);
if (pgm_options->log.dump_certificates) {
log_cert(LLVL_DEBUG, certificate, "Created forged server certificate");
}
Expand Down
10 changes: 5 additions & 5 deletions hostname_ids.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,29 @@ unsigned int resolve_hostname_id(uint32_t ipv4_nbo, const char *hostname) {
struct map_t *map = map_get(ip_to_hostnames, &ipv4_nbo, sizeof(uint32_t));
if (!map) {
/* No entry for that IP address so far */
map = map_init();
map = map_new();
if (!map) {
logmsg(LLVL_FATAL, "Unable to create inner map for hostname entry for \"%s\", returning 0.", hostname);
return 0;
}
if (!map_set(ip_to_hostnames, &ipv4_nbo, sizeof(uint32_t), map, 0)) {
if (!map_set_ptr(ip_to_hostnames, &ipv4_nbo, sizeof(uint32_t), map)) {
logmsg(LLVL_FATAL, "Unable to register inner map for hostname entry for \"%s\", returning 0.", hostname);
map_free(map);
return 0;
}
}

int hostname_id = map_get_str_int(map, hostname);
int hostname_id = strmap_get_int(map, hostname);
if (hostname_id == -1) {
hostname_id = map->element_count + 1;
map_set_str_int(map, hostname, hostname_id);
strmap_set_int(map, hostname, hostname_id);
}

return hostname_id;
}

void init_hostname_ids(void) {
ip_to_hostnames = map_init();
ip_to_hostnames = map_new();
}

static void free_inner_map(void *inner_map) {
Expand Down
8 changes: 4 additions & 4 deletions interceptdb.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ static struct intercept_entry_t default_entry;
static struct map_t *intercept_entry_by_hostname;

struct intercept_entry_t* interceptdb_find_entry(const char *hostname, uint32_t ipv4_nbo) {
struct intercept_entry_t *entry = (struct intercept_entry_t*)map_get_str(intercept_entry_by_hostname, hostname);
struct intercept_entry_t *entry = (struct intercept_entry_t*)strmap_get(intercept_entry_by_hostname, hostname);
if (!entry) {
return &default_entry;
} else {
Expand Down Expand Up @@ -116,14 +116,14 @@ bool init_interceptdb(void) {
return false;
}

intercept_entry_by_hostname = map_init();
intercept_entry_by_hostname = map_new();
for (int i = 0; i < pgm_options->intercept.count; i++) {
struct intercept_config_t *pgm_config = pgm_options->intercept.config[i];
struct map_element_t *new_map_entry = map_set_str(intercept_entry_by_hostname, pgm_config->hostname, NULL, sizeof(struct intercept_entry_t));
struct map_element_t *new_map_entry = strmap_set_mem(intercept_entry_by_hostname, pgm_config->hostname, NULL, sizeof(struct intercept_entry_t));
if (!new_map_entry) {
return false;
}
struct intercept_entry_t *new_entry = (struct intercept_entry_t*)new_map_entry->ptrvalue;
struct intercept_entry_t *new_entry = (struct intercept_entry_t*)new_map_entry->value.pointer;
initialize_intercept_entry_from_pgm_config(new_entry, pgm_config);
}
return true;
Expand Down
163 changes: 100 additions & 63 deletions map.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@
#include "map.h"
#include "logging.h"

static void map_free_element(struct map_element_t *element);
static void map_element_free(struct map_element_t *element);
static void map_element_value_free(struct map_element_t *element);

static int map_element_cmp(const void *vptr1, const void *vptr2) {
const struct map_element_t **ptr1 = (const struct map_element_t**)vptr1;
Expand All @@ -44,7 +45,7 @@ static int map_element_cmp(const void *vptr1, const void *vptr2) {
}
}

static struct map_element_t* map_insert_at_end(struct map_t *map, const void *key, unsigned int key_len, const void *value, unsigned int value_len) {
static struct map_element_t* map_insert_at_end(struct map_t *map, const void *key, const unsigned int key_len, const enum map_element_type_t value_type, const union value_t value, const unsigned int value_len) {
struct map_element_t *new_element = malloc(sizeof(struct map_element_t));
if (!new_element) {
logmsg(LLVL_FATAL, "Failed to malloc(3) new map element: %s", strerror(errno));
Expand All @@ -59,8 +60,8 @@ static struct map_element_t* map_insert_at_end(struct map_t *map, const void *ke
}
memcpy((void*)new_element->key, key, key_len);

new_element->value_allocated = false;
if (!map_set_value(new_element, value, value_len)) {
new_element->value_type = UNDEFINED;
if (!map_set_value(new_element, value_type, value, value_len)) {
free((void*)new_element->key);
free(new_element);
return NULL;
Expand All @@ -70,7 +71,7 @@ static struct map_element_t* map_insert_at_end(struct map_t *map, const void *ke
if (!new_elements) {
logmsg(LLVL_FATAL, "Failed to realloc(3) map elements: %s", strerror(errno));
free((void*)new_element->key);
free(new_element->ptrvalue);
free(new_element->value.pointer);
free(new_element);
return NULL;
}
Expand All @@ -84,26 +85,25 @@ static void map_sort_elements(struct map_t *map) {
qsort(map->elements, map->element_count, sizeof(struct map_element_t*), map_element_cmp);
}

bool map_set_value(struct map_element_t *element, const void *new_value, unsigned int new_value_len) {
if (element->value_allocated) {
free(element->ptrvalue);
}
bool map_set_value(struct map_element_t *element, const enum map_element_type_t value_type, const union value_t new_value, const unsigned int new_value_len) {
map_element_value_free(element);

if (new_value_len > 0) {
element->ptrvalue = malloc(new_value_len);
if (!element->ptrvalue) {
if (value_type == ALLOCED_MEMORY) {
element->value.pointer = malloc(new_value_len);
if (!element->value.pointer) {
logmsg(LLVL_FATAL, "Failed to malloc(3) new map element value to size of %u bytes: %s", new_value_len, strerror(errno));
element->value_len = 0;
return false;
}
element->value_allocated = true;
if (new_value) {
memcpy(element->ptrvalue, new_value, new_value_len);
if (new_value.pointer) {
memcpy(element->value.pointer, new_value.pointer, new_value_len);
}
} else {
element->value_allocated = false;
element->ptrvalue = (void*)new_value;
} else if (value_type == VOID_PTR) {
element->value.pointer = new_value.pointer;
} else if (value_type == INTEGER) {
element->value.integer = new_value.integer;
}
element->value_type = value_type;
element->value_len = new_value_len;
return true;
}
Expand Down Expand Up @@ -137,47 +137,57 @@ struct map_element_t *map_getitem(struct map_t *map, const void *key, unsigned i
void *map_get(struct map_t *map, const void *key, unsigned int key_len) {
struct map_element_t *element = map_getitem(map, key, key_len);
if (element) {
return element->ptrvalue;
} else {
return NULL;
if ((element->value_type == ALLOCED_MEMORY) || (element->value_type == VOID_PTR)) {
return element->value.pointer;
} else {
logmsg(LLVL_FATAL, "Type mismatch at map_get(): Wanted pointer, but element type is 0x%x.", element->value_type);
}
}
return NULL;
}

int map_getint(struct map_t *map, const void *key, unsigned int key_len) {
int map_get_int(struct map_t *map, const void *key, unsigned int key_len) {
struct map_element_t *element = map_getitem(map, key, key_len);
if (element) {
return element->intvalue;
} else {
return -1;
if (element->value_type == INTEGER) {
return element->value.integer;
} else {
logmsg(LLVL_FATAL, "Type mismatch at map_get_int(): Wanted integer, but element type is 0x%x.", element->value_type);
}
}
return -1;
}

struct map_element_t* map_set(struct map_t *map, const void *key, unsigned int key_len, const void *value, unsigned int value_len) {
struct map_element_t* map_set(struct map_t *map, const void *key, const unsigned int key_len, enum map_element_type_t value_type, const union value_t value, const unsigned int value_len) {
struct map_element_t *element = map_getitem(map, key, key_len);
if (element) {
map_set_value(element, value, value_len);
map_set_value(element, value_type, value, value_len);
} else {
element = map_insert_at_end(map, key, key_len, value, value_len);
element = map_insert_at_end(map, key, key_len, value_type, value, value_len);
map_sort_elements(map);
}
return element;
}

int map_get_str_int(struct map_t *map, const char *strkey) {
return map_getint(map, strkey, strlen(strkey) + 1);
}

void* map_get_str(struct map_t *map, const char *strkey) {
return map_get(map, strkey, strlen(strkey) + 1);
struct map_element_t* map_set_mem(struct map_t *map, const void *key, const unsigned int key_len, const void *value, const unsigned int value_len) {
union value_t uvalue = {
.pointer = (void*)value,
};
return map_set(map, key, key_len, ALLOCED_MEMORY, uvalue, value_len);
}

struct map_element_t* map_set_str(struct map_t *map, const char *strkey, const void *value, unsigned int value_len) {
return map_set(map, strkey, strlen(strkey) + 1, value, value_len);
struct map_element_t* map_set_ptr(struct map_t *map, const void *key, const unsigned int key_len, const void *value) {
union value_t uvalue = {
.pointer = (void*)value,
};
return map_set(map, key, key_len, VOID_PTR, uvalue, 0);
}

void map_set_str_int(struct map_t *map, const char *strkey, int value) {
struct map_element_t *element = map_set(map, strkey, strlen(strkey) + 1, NULL, 0);
element->intvalue = value;
struct map_element_t* map_set_int(struct map_t *map, const void *key, const unsigned int key_len, int value) {
union value_t uvalue = {
.integer = value,
};
return map_set(map, key, key_len, INTEGER, uvalue, 0);
}

void map_del_key(struct map_t *map, const void *key, unsigned int key_len) {
Expand All @@ -186,7 +196,7 @@ void map_del_key(struct map_t *map, const void *key, unsigned int key_len) {
return;
}

map_free_element(map->elements[index]);
map_element_free(map->elements[index]);
memmove(map->elements + index, map->elements + 1, (map->element_count - index - 1) * sizeof(struct map_element_t*));

struct map_element_t **new_elements = realloc(map->elements, sizeof(struct map_element_t*) * (map->element_count - 1));
Expand All @@ -197,16 +207,36 @@ void map_del_key(struct map_t *map, const void *key, unsigned int key_len) {
map->element_count--;
}

void strmap_set(struct map_t *map, const char *strkey, const char *strvalue) {
map_set(map, strkey, strlen(strkey) + 1, strvalue, strlen(strvalue) + 1);
struct map_element_t *strmap_set_mem(struct map_t *map, const char *strkey, const void *value, const unsigned int value_len) {
return map_set_mem(map, strkey, strlen(strkey) + 1, value, value_len);
}

void strmap_del(struct map_t *map, const char *strkey) {
map_del_key(map, strkey, strlen(strkey) + 1);
struct map_element_t *strmap_set_ptr(struct map_t *map, const char *strkey, void *value) {
return map_set_ptr(map, strkey, strlen(strkey) + 1, value);
}

const char* strmap_get(struct map_t *map, const char *strkey) {
return (const char*)map_get(map, strkey, strlen(strkey) + 1);
struct map_element_t *strmap_set_str(struct map_t *map, const char *strkey, const char *strvalue) {
return map_set_mem(map, strkey, strlen(strkey) + 1, (void*)strvalue, strlen(strvalue) + 1);
}

struct map_element_t *strmap_set_int(struct map_t *map, const char *strkey, int value) {
return map_set_int(map, strkey, strlen(strkey) + 1, value);
}

void* strmap_get(struct map_t *map, const char *strkey) {
return map_get(map, strkey, strlen(strkey) + 1);
}

const char* strmap_get_str(struct map_t *map, const char *strkey) {
return (const char*)strmap_get(map, strkey);
}

int strmap_get_int(struct map_t *map, const char *strkey) {
return map_get_int(map, strkey, strlen(strkey) + 1);
}

void strmap_del(struct map_t *map, const char *strkey) {
map_del_key(map, strkey, strlen(strkey) + 1);
}

void map_dump(const struct map_t *map) {
Expand All @@ -218,28 +248,35 @@ void map_dump(const struct map_t *map) {
fprintf(stderr, "%02x ", ((const uint8_t*)element->key)[j]);
}
fprintf(stderr, "] = ");
if (element->ptrvalue) {
if (element->value_allocated) {
fprintf(stderr, "%d [ ", element->value_len);
for (unsigned int j = 0; j < element->value_len; j++) {
fprintf(stderr, "%02x ", ((const uint8_t*)element->ptrvalue)[j]);
}
fprintf(stderr, "]");
} else {
fprintf(stderr, "%p", element->ptrvalue);
if (element->value_type == ALLOCED_MEMORY) {
fprintf(stderr, "%d [ ", element->value_len);
for (unsigned int j = 0; j < element->value_len; j++) {
fprintf(stderr, "%02x ", ((const uint8_t*)element->value.pointer)[j]);
}
fprintf(stderr, "]");
} else if (element->value_type == VOID_PTR) {
fprintf(stderr, "%p", element->value.pointer);
} else if (element->value_type == INTEGER) {
fprintf(stderr, "%d", element->value.integer);
} else if (element->value_type == UNDEFINED) {
fprintf(stderr, "undefined");
} else {
fprintf(stderr, "NULL");
fprintf(stderr, "unknown");
}
fprintf(stderr, "\n");
}
}

static void map_free_element(struct map_element_t *element) {
free((void*)element->key);
if (element->value_allocated) {
free(element->ptrvalue);
static void map_element_value_free(struct map_element_t *element) {
if (element->value_type == ALLOCED_MEMORY) {
free(element->value.pointer);
element->value_type = UNDEFINED;
}
}

static void map_element_free(struct map_element_t *element) {
free((void*)element->key);
map_element_value_free(element);
free(element);
}

Expand All @@ -251,17 +288,17 @@ void map_foreach(struct map_t *map, void (*callback_fnc)(struct map_element_t *e

void map_foreach_ptrvalue(struct map_t *map, void (*callback_fnc)(void *value)) {
for (unsigned int i = 0; i < map->element_count; i++) {
callback_fnc(map->elements[i]->ptrvalue);
callback_fnc(map->elements[i]->value.pointer);
}
}

void map_free(struct map_t *map) {
map_foreach(map, map_free_element);
map_foreach(map, map_element_free);
free(map->elements);
free(map);
}

struct map_t *map_init(void) {
struct map_t *map_new(void) {
struct map_t *map = calloc(1, sizeof(struct map_t));
return map;
}
Loading

0 comments on commit 24bc884

Please sign in to comment.