From 018a309a944adc71a8008558741dbbf04eb1a0ca Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sat, 16 Jul 2011 13:22:58 +0300 Subject: [PATCH] Drop oldest unknown BSS table entries first When the BSS table size limit has been reached, drop first the oldest BSS entries for which there is not a matching network in the configuration based on SSID (wildcards are ignored). This makes it less likely to hit connection issues in environments with huge number of visible APs. --- wpa_supplicant/bss.c | 56 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 5b48951f0..21d63221b 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -93,6 +93,55 @@ static void wpa_bss_copy_res(struct wpa_bss *dst, struct wpa_scan_res *src) } +static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss) +{ + struct wpa_ssid *ssid; + + for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next) { + if (ssid->ssid == NULL || ssid->ssid_len == 0) + continue; + if (ssid->ssid_len == bss->ssid_len && + os_memcmp(ssid->ssid, bss->ssid, ssid->ssid_len) == 0) + return 1; + } + + return 0; +} + + +static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s) +{ + struct wpa_bss *bss; + + dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) { + if (!wpa_bss_known(wpa_s, bss)) { + wpa_bss_remove(wpa_s, bss); + return 0; + } + } + + return -1; +} + + +static void wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s) +{ + /* + * Remove the oldest entry that does not match with any configured + * network. + */ + if (wpa_bss_remove_oldest_unknown(wpa_s) == 0) + return; + + /* + * Remove the oldest entry since no better candidate for removal was + * found. + */ + wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss, + struct wpa_bss, list)); +} + + static void wpa_bss_add(struct wpa_supplicant *wpa_s, const u8 *ssid, size_t ssid_len, struct wpa_scan_res *res) @@ -118,11 +167,8 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s, " SSID '%s'", bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len)); wpas_notify_bss_added(wpa_s, bss->bssid, bss->id); - if (wpa_s->num_bss > wpa_s->conf->bss_max_count) { - /* Remove the oldest entry */ - wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss, - struct wpa_bss, list)); - } + if (wpa_s->num_bss > wpa_s->conf->bss_max_count) + wpa_bss_remove_oldest(wpa_s); }