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:
Ian Clowes 2020-08-05 11:03:06 +01:00 committed by Polynomialdivision
parent 34da5328f6
commit 117a340b9d
11 changed files with 395 additions and 275 deletions

View file

@ -250,7 +250,7 @@ extern struct client_s *client_set_bc;
extern pthread_mutex_t client_array_mutex;
// ---------------- Functions ----------------
probe_entry *insert_to_array(probe_entry *entry, int inc_counter, int save_80211k, int is_beacon);
probe_entry *insert_to_array(probe_entry *entry, int inc_counter, int save_80211k, int is_beacon, time_t expiry);
int probe_array_delete(probe_entry *entry);
@ -266,7 +266,9 @@ int eval_probe_metric(struct probe_entry_s * probe_entry, ap *ap_entry);
void denied_req_array_delete(auth_entry *entry);
auth_entry *insert_to_denied_req_array(auth_entry*entry, int inc_counter);
auth_entry *insert_to_denied_req_array(auth_entry*entry, int inc_counter, time_t expiry);
void remove_old_denied_req_entries(time_t current_time, long long int threshold, int logmac);
void print_auth_entry(auth_entry *entry);
@ -278,7 +280,7 @@ int probe_array_update_rcpi_rsni(struct dawn_mac bssid_addr, struct dawn_mac cli
void remove_old_client_entries(time_t current_time, long long int threshold);
client *insert_client_to_array(client *entry);
client *insert_client_to_array(client *entry, time_t expiry);
int kick_clients(ap* kicking_ap, uint32_t id);
@ -296,7 +298,7 @@ void print_client_entry(client *entry);
int is_connected_somehwere(struct dawn_mac client_addr);
ap *insert_to_ap_array(ap *entry);
ap *insert_to_ap_array(ap *entry, time_t expiry);
void remove_old_ap_entries(time_t current_time, long long int threshold);

View file

@ -5,15 +5,15 @@
enum dawn_memop
{
DAWN_MALLOC,
DAWN_CALLOC,
DAWN_REALLOC,
DAWN_MEMREG,
DAWN_MEMUNREG,
DAWN_FREE
DAWN_MALLOC,
DAWN_CALLOC,
DAWN_REALLOC,
DAWN_MEMREG,
DAWN_MEMUNREG,
DAWN_FREE
};
//#define DAWN_MEMORY_AUDITING
#define DAWN_MEMORY_AUDITING
#ifdef DAWN_MEMORY_AUDITING
#define dawn_malloc(size) dawn_memory_alloc(DAWN_MALLOC, __FILE__, __LINE__, 1, size, NULL)

View file

@ -68,13 +68,6 @@ void del_client_all_interfaces(const struct dawn_mac client_addr, uint32_t reaso
*/
void update_hostapd_sockets(struct uloop_timeout *t);
/**
* Send control message to all hosts to add the mac to a don't control list.
* @param client_addr
* @return
*/
int send_add_mac(struct dawn_mac client_addr);
void ubus_send_beacon_report(struct dawn_mac client, int id);
void uloop_add_data_cbs();
@ -148,4 +141,11 @@ int send_set_probe(struct dawn_mac client_addr);
*/
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, char* dest_ap, uint32_t duration);
/**
* Send control message to all hosts to add the mac to a don't control list.
* @param client_addr
* @return
*/
int send_add_mac(struct dawn_mac client_addr);
#endif

View file

@ -85,7 +85,7 @@ static const struct dawn_mac dawn_mac_null = { .u8 = {0,0,0,0,0,0} };
** then the target element does not exist, but can be inserted by using the returned reference.
*/
static struct probe_entry_s** probe_skip_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, bool do_bssid)
static struct probe_entry_s** probe_skip_array_find_first_entry(struct dawn_mac client_mac, struct dawn_mac bssid_mac, int do_bssid)
{
int lo = 0;
struct probe_entry_s** lo_ptr = &probe_skip_set;
@ -752,7 +752,7 @@ void client_array_insert(client *entry, client** insert_pos) {
client_entry_last++;
if (client_entry_last == ARRAY_CLIENT_LEN) {
printf("warning: client_array overflowing (now contains %d entires)!\n", client_entry_last);
printf("warning: client_array overflowing (now contains %d entries)!\n", client_entry_last);
}
// Try to keep skip list density stable
@ -788,6 +788,15 @@ static client* client_array_unlink_entry(client** ref_bc, int unlink_only)
{
client* entry = *ref_bc; // Both ref_bc and ref_c point to the entry we're deleting
for (struct client_s** s = &client_skip_set; *s != NULL; s = &((*s)->next_skip_entry_bc)) {
if (*s == entry) {
*s = (*s)->next_skip_entry_bc;
client_skip_entry_last--;
break;
}
}
// Accident of history that we always pass in the _bc ref, so need to find _c ref
#ifndef DAWN_CLIENT_SCAN_BC_ONLY
client** ref_c = &client_set_c;
@ -818,15 +827,6 @@ static client* client_array_unlink_entry(client** ref_bc, int unlink_only)
client *client_array_delete(client *entry, int unlink_only) {
client* ret = NULL;
for (struct client_s** s = &client_skip_set; *s != NULL; s = &((*s)->next_skip_entry_bc)) {
if (*s == entry) {
*s = (*s)->next_skip_entry_bc;
client_skip_entry_last--;
break;
}
}
client** ref_bc = NULL;
// Bodyless for-loop: test done in control logic
@ -871,9 +871,19 @@ static __inline__ int probe_compare(probe_entry* probe1, probe_entry* probe2) {
static __inline__ void probe_array_unlink_next(probe_entry** i)
{
probe_entry* victim;
probe_entry* victim = *i;
// TODO: Can we pre-test that entry is in skip set with
// if ((*s)->next_probe_skip != NULL)... ???
for (struct probe_entry_s** s = &probe_skip_set; *s != NULL; s = &((*s)->next_probe_skip)) {
if (*s == victim) {
*s = (*s)->next_probe_skip;
probe_skip_entry_last--;
break;
}
}
victim = *i;
*i = victim->next_probe;
dawn_free(victim);
@ -883,15 +893,6 @@ probe_entry* victim;
int probe_array_delete(probe_entry *entry) {
int found_in_array = false;
for (struct probe_entry_s** s = &probe_skip_set; *s != NULL; s = &((*s)->next_probe_skip)) {
if (*s == entry) {
*s = (*s)->next_probe_skip;
probe_skip_entry_last--;
break;
}
}
for (probe_entry** i = &probe_set; *i != NULL; i = &((*i)->next_probe)) {
if (*i == entry) {
probe_array_unlink_next(i);
@ -993,13 +994,16 @@ static struct probe_entry_s* insert_to_skip_array(struct probe_entry_s* entry) {
return entry;
}
probe_entry* insert_to_array(probe_entry* entry, int inc_counter, int save_80211k, int is_beacon) {
probe_entry* insert_to_array(probe_entry* entry, int inc_counter, int save_80211k, int is_beacon, time_t expiry) {
pthread_mutex_lock(&probe_array_mutex);
entry->time = expiry;
// TODO: Add a packed / unpacked wrapper pair?
probe_entry** existing_entry = probe_array_find_first_entry(entry->client_addr, entry->bssid_addr, true);
if (((*existing_entry) != NULL) && mac_is_equal_bb((*existing_entry)->client_addr, entry->client_addr) && mac_is_equal_bb((*existing_entry)->bssid_addr, entry->bssid_addr)) {
(*existing_entry)->time = expiry;
if (inc_counter)
(*existing_entry)->counter++;
@ -1019,18 +1023,18 @@ probe_entry* insert_to_array(probe_entry* entry, int inc_counter, int save_80211
else
entry->counter = 0;
entry->next_probe_skip = NULL;
entry->next_probe = *existing_entry;
*existing_entry = entry;
probe_entry_last++;
if (probe_entry_last == PROBE_ARRAY_LEN) {
printf("warning: probe_array overflowing (now contains %d entires)!\n", probe_entry_last);
printf("warning: probe_array overflowing (now contains %d entries)!\n", probe_entry_last);
}
// Try to keep skip list density stable
if ((probe_entry_last / DAWN_PROBE_SKIP_RATIO) > probe_skip_entry_last)
{
entry->next_probe_skip = NULL;
insert_to_skip_array(entry);
}
}
@ -1040,7 +1044,7 @@ probe_entry* insert_to_array(probe_entry* entry, int inc_counter, int save_80211
return entry; // return pointer to what we used, which may not be what was passed in
}
ap *insert_to_ap_array(ap* entry) {
ap *insert_to_ap_array(ap* entry, time_t expiry) {
pthread_mutex_lock(&ap_array_mutex);
@ -1054,6 +1058,7 @@ ap *insert_to_ap_array(ap* entry) {
if (old_entry != NULL)
ap_array_delete(old_entry);
entry->time = expiry;
ap_array_insert(entry);
pthread_mutex_unlock(&ap_array_mutex);
@ -1096,7 +1101,7 @@ void ap_array_insert(ap* entry) {
ap_entry_last++;
if (ap_entry_last == ARRAY_AP_LEN) {
printf("warning: ap_array overflowing (contains %d entires)!\n", ap_entry_last);
printf("warning: ap_array overflowing (contains %d entries)!\n", ap_entry_last);
}
}
@ -1176,16 +1181,50 @@ void remove_old_ap_entries(time_t current_time, long long int threshold) {
}
}
client *insert_client_to_array(client *entry) {
void remove_old_denied_req_entries(time_t current_time, long long int threshold, int logmac) {
auth_entry** i = &denied_req_set;
while (*i != NULL) {
// check counter
//check timer
if ((*i)->time < (current_time - threshold)) {
// client is not connected for a given time threshold!
if (logmac && !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);
}
}
}
client *insert_client_to_array(client *entry, time_t expiry) {
client * ret = NULL;
client **client_tmp = client_find_first_bc_entry(entry->bssid_addr, entry->client_addr, true);
if (*client_tmp == NULL || !mac_is_equal_bb(entry->bssid_addr, (*client_tmp)->bssid_addr) || !mac_is_equal_bb(entry->client_addr, (*client_tmp)->client_addr)) {
entry->kick_count = 0;
entry->time = expiry;
client_array_insert(entry, client_tmp);
ret = entry;
}
else
(*client_tmp)->time = expiry;
return ret;
}
@ -1208,12 +1247,12 @@ void insert_macs_from_file() {
while ((read = getline(&line, &len, fp)) != -1) {
#ifdef DAWN_MEMORY_AUDITING
if (old_line != line)
{
if (old_line != NULL)
dawn_unregmem(old_line);
old_line = line;
dawn_regmem(old_line);
}
{
if (old_line != NULL)
dawn_unregmem(old_line);
old_line = line;
dawn_regmem(old_line);
}
#endif
printf("Retrieved line of length %zu :\n", read);
@ -1295,7 +1334,7 @@ struct mac_entry_s** i = mac_find_first_entry(mac);
return ret;
}
auth_entry* insert_to_denied_req_array(auth_entry* entry, int inc_counter) {
auth_entry* insert_to_denied_req_array(auth_entry* entry, int inc_counter, time_t expiry) {
pthread_mutex_lock(&denied_array_mutex);
auth_entry** i = auth_entry_find_first_entry(entry->bssid_addr, entry->client_addr);
@ -1304,12 +1343,14 @@ auth_entry* insert_to_denied_req_array(auth_entry* entry, int inc_counter) {
entry = *i;
entry->time = expiry;
if (inc_counter) {
entry->counter++;
}
}
else
{
entry->time = expiry;
if (inc_counter)
entry->counter++;
else
@ -1320,7 +1361,7 @@ auth_entry* insert_to_denied_req_array(auth_entry* entry, int inc_counter) {
denied_req_last++;
if (denied_req_last == DENY_REQ_ARRAY_LEN) {
printf("warning: denied_req_array overflowing (now contains %d entires)!\n", denied_req_last);
printf("warning: denied_req_array overflowing (now contains %d entries)!\n", denied_req_last);
}
}
@ -1354,7 +1395,7 @@ struct mac_entry_s* insert_to_mac_array(struct mac_entry_s* entry, struct mac_en
mac_set_last++;
if (mac_set_last == DENY_REQ_ARRAY_LEN) {
printf("warning: denied_req_array overflowing (now contains %d entires)!\n", mac_set_last);
printf("warning: denied_req_array overflowing (now contains %d entries)!\n", mac_set_last);
}
return entry;

View file

@ -0,0 +1,3 @@
probe_stress 10000
#probe_show
memaudit

View file

@ -5,5 +5,5 @@
int main(int argc, char* argv[])
{
return 0;
}
return 0;
}

View file

@ -34,7 +34,7 @@ int ret = 0;
client *mc = client_array_get_client(client_addr);
mc = client_array_delete(mc, true);
hwaddr_aton(dest_ap, mc->bssid_addr.u8);
insert_client_to_array(mc);
insert_client_to_array(mc, 0);
printf("BSS TRANSITION TO %s\n", dest_ap);
// Tell caller not to change the arrays any further
@ -81,12 +81,19 @@ int get_bandwidth_iwinfo(struct dawn_mac client_addr, float* rx_rate, float* tx_
return 0;
}
int send_add_mac(struct dawn_mac client_addr)
{
printf("send_add_mac() was called...\n");
return 0;
}
/*** Local Function Prototypes and Related Constants ***/
static int array_auto_helper(int action, int i0, int i1);
#define HELPER_ACTION_ADD 0x0000
#define HELPER_ACTION_DEL 0x1000
#define HELPER_ACTION_MASK 0x1000
#define HELPER_ACTION_ADD 0x1000
#define HELPER_ACTION_DEL 0x2000
#define HELPER_ACTION_STRESS 0x4000
#define HELPER_ACTION_MASK 0x7000
#define HELPER_AP 0x0001
#define HELPER_CLIENT 0x0002
@ -102,6 +109,33 @@ static time_t faketime = 1000;
static bool faketime_auto = true; // true = increment every command; false = scripted updates
/*** Test harness code */
static void time_moves_on()
{
// Sometimes move fake time on a second - about 1 in 5 chance
if (((rand() & 0xFF) > 200))
{
faketime += 1;
}
return;
}
static void set_random_mac(uint8_t *mac)
{
int16_t r1 = rand();
int16_t r2 = rand();
int16_t r3 = rand();
mac[0] = r1;
mac[1] = r1 >> 4;
mac[2] = r2;
mac[3] = r2 >> 4;
mac[4] = r3;
mac[5] = r3 >> 4;
return;
}
static int array_auto_helper(int action, int i0, int i1)
{
int m = i0;
@ -125,7 +159,15 @@ static int array_auto_helper(int action, int i0, int i1)
ap* ap0 = dawn_malloc(sizeof(struct ap_s));
ap0->bssid_addr = this_mac;
insert_to_ap_array(ap0);
insert_to_ap_array(ap0, 0);
}
else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) {
ap* ap0 = dawn_malloc(sizeof(struct ap_s));
set_random_mac(ap0->bssid_addr.u8);
insert_to_ap_array(ap0, faketime);
remove_old_ap_entries(faketime, 10);
time_moves_on();
}
else
ap_array_delete(ap_array_get_ap(this_mac));
@ -138,7 +180,16 @@ static int array_auto_helper(int action, int i0, int i1)
client0->bssid_addr = this_mac;
client0->client_addr = this_mac;
insert_client_to_array(client0);
insert_client_to_array(client0, 0);
}
else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) {
client* client0 = dawn_malloc(sizeof(struct client_s));
set_random_mac(client0->client_addr.u8);
set_random_mac(client0->bssid_addr.u8);
insert_client_to_array(client0, faketime);
remove_old_client_entries(faketime, 10);
time_moves_on();
}
else
{
@ -157,7 +208,16 @@ static int array_auto_helper(int action, int i0, int i1)
probe0->client_addr = this_mac;
probe0->bssid_addr = this_mac;
insert_to_array(probe0, true, true, true); // TODO: Check bool flags
insert_to_array(probe0, true, true, true, 0); // TODO: Check bool flags
}
else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) {
probe0 = dawn_malloc(sizeof(probe_entry));
set_random_mac(probe0->client_addr.u8);
set_random_mac(probe0->bssid_addr.u8);
insert_to_array(probe0, true, true, true, faketime);
remove_old_probe_entries(faketime, 10);
time_moves_on();
}
else
{
@ -180,7 +240,16 @@ static int array_auto_helper(int action, int i0, int i1)
auth_entry0->bssid_addr = this_mac;
auth_entry0->client_addr = this_mac;
insert_to_denied_req_array(auth_entry0, true); // TODO: Check bool flags
insert_to_denied_req_array(auth_entry0, true, 0); // TODO: Check bool flags
}
else if ((action & HELPER_ACTION_MASK) == HELPER_ACTION_STRESS) {
auth_entry* auth_entry0 = dawn_malloc(sizeof(struct auth_entry_s));
set_random_mac(auth_entry0->bssid_addr.u8);
set_random_mac(auth_entry0->client_addr.u8);
insert_to_denied_req_array(auth_entry0, true, faketime);
remove_old_denied_req_entries(faketime, 10, false);
time_moves_on();
}
else
{
@ -406,6 +475,14 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
ret = array_auto_helper(HELPER_AP | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "ap_stress") == 0)
{
args_required = 2;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_AP | HELPER_ACTION_STRESS, 1, atoi(*(argv + 1)));
}
}
else if (strcmp(*argv, "probe_add_auto") == 0)
{
args_required = 3;
@ -422,6 +499,14 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
ret = array_auto_helper(HELPER_PROBE_ARRAY | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "probe_stress") == 0)
{
args_required = 2;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_PROBE_ARRAY | HELPER_ACTION_STRESS, 1, atoi(*(argv + 1)));
}
}
else if (strcmp(*argv, "client_add_auto") == 0)
{
args_required = 3;
@ -438,6 +523,14 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
ret = array_auto_helper(HELPER_CLIENT | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "client_stress") == 0)
{
args_required = 2;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_CLIENT | HELPER_ACTION_STRESS, 1, atoi(*(argv + 1)));
}
}
else if (strcmp(*argv, "auth_entry_add_auto") == 0)
{
args_required = 3;
@ -454,6 +547,14 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
ret = array_auto_helper(HELPER_AUTH_ENTRY | HELPER_ACTION_DEL, atoi(*(argv + 1)), atoi(*(argv + 2)));
}
}
else if (strcmp(*argv, "auth_entry_stress") == 0)
{
args_required = 2;
if (curr_arg + args_required <= argc)
{
ret = array_auto_helper(HELPER_AUTH_ENTRY | HELPER_ACTION_STRESS, 1, atoi(*(argv + 1)));
}
}
else if (strcmp(*argv, "remove_old_ap_entries") == 0)
{
args_required = 2;
@ -633,7 +734,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
}
if (ret == 0)
insert_to_ap_array(ap0);
insert_to_ap_array(ap0, ap0->time);
else
dawn_free(ap0);
}
@ -697,7 +798,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
if (ret == 0)
{
insert_client_to_array(cl0);
insert_client_to_array(cl0, cl0->time);
}
}
else if (strcmp(*argv, "probe") == 0)
@ -776,7 +877,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
pr0->rcpi = 0;
pr0->rsni = 0;
insert_to_array(pr0, true, true, true);
insert_to_array(pr0, true, true, true, pr0->time);
}
}
@ -821,7 +922,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
if (ret == 0)
{
insert_to_denied_req_array(au0, true);
insert_to_denied_req_array(au0, true, au0->time);
}
}
else if (strcmp(*argv, "kick") == 0) // Perform kicking evaluation
@ -908,30 +1009,29 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
}
}
else
{
{
args_required = 1;
printf("COMMAND \"%s\": Unknown - stopping!\n", *argv);
printf("COMMAND \"%s\": Unknown - stopping!\n", *argv);
ret = -1;
}
}
curr_arg += args_required;
curr_arg += args_required;
if (curr_arg <= argc)
{
// Still need to continue consuming args
argv += args_required;
// Sometimes move fake time on a second - about 1 in 5 chance
if (faketime_auto && ((rand() & 0xFF) > 200))
if (faketime_auto)
{
faketime += 1;
time_moves_on();
if (harness_verbosity > 0)
{
if (!(faketime & 1))
printf("Faketime: tick %" PRId64 "...\n", (int64_t)faketime);
else
printf("Faketime: tock %" PRId64 "...\n", (int64_t)faketime);
if (!(faketime & 1))
printf("Faketime: tick %" PRId64 "...\n", (int64_t)faketime);
else
printf("Faketime: tock %" PRId64 "...\n", (int64_t)faketime);
}
}
}
@ -1088,6 +1188,7 @@ int main(int argc, char* argv[])
if (ret == 0)
{
read = getline(&line, &len, fp);
dawn_regmem(line);
while (!ret && read != -1)
{
if (harness_verbosity > 0)

View file

@ -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))

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}