mirror of
https://github.com/berlin-open-wireless-lab/DAWN.git
synced 2025-02-12 08:41:51 +00:00
scoring: improve scoring algorithm
- Simplify how score is tracked - Streamline some code paths for scoring evaluation to reduce data searches, etc - Allow more entries to be considered for AP NR [cleanup commit message] Signed-off-by: Nick Hainke <vincent@systemli.org>
This commit is contained in:
parent
b7e3d6f34d
commit
8064e56899
5 changed files with 193 additions and 195 deletions
|
@ -352,7 +352,7 @@ struct kicking_nr {
|
||||||
};
|
};
|
||||||
|
|
||||||
// ---------------- Functions -------------------
|
// ---------------- Functions -------------------
|
||||||
int better_ap_available(ap *kicking_ap, struct dawn_mac client_addr, struct kicking_nr** neighbor_report);
|
int better_ap_available(ap *kicking_ap, probe_entry *own_probe, int own_score, struct kicking_nr** neighbor_report);
|
||||||
|
|
||||||
// All users of datastorage should call init_ / destroy_mutex at initialisation and termination respectively
|
// All users of datastorage should call init_ / destroy_mutex at initialisation and termination respectively
|
||||||
int init_mutex();
|
int init_mutex();
|
||||||
|
|
|
@ -131,7 +131,7 @@ int send_set_probe(struct dawn_mac client_addr);
|
||||||
* @param duration
|
* @param duration
|
||||||
* @return - 0 = asynchronous (client has been told to remove itself, and caller should manage arrays); 1 = synchronous (caller should assume arrays are updated)
|
* @return - 0 = asynchronous (client has been told to remove itself, and caller should manage arrays); 1 = synchronous (caller should assume arrays are updated)
|
||||||
*/
|
*/
|
||||||
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct kicking_nr* neighbor_list, uint32_t duration);
|
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct kicking_nr* neighbor_list, int threshold, uint32_t duration);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send control message to all hosts to add the mac to a don't control list.
|
* Send control message to all hosts to add the mac to a don't control list.
|
||||||
|
|
|
@ -267,14 +267,10 @@ static int compare_station_count(ap* ap_entry_own, ap* ap_entry_to_compare, stru
|
||||||
dawnlog_debug("Comparing station is already connected! Decrease counter!\n");
|
dawnlog_debug("Comparing station is already connected! Decrease counter!\n");
|
||||||
sta_count_to_compare--;
|
sta_count_to_compare--;
|
||||||
}
|
}
|
||||||
|
|
||||||
dawnlog_info("Comparing own station count %d to %d\n", sta_count, sta_count_to_compare);
|
dawnlog_info("Comparing own station count %d to %d\n", sta_count, sta_count_to_compare);
|
||||||
|
|
||||||
if (sta_count - sta_count_to_compare > dawn_metric.max_station_diff)
|
return sta_count - sta_count_to_compare;
|
||||||
return 1;
|
|
||||||
else if (sta_count_to_compare - sta_count > dawn_metric.max_station_diff)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_kicking_nr_list(struct kicking_nr *nr_list) {
|
static void remove_kicking_nr_list(struct kicking_nr *nr_list) {
|
||||||
|
@ -359,38 +355,21 @@ static void insert_kicking_nr_by_score(struct kicking_nr** nrlist, ap* nr_ap, i
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
int better_ap_available(ap *kicking_ap, struct dawn_mac client_mac, struct kicking_nr **neighbor_report) {
|
|
||||||
|
int better_ap_available(ap *kicking_ap, probe_entry *own_probe, int own_score, struct kicking_nr **neighbor_report) {
|
||||||
|
|
||||||
dawnlog_debug_func("Entering...");
|
dawnlog_debug_func("Entering...");
|
||||||
dawn_mutex_require(&ap_array_mutex);
|
dawn_mutex_require(&ap_array_mutex);
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
dawn_mutex_require(&probe_array_mutex);
|
||||||
|
|
||||||
// This remains set to the current AP of client for rest of function
|
int tgt_score = own_score + dawn_metric.kicking_threshold;
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
int better_ap_found = 0;
|
||||||
probe_entry* own_probe = probe_array_get_entry(client_mac, kicking_ap->bssid_addr);
|
|
||||||
int own_score = -1;
|
|
||||||
if (own_probe != NULL) {
|
|
||||||
own_score = eval_probe_metric(own_probe, kicking_ap); //TODO: Should the -2 return be handled?
|
|
||||||
dawnlog_trace("Current AP score = %d for:\n", own_score);
|
|
||||||
print_probe_entry(DAWNLOG_TRACE, own_probe);
|
|
||||||
}
|
|
||||||
// no entry for own ap - may happen if DAWN is started after client has connected, and then "sleeps" so sends no BEACON / PROBE
|
|
||||||
else {
|
|
||||||
dawnlog_info("Current AP " MACSTR " for client " MACSTR " not found in probe array!\n", MAC2STR(kicking_ap->bssid_addr.u8), MAC2STR(client_mac.u8));
|
|
||||||
print_probe_array();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int max_score = own_score;
|
|
||||||
dawn_mutex_require(&ap_array_mutex);
|
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
|
||||||
int kick = 0;
|
|
||||||
int ap_count = 0;
|
int ap_count = 0;
|
||||||
// Now go through all probe entries for this client looking for better score
|
// Now go through all probe entries for this client looking for better score
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
dawn_mutex_require(&probe_array_mutex);
|
||||||
probe_entry* i = probe_array_find_first_entry(client_mac, dawn_mac_null, false);
|
probe_entry* i = probe_array_find_first_entry(own_probe->client_addr, dawn_mac_null, false);
|
||||||
|
|
||||||
while (i != NULL && mac_is_equal_bb(i->client_addr, client_mac)) {
|
while (i != NULL && mac_is_equal_bb(i->client_addr, own_probe->client_addr)) {
|
||||||
if (i == own_probe) {
|
if (i == own_probe) {
|
||||||
dawnlog_trace("Own Score! Skipping!\n");
|
dawnlog_trace("Own Score! Skipping!\n");
|
||||||
i = i->next_probe;
|
i = i->next_probe;
|
||||||
|
@ -422,24 +401,24 @@ int better_ap_available(ap *kicking_ap, struct dawn_mac client_mac, struct kicki
|
||||||
int ap_outcome = 0; // No kicking
|
int ap_outcome = 0; // No kicking
|
||||||
|
|
||||||
// Find better score...
|
// Find better score...
|
||||||
// FIXME: Do we mean to use 'kick' like this here? It is set when we find an AP with bigger score
|
if (score_to_compare > tgt_score) {
|
||||||
// then any more have to also be 'kicking_threshold' bigger
|
|
||||||
if (score_to_compare > max_score + (kick ? 0 : dawn_metric.kicking_threshold)) {
|
|
||||||
ap_outcome = 2; // Add and prune
|
ap_outcome = 2; // Add and prune
|
||||||
max_score = score_to_compare;
|
// TODO: Should we adjust this, or just stick with original "better than current AP" target?
|
||||||
|
tgt_score = score_to_compare;
|
||||||
}
|
}
|
||||||
// if AP have same value but station count might improve it...
|
// Give a few marks for candidate AP having fewer clients than current
|
||||||
// TODO: Is absolute number meaningful when AP have diffeent capacity?
|
// TODO: Is absolute number meaningful when AP have diffeent capacity?
|
||||||
else if (score_to_compare == max_score && dawn_metric.use_station_count > 0 ) {
|
// TODO: This test doesn't really make sense if we have adjusted target score to best found so far
|
||||||
int compare = compare_station_count(kicking_ap, candidate_ap, client_mac);
|
else if (score_to_compare == tgt_score && dawn_metric.use_station_count > 0 ) {
|
||||||
if (compare > 0) {
|
int compare = compare_station_count(kicking_ap, candidate_ap, own_probe->client_addr);
|
||||||
|
if (compare > dawn_metric.max_station_diff) {
|
||||||
ap_outcome = 2; // Add and prune
|
ap_outcome = 2; // Add and prune
|
||||||
}
|
}
|
||||||
else if (compare == 0 && kick) {
|
else if (compare == 0) {
|
||||||
ap_outcome = 1; // Add but no prune
|
ap_outcome = 1; // Add but no prune
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (score_to_compare >= max_score && kick) {
|
else if (score_to_compare == tgt_score) {
|
||||||
ap_outcome = 1; // Add but no prune
|
ap_outcome = 1; // Add but no prune
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,10 +428,22 @@ int better_ap_available(ap *kicking_ap, struct dawn_mac client_mac, struct kicki
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dawnlog_trace("Better AP after full evaluation - add to NR (%s pruning)\n", ap_outcome == 2 ? "with" : "without");
|
dawnlog_trace("Better AP after full evaluation\n");
|
||||||
// NR is NULL if we're only testing for a better AP without actually using it
|
better_ap_found = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NR is NULL if we're only testing for a better AP without actually using it
|
||||||
|
if (better_ap_found && neighbor_report == NULL)
|
||||||
|
{
|
||||||
|
// Short circuit loop if we're only finding a better AP without actually using it
|
||||||
|
i = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Always add the NR as we use it to adjust the "own AP" semi-static NR as well
|
||||||
if (neighbor_report != NULL)
|
if (neighbor_report != NULL)
|
||||||
{
|
{
|
||||||
|
dawnlog_trace("Add to NR (%s pruning)\n", ap_outcome == 2 ? "with" : "without");
|
||||||
// FIXME: Do we need to prune this list as we build it? trying new approach to send N best entries to hostapd
|
// FIXME: Do we need to prune this list as we build it? trying new approach to send N best entries to hostapd
|
||||||
// if (ap_outcome == 2)
|
// if (ap_outcome == 2)
|
||||||
// prune_kicking_nr_list(neighbor_report, score_to_compare - dawn_metric.kicking_threshold);
|
// prune_kicking_nr_list(neighbor_report, score_to_compare - dawn_metric.kicking_threshold);
|
||||||
|
@ -460,25 +451,14 @@ int better_ap_available(ap *kicking_ap, struct dawn_mac client_mac, struct kicki
|
||||||
insert_kicking_nr_by_score(neighbor_report, candidate_ap, score_to_compare);
|
insert_kicking_nr_by_score(neighbor_report, candidate_ap, score_to_compare);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we find a single candidate then we will be kicking
|
|
||||||
kick = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Short circuit loop if we're only finding a better AP without actually using it
|
|
||||||
if (kick && neighbor_report == NULL)
|
|
||||||
{
|
|
||||||
i = NULL;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = i->next_probe;
|
i = i->next_probe;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neighbor_report != NULL)
|
if (neighbor_report != NULL)
|
||||||
dawnlog_info("Client " MACSTR ": Compared %d alternate AP candidates\n", MAC2STR(client_mac.u8), ap_count);
|
dawnlog_info("Client " MACSTR ": Compared %d alternate AP candidates\n", MAC2STR(own_probe->client_addr.u8), ap_count);
|
||||||
|
|
||||||
return kick;
|
return better_ap_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kick_clients(struct dawn_mac bssid_mac, uint32_t id) {
|
int kick_clients(struct dawn_mac bssid_mac, uint32_t id) {
|
||||||
|
@ -506,12 +486,26 @@ int kick_clients(struct dawn_mac bssid_mac, uint32_t id) {
|
||||||
struct kicking_nr *kick_nr_list = NULL;
|
struct kicking_nr *kick_nr_list = NULL;
|
||||||
|
|
||||||
int do_kick = 0;
|
int do_kick = 0;
|
||||||
|
int own_score = 0;
|
||||||
|
|
||||||
if (mac_find_entry(j->client_addr)) {
|
if (mac_find_entry(j->client_addr)) {
|
||||||
dawnlog_info("Client " MACSTR ": Suppressing check due to MAC list entry\n", MAC2STR(j->client_addr.u8));
|
dawnlog_info("Client " MACSTR ": Suppressing check due to MAC list entry\n", MAC2STR(j->client_addr.u8));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
do_kick = better_ap_available(kicking_ap, j->client_addr, &kick_nr_list);
|
dawn_mutex_require(&probe_array_mutex);
|
||||||
|
probe_entry* own_probe = probe_array_get_entry(j->client_addr, kicking_ap->bssid_addr);
|
||||||
|
if (own_probe == NULL) {
|
||||||
|
// no entry for own ap - may happen if DAWN is started after client has connected, and then "sleeps" so sends no BEACON / PROBE
|
||||||
|
dawnlog_info("Current AP " MACSTR " for client " MACSTR " not found in probe array!\n", MAC2STR(kicking_ap->bssid_addr.u8), MAC2STR(j->client_addr.u8));
|
||||||
|
print_probe_array();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
own_score = eval_probe_metric(own_probe, kicking_ap);
|
||||||
|
dawnlog_trace("Current AP score = %d for:\n", own_score);
|
||||||
|
print_probe_entry(DAWNLOG_TRACE, own_probe);
|
||||||
|
|
||||||
|
do_kick = better_ap_available(kicking_ap, own_probe, own_score, &kick_nr_list);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we found any candidates (even if too low to kick to) add the highest scoring one to local AP NR set
|
// If we found any candidates (even if too low to kick to) add the highest scoring one to local AP NR set
|
||||||
|
@ -570,7 +564,7 @@ int kick_clients(struct dawn_mac bssid_mac, uint32_t id) {
|
||||||
// don't deauth station? <- deauth is better!
|
// don't deauth station? <- deauth is better!
|
||||||
// maybe we can use handovers...
|
// maybe we can use handovers...
|
||||||
//del_client_interface(id, client_array[j].client_addr, NO_MORE_STAS, 1, 1000);
|
//del_client_interface(id, client_array[j].client_addr, NO_MORE_STAS, 1, 1000);
|
||||||
int sync_kick = wnm_disassoc_imminent(id, j->client_addr, kick_nr_list, 12);
|
int sync_kick = wnm_disassoc_imminent(id, j->client_addr, kick_nr_list, own_score + dawn_metric.kicking_threshold, 12);
|
||||||
|
|
||||||
// Synchronous kick is a test harness feature to indicate arrays have been updated, so don't change further
|
// Synchronous kick is a test harness feature to indicate arrays have been updated, so don't change further
|
||||||
if (sync_kick)
|
if (sync_kick)
|
||||||
|
|
|
@ -34,7 +34,7 @@ int send_set_probe(struct dawn_mac client_addr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct kicking_nr* neighbor_list, uint32_t duration)
|
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct kicking_nr* neighbor_list, int threshold, uint32_t duration)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -892,7 +892,7 @@ static int consume_actions(int argc, char* argv[], int harness_verbosity)
|
||||||
|
|
||||||
struct kicking_nr *neighbor_list = NULL;
|
struct kicking_nr *neighbor_list = NULL;
|
||||||
|
|
||||||
tr = better_ap_available(ap_array_get_ap(bssid_mac), client_mac, with_nr ? &neighbor_list : NULL);
|
tr = better_ap_available(ap_array_get_ap(bssid_mac), probe_array_get_entry(client_mac, bssid_mac), 100, with_nr ? &neighbor_list : NULL);
|
||||||
|
|
||||||
printf("better_ap_available returned %d (with neighbour report %s)\n", tr, neighbor_list ? neighbor_list->nr_ap->neighbor_report : "NONE");
|
printf("better_ap_available returned %d (with neighbour report %s)\n", tr, neighbor_list ? neighbor_list->nr_ap->neighbor_report : "NONE");
|
||||||
}
|
}
|
||||||
|
|
274
src/utils/ubus.c
274
src/utils/ubus.c
|
@ -328,78 +328,79 @@ static probe_entry* parse_to_beacon_rep(struct blob_attr *msg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int handle_auth_req(struct blob_attr* msg) {
|
int handle_auth_req(struct blob_attr* msg) {
|
||||||
int ret = WLAN_STATUS_SUCCESS;
|
|
||||||
bool discard_entry = true;
|
|
||||||
|
|
||||||
dawnlog_debug_func("Entering...");
|
dawnlog_debug_func("Entering...");
|
||||||
|
|
||||||
|
// Allow if we can't evalute an active reason to deny
|
||||||
|
int ret = WLAN_STATUS_SUCCESS;
|
||||||
|
|
||||||
client_req_entry *auth_req = dawn_malloc(sizeof(struct client_req_entry_s));
|
client_req_entry *auth_req = dawn_malloc(sizeof(struct client_req_entry_s));
|
||||||
if (auth_req == NULL)
|
if (auth_req == NULL)
|
||||||
{
|
{
|
||||||
dawnlog_error("Memory allocation of auth req failed!");
|
dawnlog_error("Memory allocation of auth req failed!");
|
||||||
return ret; // Allow if we can't evalute a reason to deny
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parse_to_client_req(msg, auth_req);
|
||||||
|
|
||||||
parse_to_client_req(msg, auth_req);
|
dawnlog_debug("Auth entry: ");
|
||||||
|
print_client_req_entry(DAWNLOG_DEBUG, auth_req);
|
||||||
|
|
||||||
dawnlog_debug("Auth entry: ");
|
if (dawn_metric.eval_auth_req <= 0) {
|
||||||
print_client_req_entry(DAWNLOG_DEBUG, auth_req);
|
dawnlog_trace(MACSTR " Allow authentication due to not evaluating requests", MAC2STR(auth_req->client_addr.u8));
|
||||||
|
}
|
||||||
|
else if (mac_find_entry(auth_req->client_addr)) {
|
||||||
|
dawnlog_trace(MACSTR " Allow authentication due to whitelisted MAC", MAC2STR(auth_req->client_addr.u8));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dawn_mutex_lock(&probe_array_mutex);
|
||||||
|
|
||||||
if (dawn_metric.eval_auth_req <= 0) {
|
if (dawnlog_showing(DAWNLOG_DEBUG))
|
||||||
dawnlog_trace(MACSTR " Allow authentication due to not evaluating requests", MAC2STR(auth_req->client_addr.u8));
|
print_probe_array();
|
||||||
}
|
|
||||||
else if (mac_find_entry(auth_req->client_addr)) {
|
|
||||||
dawnlog_trace(MACSTR " Allow authentication due to mac_find_entry()", MAC2STR(auth_req->client_addr.u8));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dawn_mutex_lock(&probe_array_mutex);
|
|
||||||
|
|
||||||
if (dawnlog_showing(DAWNLOG_DEBUG))
|
|
||||||
print_probe_array();
|
|
||||||
|
|
||||||
probe_entry *tmp = probe_array_get_entry(auth_req->client_addr, auth_req->bssid_addr);
|
|
||||||
|
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
dawn_mutex_require(&probe_array_mutex);
|
||||||
|
probe_entry* own_probe = probe_array_get_entry(auth_req->client_addr, auth_req->bssid_addr);
|
||||||
|
|
||||||
/*** Deprecated function decide_function() removed here ***/
|
// block if entry was not already found in probe database
|
||||||
int deny_request = 0;
|
if (own_probe == NULL) {
|
||||||
|
dawnlog_trace(MACSTR " Deny authentication due to no probe entry", MAC2STR(auth_req->client_addr.u8));
|
||||||
// block if entry was not already found in probe database
|
ret = dawn_metric.deny_auth_reason;
|
||||||
if (tmp == NULL) {
|
}
|
||||||
dawnlog_trace(MACSTR " Deny authentication due to no probe entry", MAC2STR(auth_req->client_addr.u8));
|
else if (own_probe->counter < dawn_metric.min_probe_count) {
|
||||||
deny_request = 1;
|
dawnlog_trace(MACSTR " Deny authentication due to low probe count", MAC2STR(auth_req->client_addr.u8));
|
||||||
}
|
ret = dawn_metric.deny_auth_reason;
|
||||||
else if (tmp->counter < dawn_metric.min_probe_count) {
|
|
||||||
dawnlog_trace(MACSTR " Deny authentication due to low probe count", MAC2STR(auth_req->client_addr.u8));
|
|
||||||
deny_request = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dawn_mutex_lock(&ap_array_mutex);
|
|
||||||
|
|
||||||
dawn_mutex_require(&ap_array_mutex);
|
|
||||||
ap* this_ap = ap_array_get_ap(tmp->bssid_addr);
|
|
||||||
if (this_ap != NULL && better_ap_available(this_ap, tmp->client_addr, NULL) > 0) {
|
|
||||||
dawnlog_trace(MACSTR " Deny authentication due to better AP available", MAC2STR(auth_req->client_addr.u8));
|
|
||||||
deny_request = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
// maybe send here that the client is connected?
|
{
|
||||||
dawnlog_trace(MACSTR " Allow authentication!\n", MAC2STR(auth_req->client_addr.u8));
|
dawn_mutex_lock(&ap_array_mutex);
|
||||||
|
|
||||||
dawn_mutex_unlock(&ap_array_mutex);
|
dawn_mutex_require(&ap_array_mutex);
|
||||||
}
|
ap* this_ap = ap_array_get_ap(auth_req->bssid_addr);
|
||||||
/*** End of decide_function() rework ***/
|
if (this_ap == NULL)
|
||||||
|
{
|
||||||
|
dawnlog_trace(MACSTR " Allow authentication due to no AP entry", MAC2STR(auth_req->client_addr.u8));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int own_score = eval_probe_metric(own_probe, this_ap);
|
||||||
|
dawnlog_trace("Current AP score = %d for:\n", own_score);
|
||||||
|
print_probe_entry(DAWNLOG_TRACE, own_probe);
|
||||||
|
|
||||||
if (deny_request) {
|
if (better_ap_available(this_ap, own_probe, own_score, NULL) > 0) {
|
||||||
ret = dawn_metric.deny_auth_reason;
|
dawnlog_trace(MACSTR " Deny authentication due to better AP available", MAC2STR(auth_req->client_addr.u8));
|
||||||
|
ret = dawn_metric.deny_auth_reason;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// maybe send here that the client is connected?
|
||||||
|
dawnlog_trace(MACSTR " Allow authentication request due to AP score\n", MAC2STR(auth_req->client_addr.u8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn_mutex_unlock(&ap_array_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn_mutex_unlock(&probe_array_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
dawn_mutex_unlock(&probe_array_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discard_entry)
|
|
||||||
{
|
|
||||||
dawn_free(auth_req);
|
dawn_free(auth_req);
|
||||||
auth_req = NULL;
|
auth_req = NULL;
|
||||||
}
|
}
|
||||||
|
@ -408,79 +409,77 @@ bool discard_entry = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_assoc_req(struct blob_attr *msg) {
|
static int handle_assoc_req(struct blob_attr *msg) {
|
||||||
int ret = WLAN_STATUS_SUCCESS;
|
|
||||||
int discard_entry = true;
|
|
||||||
|
|
||||||
dawnlog_debug_func("Entering...");
|
dawnlog_debug_func("Entering...");
|
||||||
|
|
||||||
|
// Allow if we can't evalute an active reason to deny
|
||||||
|
int ret = WLAN_STATUS_SUCCESS;
|
||||||
|
|
||||||
client_req_entry* assoc_req = dawn_malloc(sizeof(struct client_req_entry_s));
|
client_req_entry* assoc_req = dawn_malloc(sizeof(struct client_req_entry_s));
|
||||||
if (assoc_req == NULL)
|
if (assoc_req == NULL)
|
||||||
{
|
{
|
||||||
dawnlog_error("Memory allocation of assoc req failed!");
|
dawnlog_error("Memory allocation of assoc req failed!");
|
||||||
return ret; // Allow if we can't evalute a reason to deny
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
parse_to_client_req(msg, assoc_req);
|
||||||
|
dawnlog_debug("Association entry: ");
|
||||||
|
print_client_req_entry(DAWNLOG_DEBUG, assoc_req);
|
||||||
|
|
||||||
parse_to_client_req(msg, assoc_req);
|
if (dawn_metric.eval_assoc_req <= 0) {
|
||||||
dawnlog_debug("Association entry: ");
|
dawnlog_trace(MACSTR " Allow association due to not evaluating requests", MAC2STR(assoc_req->client_addr.u8));
|
||||||
print_client_req_entry(DAWNLOG_DEBUG, assoc_req);
|
}
|
||||||
|
else if (mac_find_entry(assoc_req->client_addr)) {
|
||||||
|
dawnlog_trace(MACSTR " Allow association due to whitelisted MAC", MAC2STR(assoc_req->client_addr.u8));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dawn_mutex_lock(&probe_array_mutex);
|
||||||
|
|
||||||
if (dawn_metric.eval_assoc_req <= 0) {
|
if (dawnlog_showing(DAWNLOG_DEBUG))
|
||||||
dawnlog_trace(MACSTR " Allow association due to not evaluating requests", MAC2STR(assoc_req->client_addr.u8));
|
print_probe_array();
|
||||||
}
|
|
||||||
else if (mac_find_entry(assoc_req->client_addr)) {
|
|
||||||
dawnlog_trace(MACSTR " Allow association due to mac_find_entry()", MAC2STR(assoc_req->client_addr.u8));
|
|
||||||
} else {
|
|
||||||
dawn_mutex_lock(&probe_array_mutex);
|
|
||||||
|
|
||||||
if (dawnlog_showing(DAWNLOG_DEBUG))
|
|
||||||
print_probe_array();
|
|
||||||
|
|
||||||
probe_entry *tmp = probe_array_get_entry(assoc_req->client_addr, assoc_req->bssid_addr);
|
|
||||||
|
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
dawn_mutex_require(&probe_array_mutex);
|
||||||
|
probe_entry* own_probe = probe_array_get_entry(assoc_req->client_addr, assoc_req->bssid_addr);
|
||||||
|
|
||||||
/*** Deprecated function decide_function() removed here ***/
|
// block if entry was not already found in probe database
|
||||||
int deny_request = 0;
|
if (own_probe == NULL) {
|
||||||
|
dawnlog_trace(MACSTR " Deny association due to no probe entry found", MAC2STR(assoc_req->client_addr.u8));
|
||||||
// block if entry was not already found in probe database
|
}
|
||||||
if (tmp == NULL) {
|
else if (own_probe->counter < dawn_metric.min_probe_count) {
|
||||||
dawnlog_trace(MACSTR " Deny association due to no probe entry found", MAC2STR(assoc_req->client_addr.u8));
|
dawnlog_trace(MACSTR " Deny association due to low probe count", MAC2STR(assoc_req->client_addr.u8));
|
||||||
deny_request = 1;
|
ret = dawn_metric.deny_auth_reason;
|
||||||
}
|
}
|
||||||
else if (tmp->counter < dawn_metric.min_probe_count) {
|
else
|
||||||
dawnlog_trace(MACSTR " Deny association due to low probe count", MAC2STR(assoc_req->client_addr.u8));
|
{
|
||||||
deny_request = 1;
|
// find own probe entry and calculate score
|
||||||
}
|
dawn_mutex_lock(&ap_array_mutex);
|
||||||
else
|
|
||||||
{
|
|
||||||
// find own probe entry and calculate score
|
|
||||||
dawn_mutex_lock(&ap_array_mutex);
|
|
||||||
|
|
||||||
dawn_mutex_require(&ap_array_mutex);
|
dawn_mutex_require(&ap_array_mutex);
|
||||||
ap* this_ap = ap_array_get_ap(assoc_req->bssid_addr);
|
ap* this_ap = ap_array_get_ap(assoc_req->bssid_addr);
|
||||||
if (this_ap != NULL && better_ap_available(this_ap, assoc_req->client_addr, NULL) > 0) {
|
if (this_ap == NULL)
|
||||||
dawnlog_trace(MACSTR " Deny association due to better AP available", MAC2STR(assoc_req->client_addr.u8));
|
{
|
||||||
deny_request = 1;
|
dawnlog_trace(MACSTR " Allow association due to no AP entry", MAC2STR(assoc_req->client_addr.u8));
|
||||||
}
|
}
|
||||||
else { // TODO: Should we reset probe counter to zero here? Does active client do probe and if so what would a deny lead to?
|
else
|
||||||
dawnlog_trace(MACSTR " Allow association!\n", MAC2STR(assoc_req->client_addr.u8));
|
{
|
||||||
}
|
int own_score = eval_probe_metric(own_probe, this_ap);
|
||||||
dawn_mutex_unlock(&ap_array_mutex);
|
dawnlog_trace("Current AP score = %d for:\n", own_score);
|
||||||
}
|
print_probe_entry(DAWNLOG_TRACE, own_probe);
|
||||||
/*** End of decide_function() rework ***/
|
|
||||||
|
|
||||||
if (deny_request) {
|
if (better_ap_available(this_ap, own_probe, own_score, NULL) > 0) {
|
||||||
if (tmp != NULL)
|
dawnlog_trace(MACSTR " Deny association due to better AP available", MAC2STR(assoc_req->client_addr.u8));
|
||||||
print_probe_entry(DAWNLOG_DEBUG, tmp);
|
ret = dawn_metric.deny_assoc_reason;
|
||||||
|
}
|
||||||
|
else { // TODO: Should we reset probe counter to zero here? Does active client do probe and if so what would a deny lead to?
|
||||||
|
dawnlog_trace(MACSTR " Allow association request due to AP score\n", MAC2STR(assoc_req->client_addr.u8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret = dawn_metric.deny_assoc_reason;
|
dawn_mutex_unlock(&ap_array_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
dawn_mutex_unlock(&probe_array_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
dawn_mutex_unlock(&probe_array_mutex);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (discard_entry)
|
|
||||||
{
|
|
||||||
dawn_free(assoc_req);
|
dawn_free(assoc_req);
|
||||||
assoc_req = NULL;
|
assoc_req = NULL;
|
||||||
}
|
}
|
||||||
|
@ -491,29 +490,30 @@ int discard_entry = true;
|
||||||
static int handle_probe_req(struct blob_attr* msg) {
|
static int handle_probe_req(struct blob_attr* msg) {
|
||||||
dawnlog_debug_func("Entering...");
|
dawnlog_debug_func("Entering...");
|
||||||
|
|
||||||
// MUSTDO: Untangle dawn_malloc() and linking of probe_entry
|
// Allow if we can't evalute an active reason to deny
|
||||||
probe_entry* probe_req = parse_to_probe_req(msg);
|
int ret = WLAN_STATUS_SUCCESS;
|
||||||
|
|
||||||
if (probe_req == NULL)
|
probe_entry* probe_req_new = parse_to_probe_req(msg);
|
||||||
|
|
||||||
|
if (probe_req_new == NULL)
|
||||||
{
|
{
|
||||||
dawnlog_error("Parse of probe req failed!");
|
dawnlog_error("Parse of probe req failed!");
|
||||||
return WLAN_STATUS_SUCCESS; // Allow if we can't evalute a reason to deny
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dawn_mutex_lock(&probe_array_mutex);
|
dawn_mutex_lock(&probe_array_mutex);
|
||||||
|
|
||||||
dawn_mutex_require(&probe_array_mutex);
|
dawn_mutex_require(&probe_array_mutex);
|
||||||
probe_entry* probe_req_updated = insert_to_probe_array(probe_req, true, true, false, time(0));
|
probe_entry* probe_req_updated = insert_to_probe_array(probe_req_new, true, true, false, time(0));
|
||||||
// If insert finds an existing entry, rather than linking in our new one,
|
// If insert finds an existing entry, rather than linking in our new one,
|
||||||
// send new probe req because we want to stay synced.
|
// send new probe req because we want to stay synced.
|
||||||
// If not, probe_req and probe_req_updated should be equivalent
|
// If not, probe_req and probe_req_updated should be equivalent
|
||||||
if (probe_req != probe_req_updated)
|
if (probe_req_new != probe_req_updated)
|
||||||
{
|
{
|
||||||
dawnlog_info("Local PROBE used to update client / BSSID = " MACSTR " / " MACSTR " \n", MAC2STR(probe_req_updated->client_addr.u8), MAC2STR(probe_req_updated->bssid_addr.u8));
|
dawnlog_info("Local PROBE used to update client / BSSID = " MACSTR " / " MACSTR " \n", MAC2STR(probe_req_updated->client_addr.u8), MAC2STR(probe_req_updated->bssid_addr.u8));
|
||||||
|
|
||||||
dawn_free(probe_req);
|
dawn_free(probe_req_new);
|
||||||
probe_req = NULL;
|
probe_req_new = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -522,46 +522,50 @@ static int handle_probe_req(struct blob_attr* msg) {
|
||||||
|
|
||||||
ubus_send_probe_via_network(probe_req_updated);
|
ubus_send_probe_via_network(probe_req_updated);
|
||||||
|
|
||||||
/*** Deprecated function decide_function() removed here ***/
|
|
||||||
int deny_request = 0;
|
|
||||||
|
|
||||||
if (dawn_metric.eval_probe_req <= 0) {
|
if (dawn_metric.eval_probe_req <= 0) {
|
||||||
dawnlog_trace(MACSTR " Allow probe due to not evaluating requests", MAC2STR(probe_req_updated->client_addr.u8));
|
dawnlog_trace(MACSTR " Allow probe due to not evaluating requests", MAC2STR(probe_req_updated->client_addr.u8));
|
||||||
}
|
}
|
||||||
else if (mac_find_entry(probe_req_updated->client_addr)) {
|
else if (mac_find_entry(probe_req_updated->client_addr)) {
|
||||||
dawnlog_trace(MACSTR " Allow probe due to mac_find_entry()", MAC2STR(probe_req_updated->client_addr.u8));
|
dawnlog_trace(MACSTR " Allow probe due to whitelisted MAC", MAC2STR(probe_req_updated->client_addr.u8));
|
||||||
}
|
}
|
||||||
else if (probe_req_updated->counter < dawn_metric.min_probe_count) {
|
else if (probe_req_updated->counter < dawn_metric.min_probe_count) {
|
||||||
dawnlog_trace(MACSTR " Deny probe due to low probe count", MAC2STR(probe_req_updated->client_addr.u8));
|
dawnlog_trace(MACSTR " Deny probe due to low probe count", MAC2STR(probe_req_updated->client_addr.u8));
|
||||||
deny_request = 1;
|
ret = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// find own probe entry and calculate score
|
// Evaluate whether to allow probe to succeed
|
||||||
dawn_mutex_lock(&ap_array_mutex);
|
dawn_mutex_lock(&ap_array_mutex);
|
||||||
|
|
||||||
dawn_mutex_require(&ap_array_mutex);
|
dawn_mutex_require(&ap_array_mutex);
|
||||||
ap* this_ap = ap_array_get_ap(probe_req_updated->bssid_addr);
|
ap* this_ap = ap_array_get_ap(probe_req_updated->bssid_addr);
|
||||||
if (this_ap != NULL && better_ap_available(this_ap, probe_req_updated->client_addr, NULL) > 0) {
|
if (this_ap == NULL)
|
||||||
dawnlog_trace(MACSTR " Deny probe due to better AP available", MAC2STR(probe_req_updated->client_addr.u8));
|
{
|
||||||
deny_request = 1;
|
dawnlog_trace(MACSTR " Allow probe due to no AP entry", MAC2STR(probe_req_updated->client_addr.u8));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dawnlog_trace(MACSTR " Allow probe request!", MAC2STR(probe_req_updated->client_addr.u8));
|
int own_score = eval_probe_metric(probe_req_updated, this_ap); //TODO: Should the -2 return be handled?
|
||||||
|
dawnlog_trace("Current AP score = %d for:\n", own_score);
|
||||||
|
print_probe_entry(DAWNLOG_TRACE, probe_req_updated);
|
||||||
|
|
||||||
|
if (better_ap_available(this_ap, probe_req_updated, own_score, NULL) > 0) {
|
||||||
|
dawnlog_trace(MACSTR " Deny probe due to better AP available", MAC2STR(probe_req_updated->client_addr.u8));
|
||||||
|
ret = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dawnlog_trace(MACSTR " Allow probe request due to AP score", MAC2STR(probe_req_updated->client_addr.u8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dawn_mutex_unlock(&ap_array_mutex);
|
dawn_mutex_unlock(&ap_array_mutex);
|
||||||
}
|
}
|
||||||
/*** End of decide_function() rework ***/
|
|
||||||
if (deny_request) {
|
|
||||||
return WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA; // no reason needed...
|
|
||||||
}
|
|
||||||
dawn_mutex_unlock(&probe_array_mutex);
|
dawn_mutex_unlock(&probe_array_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Return for dawn_malloc() failure?
|
return ret;
|
||||||
return WLAN_STATUS_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_beacon_rep(struct blob_attr *msg) {
|
static int handle_beacon_rep(struct blob_attr *msg) {
|
||||||
|
@ -1146,7 +1150,7 @@ void del_client_interface(uint32_t id, const struct dawn_mac client_addr, uint32
|
||||||
dawn_unregmem(&b);
|
dawn_unregmem(&b);
|
||||||
}
|
}
|
||||||
|
|
||||||
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct kicking_nr* neighbor_list, uint32_t duration) {
|
int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct kicking_nr* neighbor_list, int threshold, uint32_t duration) {
|
||||||
struct hostapd_sock_entry *sub;
|
struct hostapd_sock_entry *sub;
|
||||||
struct blob_buf b = {0};
|
struct blob_buf b = {0};
|
||||||
|
|
||||||
|
@ -1162,9 +1166,9 @@ int wnm_disassoc_imminent(uint32_t id, const struct dawn_mac client_addr, struct
|
||||||
|
|
||||||
void* nbs = blobmsg_open_array(&b, "neighbors");
|
void* nbs = blobmsg_open_array(&b, "neighbors");
|
||||||
|
|
||||||
// Add the first N AP, where list order id high->low score
|
// Add the first N AP that reach threshold, where list order id high->low score
|
||||||
int neighbors_added = 0;
|
int neighbors_added = 0;
|
||||||
while(neighbors_added < dawn_metric.disassoc_nr_length && neighbor_list != NULL) {
|
while(neighbors_added < dawn_metric.disassoc_nr_length && neighbor_list != NULL && neighbor_list->score >= threshold) {
|
||||||
dawnlog_info("BSS TRANSITION NEIGHBOR " NR_MACSTR ", Score=%d\n", NR_MAC2STR(neighbor_list->nr_ap->neighbor_report), neighbor_list->score);
|
dawnlog_info("BSS TRANSITION NEIGHBOR " NR_MACSTR ", Score=%d\n", NR_MAC2STR(neighbor_list->nr_ap->neighbor_report), neighbor_list->score);
|
||||||
blobmsg_add_string(&b, NULL, neighbor_list->nr_ap->neighbor_report);
|
blobmsg_add_string(&b, NULL, neighbor_list->nr_ap->neighbor_report);
|
||||||
neighbor_list = neighbor_list->next;
|
neighbor_list = neighbor_list->next;
|
||||||
|
|
Loading…
Reference in a new issue