diff --git a/src/include/datastorage.h b/src/include/datastorage.h index 5fc77c1..cb60a33 100644 --- a/src/include/datastorage.h +++ b/src/include/datastorage.h @@ -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); diff --git a/src/include/memory_utils.h b/src/include/memory_utils.h index 7f97417..b02c5ac 100644 --- a/src/include/memory_utils.h +++ b/src/include/memory_utils.h @@ -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) diff --git a/src/include/ubus.h b/src/include/ubus.h index ad36c44..78e06cd 100644 --- a/src/include/ubus.h +++ b/src/include/ubus.h @@ -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 diff --git a/src/storage/datastorage.c b/src/storage/datastorage.c index faa4ed3..6b0e1e9 100644 --- a/src/storage/datastorage.c +++ b/src/storage/datastorage.c @@ -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; diff --git a/src/test/probe_stress_10k.script b/src/test/probe_stress_10k.script new file mode 100644 index 0000000..d6bef16 --- /dev/null +++ b/src/test/probe_stress_10k.script @@ -0,0 +1,3 @@ +probe_stress 10000 +#probe_show +memaudit diff --git a/src/test/test_header.c b/src/test/test_header.c index 9b9aa25..a73c428 100644 --- a/src/test/test_header.c +++ b/src/test/test_header.c @@ -5,5 +5,5 @@ int main(int argc, char* argv[]) { - return 0; -} \ No newline at end of file + return 0; +} diff --git a/src/test/test_storage.c b/src/test/test_storage.c index 3679a65..4b4ef6a 100644 --- a/src/test/test_storage.c +++ b/src/test/test_storage.c @@ -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) diff --git a/src/utils/dawn_uci.c b/src/utils/dawn_uci.c index e0c43a1..76cffc5 100644 --- a/src/utils/dawn_uci.c +++ b/src/utils/dawn_uci.c @@ -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)) diff --git a/src/utils/memory_utils.c b/src/utils/memory_utils.c index 9a66c1d..03614a6 100644 --- a/src/utils/memory_utils.c +++ b/src/utils/memory_utils.c @@ -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); } diff --git a/src/utils/msghandler.c b/src/utils/msghandler.c index f0bafc0..76212a6 100644 --- a/src/utils/msghandler.c +++ b/src/utils/msghandler.c @@ -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); diff --git a/src/utils/ubus.c b/src/utils/ubus.c index d1e92c4..41ffb68 100644 --- a/src/utils/ubus.c +++ b/src/utils/ubus.c @@ -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; +}