mirror of
https://github.com/berlin-open-wireless-lab/DAWN.git
synced 2025-03-09 15:40:12 +00:00
datastorage: fixes to linked list handling
general: fixed whitespace and typos memory audit: on by default in build memory audit: enhanced audit info ubus: refactor denied_req expiry to assist datastorage testing datastorage: fixed performance bug in handling of linked list entry expiry datastorage: fixed SEGV in skip list handling test_storage: added linked list memory allocation stress tests
This commit is contained in:
parent
34da5328f6
commit
117a340b9d
11 changed files with 395 additions and 275 deletions
|
|
@ -212,11 +212,11 @@ int uci_init() {
|
|||
// shouldn't happen?
|
||||
uci_pkg = uci_lookup_package(ctx, "dawn");
|
||||
if (uci_pkg)
|
||||
{
|
||||
{
|
||||
uci_unload(ctx, uci_pkg);
|
||||
dawn_unregmem(uci_pkg);
|
||||
uci_pkg = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (uci_load(ctx, "dawn", &uci_pkg))
|
||||
|
|
|
|||
|
|
@ -8,13 +8,13 @@
|
|||
|
||||
#define DAWN_MEM_FILENAME_LEN 20
|
||||
struct mem_list {
|
||||
struct mem_list* next_mem;
|
||||
int line;
|
||||
char file[DAWN_MEM_FILENAME_LEN];
|
||||
char type;
|
||||
size_t size;
|
||||
void* ptr;
|
||||
uint64_t ref;
|
||||
struct mem_list* next_mem;
|
||||
int line;
|
||||
char file[DAWN_MEM_FILENAME_LEN];
|
||||
char type;
|
||||
size_t size;
|
||||
void* ptr;
|
||||
uint64_t ref;
|
||||
};
|
||||
|
||||
static struct mem_list* mem_base = NULL;
|
||||
|
|
@ -22,157 +22,168 @@ static uint64_t alloc_ref = 0;
|
|||
|
||||
void* dawn_memory_alloc(enum dawn_memop type, char* file, int line, size_t nmemb, size_t size, void *ptr)
|
||||
{
|
||||
void* ret = NULL;
|
||||
void* ret = NULL;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DAWN_MALLOC:
|
||||
ret = malloc(size);
|
||||
break;
|
||||
case DAWN_REALLOC:
|
||||
ret = realloc(ptr, size);
|
||||
if (ret != NULL)
|
||||
dawn_memory_unregister(DAWN_REALLOC, file, line, ptr);
|
||||
break;
|
||||
case DAWN_CALLOC:
|
||||
ret = calloc(nmemb, size);
|
||||
size *= nmemb; // May not be correct allowing for padding but gives a sense of scale
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case DAWN_MALLOC:
|
||||
ret = malloc(size);
|
||||
break;
|
||||
case DAWN_REALLOC:
|
||||
ret = realloc(ptr, size);
|
||||
if (ret != NULL)
|
||||
dawn_memory_unregister(DAWN_REALLOC, file, line, ptr);
|
||||
break;
|
||||
case DAWN_CALLOC:
|
||||
ret = calloc(nmemb, size);
|
||||
size *= nmemb; // May not be correct allowing for padding but gives a sense of scale
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret != NULL)
|
||||
dawn_memory_register(type, file, line, size, ret);
|
||||
if (ret != NULL)
|
||||
dawn_memory_register(type, file, line, size, ret);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t size, void* ptr)
|
||||
{
|
||||
void* ret = NULL;
|
||||
struct mem_list* this_log = NULL;
|
||||
char type_c = '?';
|
||||
void* ret = NULL;
|
||||
struct mem_list* this_log = NULL;
|
||||
char type_c = '?';
|
||||
|
||||
// Ignore over enthusiastic effort to register a failed allocation
|
||||
if (ptr == NULL)
|
||||
return ret;
|
||||
// Ignore over enthusiastic effort to register a failed allocation
|
||||
if (ptr == NULL)
|
||||
return ret;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DAWN_MALLOC:
|
||||
type_c = 'M';
|
||||
break;
|
||||
case DAWN_REALLOC:
|
||||
type_c = 'R';
|
||||
break;
|
||||
case DAWN_CALLOC:
|
||||
type_c = 'C';
|
||||
break;
|
||||
case DAWN_MEMREG:
|
||||
type_c = 'X';
|
||||
break;
|
||||
default:
|
||||
printf("mem-audit: Unexpected memory op tag!\n");
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case DAWN_MALLOC:
|
||||
type_c = 'M';
|
||||
break;
|
||||
case DAWN_REALLOC:
|
||||
type_c = 'R';
|
||||
break;
|
||||
case DAWN_CALLOC:
|
||||
type_c = 'C';
|
||||
break;
|
||||
case DAWN_MEMREG:
|
||||
type_c = 'X';
|
||||
break;
|
||||
default:
|
||||
printf("mem-audit: Unexpected memory op tag!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
// Insert to linked list with ascending memory reference
|
||||
struct mem_list** ipos = &mem_base;
|
||||
while (*ipos != NULL && (*ipos)->ptr < ptr)
|
||||
ipos = &((*ipos)->next_mem);
|
||||
// Insert to linked list with ascending memory reference
|
||||
struct mem_list** ipos = &mem_base;
|
||||
while (*ipos != NULL && (*ipos)->ptr < ptr)
|
||||
ipos = &((*ipos)->next_mem);
|
||||
|
||||
if (*ipos != NULL && (*ipos)->ptr == ptr)
|
||||
{
|
||||
printf("mem-audit: attempting to register memory already registered (%c@%s:%d)...\n", type_c, file, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_log = malloc(sizeof(struct mem_list));
|
||||
if (*ipos != NULL && (*ipos)->ptr == ptr)
|
||||
{
|
||||
printf("mem-audit: attempting to register memory already registered (%c@%s:%d)...\n", type_c, file, line);
|
||||
}
|
||||
else
|
||||
{
|
||||
this_log = malloc(sizeof(struct mem_list));
|
||||
|
||||
if (this_log == NULL)
|
||||
{
|
||||
printf("mem-audit: Oh the irony! malloc() failed in dawn_memory_register()!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
this_log->next_mem = *ipos;
|
||||
*ipos = this_log;
|
||||
if (this_log == NULL)
|
||||
{
|
||||
printf("mem-audit: Oh the irony! malloc() failed in dawn_memory_register()!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
this_log->next_mem = *ipos;
|
||||
*ipos = this_log;
|
||||
|
||||
// Just use filename - no path
|
||||
file = strrchr(file, '/');
|
||||
// Just use filename - no path
|
||||
file = strrchr(file, '/');
|
||||
|
||||
if (file != NULL)
|
||||
strncpy(this_log->file, file + 1, DAWN_MEM_FILENAME_LEN);
|
||||
else
|
||||
strncpy(this_log->file, "?? UNKNOWN ??", DAWN_MEM_FILENAME_LEN);
|
||||
if (file != NULL)
|
||||
strncpy(this_log->file, file + 1, DAWN_MEM_FILENAME_LEN);
|
||||
else
|
||||
strncpy(this_log->file, "?? UNKNOWN ??", DAWN_MEM_FILENAME_LEN);
|
||||
|
||||
this_log->type = type_c;
|
||||
this_log->line = line;
|
||||
this_log->ptr = ptr;
|
||||
this_log->size = size;
|
||||
this_log->ref = alloc_ref++;
|
||||
}
|
||||
}
|
||||
this_log->type = type_c;
|
||||
this_log->line = line;
|
||||
this_log->ptr = ptr;
|
||||
this_log->size = size;
|
||||
this_log->ref = alloc_ref++;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void dawn_memory_unregister(enum dawn_memop type, char* file, int line, void* ptr)
|
||||
{
|
||||
struct mem_list** mem = &mem_base;
|
||||
char type_c = '?';
|
||||
struct mem_list** mem = &mem_base;
|
||||
char type_c = '?';
|
||||
|
||||
while (*mem != NULL && (*mem)->ptr < ptr)
|
||||
{
|
||||
mem = &((*mem)->next_mem);
|
||||
}
|
||||
while (*mem != NULL && (*mem)->ptr < ptr)
|
||||
{
|
||||
mem = &((*mem)->next_mem);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case DAWN_FREE:
|
||||
type_c = 'F';
|
||||
break;
|
||||
case DAWN_MEMUNREG:
|
||||
type_c = 'U';
|
||||
break;
|
||||
case DAWN_REALLOC:
|
||||
type_c = 'R';
|
||||
break;
|
||||
default:
|
||||
printf("mem-audit: Unexpected memory op tag!\n");
|
||||
break;
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case DAWN_FREE:
|
||||
type_c = 'F';
|
||||
break;
|
||||
case DAWN_MEMUNREG:
|
||||
type_c = 'U';
|
||||
break;
|
||||
case DAWN_REALLOC:
|
||||
type_c = 'R';
|
||||
break;
|
||||
default:
|
||||
printf("mem-audit: Unexpected memory op tag!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
if (*mem != NULL && (*mem)->ptr == ptr)
|
||||
{
|
||||
struct mem_list* tmp = *mem;
|
||||
*mem = tmp->next_mem;
|
||||
free(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mem-audit: Releasing (%c) memory we hadn't registered (%s:%d)...\n", type_c, file, line);
|
||||
}
|
||||
if (*mem != NULL && (*mem)->ptr == ptr)
|
||||
{
|
||||
struct mem_list* tmp = *mem;
|
||||
*mem = tmp->next_mem;
|
||||
free(tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("mem-audit: Releasing (%c) memory we hadn't registered (%s:%d)...\n", type_c, file, line);
|
||||
}
|
||||
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
void dawn_memory_free(enum dawn_memop type, char* file, int line, void* ptr)
|
||||
{
|
||||
dawn_memory_unregister(type, file, line, ptr);
|
||||
|
||||
free(ptr);
|
||||
dawn_memory_unregister(type, file, line, ptr);
|
||||
|
||||
return;
|
||||
free(ptr);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void dawn_memory_audit()
|
||||
{
|
||||
printf("mem-audit: Currently recorded allocations...\n");
|
||||
for (struct mem_list* mem = mem_base; mem != NULL; mem = mem->next_mem)
|
||||
{
|
||||
printf("mem-audit: %8" PRIu64 "=%c - %s@%d: %zu\n", mem->ref, mem->type, mem->file, mem->line, mem->size);
|
||||
}
|
||||
printf("mem-audit: [End of list]\n");
|
||||
size_t total = 0;
|
||||
|
||||
printf("mem-audit: Currently recorded allocations...\n");
|
||||
for (struct mem_list* mem = mem_base; mem != NULL; mem = mem->next_mem)
|
||||
{
|
||||
printf("mem-audit: %8" PRIu64 "=%c - %s@%d: %zu\n", mem->ref, mem->type, mem->file, mem->line, mem->size);
|
||||
total += mem->size;
|
||||
}
|
||||
|
||||
char *suffix = "bytes";
|
||||
if (total > 128 * 1024)
|
||||
{
|
||||
total /= 1024;
|
||||
suffix = "kbytes";
|
||||
}
|
||||
|
||||
printf("mem-audit: [End of list: %zu %s]\n", total, suffix);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -283,8 +283,7 @@ int handle_network_msg(char* msg) {
|
|||
if (strncmp(method, "probe", 5) == 0) {
|
||||
probe_entry *entry = parse_to_probe_req(data_buf.head);
|
||||
if (entry != NULL) {
|
||||
entry->time = time(0);
|
||||
if (entry != insert_to_array(entry, false, false, false)) // use 802.11k values
|
||||
if (entry != insert_to_array(entry, false, false, false, time(0))) // use 802.11k values
|
||||
{
|
||||
// insert found an existing entry, rather than linking in our new one
|
||||
dawn_free(entry);
|
||||
|
|
@ -425,11 +424,9 @@ dump_client(struct blob_attr** tb, struct dawn_mac client_addr, const char* bssi
|
|||
memset(client_entry->signature, 0, SIGNATURE_LEN);
|
||||
}
|
||||
|
||||
client_entry->time = time(0);
|
||||
|
||||
pthread_mutex_lock(&client_array_mutex);
|
||||
// If entry was akraedy in list it won't be added, so free memorY
|
||||
if (client_entry != insert_client_to_array(client_entry))
|
||||
if (client_entry != insert_client_to_array(client_entry, time(0)))
|
||||
dawn_free(client_entry);
|
||||
pthread_mutex_unlock(&client_array_mutex);
|
||||
}
|
||||
|
|
@ -559,8 +556,7 @@ int parse_to_clients(struct blob_attr* msg, int do_kick, uint32_t id) {
|
|||
ap_entry->hostname[0] = '\0';
|
||||
}
|
||||
|
||||
ap_entry->time = time(0);
|
||||
insert_to_ap_array(ap_entry);
|
||||
insert_to_ap_array(ap_entry, time(0));
|
||||
|
||||
if (do_kick && dawn_metric.kicking) {
|
||||
update_iw_info(ap_entry->bssid_addr);
|
||||
|
|
|
|||
|
|
@ -370,10 +370,9 @@ int parse_to_beacon_rep(struct blob_attr *msg) {
|
|||
beacon_rep->ht_capabilities = false; // that is very problematic!!!
|
||||
beacon_rep->vht_capabilities = false; // that is very problematic!!!
|
||||
printf("Inserting to array!\n");
|
||||
beacon_rep->time = time(0);
|
||||
|
||||
// TODO: kept original code order here - send on network first to simplify?
|
||||
if (beacon_rep != insert_to_array(beacon_rep, false, false, true)) // use 802.11k values // TODO: Change 0 to false?
|
||||
if (beacon_rep != insert_to_array(beacon_rep, false, false, true, time(0))) // use 802.11k values // TODO: Change 0 to false?
|
||||
{
|
||||
// insert found an existing entry, rather than linking in our new one
|
||||
ubus_send_probe_via_network(beacon_rep);
|
||||
|
|
@ -415,13 +414,12 @@ bool discard_entry = true;
|
|||
}
|
||||
|
||||
if (dawn_metric.use_driver_recog) {
|
||||
auth_req->time = time(0);
|
||||
if (auth_req == insert_to_denied_req_array(auth_req, 1))
|
||||
discard_entry = false;
|
||||
if (auth_req == insert_to_denied_req_array(auth_req, 1, time(0)))
|
||||
discard_entry = false;
|
||||
}
|
||||
ret = dawn_metric.deny_auth_reason;
|
||||
}
|
||||
else
|
||||
else
|
||||
// maybe send here that the client is connected?
|
||||
printf("Allow authentication!\n");
|
||||
}
|
||||
|
|
@ -454,21 +452,20 @@ int discard_entry = true;
|
|||
|
||||
// block if entry was not already found in probe database
|
||||
if (tmp == NULL || !decide_function(tmp, REQ_TYPE_ASSOC)) {
|
||||
if (tmp != NULL)
|
||||
{
|
||||
if (tmp != NULL)
|
||||
{
|
||||
printf("Entry found\n");
|
||||
print_probe_entry(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
printf("Deny associtation!\n");
|
||||
if (dawn_metric.use_driver_recog) {
|
||||
auth_req->time = time(0);
|
||||
if (auth_req == insert_to_denied_req_array(auth_req, 1))
|
||||
if (auth_req == insert_to_denied_req_array(auth_req, 1, time(0)))
|
||||
discard_entry = false;
|
||||
}
|
||||
return dawn_metric.deny_assoc_reason;
|
||||
}
|
||||
else
|
||||
else
|
||||
printf("Allow association!\n");
|
||||
}
|
||||
|
||||
|
|
@ -483,10 +480,10 @@ static int handle_probe_req(struct blob_attr *msg) {
|
|||
probe_entry* probe_req = parse_to_probe_req(msg);
|
||||
|
||||
if (probe_req != NULL) {
|
||||
probe_req->time = time(0);
|
||||
if (probe_req != insert_to_array(probe_req, true, true, false))
|
||||
if (probe_req != insert_to_array(probe_req, true, true, false, time(0)))
|
||||
{
|
||||
// insert found an existing entry, rather than linking in our new one
|
||||
// use new entry even though it wasn't linked: they are equivalent
|
||||
ubus_send_probe_via_network(probe_req);
|
||||
dawn_free(probe_req);
|
||||
}
|
||||
|
|
@ -1077,13 +1074,6 @@ static int add_mac(struct ubus_context *ctx, struct ubus_object *obj,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int send_add_mac(struct dawn_mac client_addr) {
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_macaddr(&b, "addr", client_addr);
|
||||
send_blob_attr_via_network(b.head, "addmac");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reload_config(struct ubus_context *ctx, struct ubus_object *obj,
|
||||
struct ubus_request_data *req, const char *method,
|
||||
struct blob_attr *msg) {
|
||||
|
|
@ -1405,8 +1395,8 @@ int build_hearing_map_sort_client(struct blob_buf *b) {
|
|||
client_list = blobmsg_open_table(b, client_mac_buf);
|
||||
probe_entry *k;
|
||||
for (k = i;
|
||||
k != NULL && mac_is_equal_bb(k->client_addr, i->client_addr);
|
||||
k = k->next_probe) {
|
||||
k != NULL && mac_is_equal_bb(k->client_addr, i->client_addr);
|
||||
k = k->next_probe) {
|
||||
|
||||
ap *ap_k = ap_array_get_ap(k->bssid_addr);
|
||||
|
||||
|
|
@ -1439,14 +1429,14 @@ int build_hearing_map_sort_client(struct blob_buf *b) {
|
|||
// TODO: Change this so that i and k are single loop?
|
||||
i = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((m->next_ap == NULL) || strcmp((char*)m->ssid, (char*)((m->next_ap)->ssid)) != 0)
|
||||
{
|
||||
blobmsg_close_table(b, ssid_list);
|
||||
{
|
||||
blobmsg_close_table(b, ssid_list);
|
||||
same_ssid = false;
|
||||
}
|
||||
else
|
||||
}
|
||||
else
|
||||
same_ssid = true;
|
||||
}
|
||||
|
||||
|
|
@ -1627,39 +1617,15 @@ void denied_req_array_cb(struct uloop_timeout* t) {
|
|||
pthread_mutex_lock(&denied_array_mutex);
|
||||
printf("[ULOOP] : Processing denied authentication!\n");
|
||||
|
||||
time_t current_time = time(0);
|
||||
remove_old_denied_req_entries(time(0), timeout_config.denied_req_threshold, true);
|
||||
|
||||
auth_entry** i = &denied_req_set;
|
||||
while (*i != NULL) {
|
||||
// check counter
|
||||
|
||||
//check timer
|
||||
if ((*i)->time < (current_time - timeout_config.denied_req_threshold)) {
|
||||
|
||||
// client is not connected for a given time threshold!
|
||||
if (!is_connected_somehwere((*i)->client_addr)) {
|
||||
printf("Client has probably a bad driver!\n");
|
||||
|
||||
// problem that somehow station will land into this list
|
||||
// maybe delete again?
|
||||
if (insert_to_maclist((*i)->client_addr) == 0) {
|
||||
send_add_mac((*i)->client_addr);
|
||||
// TODO: File can grow arbitarily large. Resource consumption risk.
|
||||
// TODO: Consolidate use of file across source: shared resource for name, single point of access?
|
||||
write_mac_to_file("/tmp/dawn_mac_list", (*i)->client_addr);
|
||||
}
|
||||
}
|
||||
// TODO: Add unlink function to save rescan to find element
|
||||
denied_req_array_delete(*i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i = &((*i)->next_auth);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&denied_array_mutex);
|
||||
uloop_timeout_set(&denied_req_timeout, timeout_config.denied_req_threshold * 1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int send_add_mac(struct dawn_mac client_addr) {
|
||||
blob_buf_init(&b, 0);
|
||||
blobmsg_add_macaddr(&b, "addr", client_addr);
|
||||
send_blob_attr_via_network(b.head, "addmac");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue