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 <j@w1.fi>
This commit is contained in:
parent
20ed5e40ba
commit
a297201df1
3 changed files with 74 additions and 5 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue