From a297201df15656dbb0f37e90f3410d9e8102c6fd Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Sun, 2 Sep 2012 19:53:15 +0300 Subject: [PATCH] Maintain list of BSS entries in last scan result order This allows last results to be used even after they have been freed since the information is copied to the BSS entries anyway and this new array provides the order in which scan results were processed. Signed-hostap: Jouni Malinen --- wpa_supplicant/bss.c | 66 ++++++++++++++++++++++++++++++++++++--- wpa_supplicant/wpa_supplicant.c | 3 ++ wpa_supplicant/wpa_supplicant_i.h | 10 ++++++ 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c index 580a82a..434fb08 100644 --- a/wpa_supplicant/bss.c +++ b/wpa_supplicant/bss.c @@ -38,6 +38,19 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, const char *reason) { + if (wpa_s->last_scan_res) { + unsigned int i; + for (i = 0; i < wpa_s->last_scan_res_used; i++) { + if (wpa_s->last_scan_res[i] == bss) { + os_memmove(&wpa_s->last_scan_res[i], + &wpa_s->last_scan_res[i + 1], + (wpa_s->last_scan_res_used - i - 1) + * sizeof(struct wpa_bss *)); + wpa_s->last_scan_res_used--; + break; + } + } + } dl_list_del(&bss->list); dl_list_del(&bss->list_id); wpa_s->num_bss--; @@ -169,15 +182,15 @@ static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s) } -static void wpa_bss_add(struct wpa_supplicant *wpa_s, - const u8 *ssid, size_t ssid_len, - struct wpa_scan_res *res) +static struct wpa_bss * wpa_bss_add(struct wpa_supplicant *wpa_s, + const u8 *ssid, size_t ssid_len, + struct wpa_scan_res *res) { struct wpa_bss *bss; bss = os_zalloc(sizeof(*bss) + res->ie_len + res->beacon_ie_len); if (bss == NULL) - return; + return NULL; bss->id = wpa_s->bss_next_id++; bss->last_update_idx = wpa_s->bss_update_idx; wpa_bss_copy_res(bss, res); @@ -201,6 +214,7 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s, "not get here!", (int) wpa_s->num_bss); wpa_s->conf->bss_max_count = wpa_s->num_bss; } + return bss; } @@ -376,6 +390,7 @@ void wpa_bss_update_start(struct wpa_supplicant *wpa_s) wpa_s->bss_update_idx++; wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Start scan result update %u", wpa_s->bss_update_idx); + wpa_s->last_scan_res_used = 0; } @@ -418,9 +433,28 @@ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s, * (to save memory) */ bss = wpa_bss_get(wpa_s, res->bssid, ssid + 2, ssid[1]); if (bss == NULL) - wpa_bss_add(wpa_s, ssid + 2, ssid[1], res); + bss = wpa_bss_add(wpa_s, ssid + 2, ssid[1], res); else wpa_bss_update(wpa_s, bss, res); + + if (bss == NULL) + return; + if (wpa_s->last_scan_res_used >= wpa_s->last_scan_res_size) { + struct wpa_bss **n; + unsigned int siz; + if (wpa_s->last_scan_res_size == 0) + siz = 32; + else + siz = wpa_s->last_scan_res_size * 2; + n = os_realloc_array(wpa_s->last_scan_res, siz, + sizeof(struct wpa_bss *)); + if (n == NULL) + return; + wpa_s->last_scan_res = n; + wpa_s->last_scan_res_size = siz; + } + + wpa_s->last_scan_res[wpa_s->last_scan_res_used++] = bss; } @@ -470,9 +504,26 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, { struct wpa_bss *bss, *n; + wpa_s->last_scan_full = 0; + os_get_time(&wpa_s->last_scan); if (!new_scan) return; /* do not expire entries without new scan */ + if (info && !info->aborted && !info->freqs) { + size_t i; + if (info->num_ssids == 0) { + wpa_s->last_scan_full = 1; + } else { + for (i = 0; i < info->num_ssids; i++) { + if (info->ssids[i].ssid == NULL || + info->ssids[i].ssid_len == 0) { + wpa_s->last_scan_full = 1; + break; + } + } + } + } + dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) { if (wpa_bss_in_use(wpa_s, bss)) continue; @@ -485,6 +536,11 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info, wpa_bss_remove(wpa_s, bss, "no match in scan"); } } + + wpa_printf(MSG_DEBUG, "BSS: last_scan_res_used=%u/%u " + "last_scan_full=%d", + wpa_s->last_scan_res_used, wpa_s->last_scan_res_size, + wpa_s->last_scan_full); } diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 820cd5e..fdd322e 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -476,6 +476,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s) wpa_s->ext_pw = NULL; wpabuf_free(wpa_s->last_gas_resp); + + os_free(wpa_s->last_scan_res); + wpa_s->last_scan_res = NULL; } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index fb8dba8..42055ec 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -347,6 +347,16 @@ struct wpa_supplicant { unsigned int bss_update_idx; unsigned int bss_next_id; + /* + * Pointers to BSS entries in the order they were in the last scan + * results. + */ + struct wpa_bss **last_scan_res; + unsigned int last_scan_res_used; + unsigned int last_scan_res_size; + int last_scan_full; + struct os_time last_scan; + struct wpa_driver_ops *driver; int interface_removed; /* whether the network interface has been * removed */ -- 2.1.4