Do not start wpa_radio work during externally triggered scan
If an external program triggers a scan, wpa_supplicant does not have a wpa_radio work item for this operation to protect against other offchannel operations. This can result in operations failing, so try to avoid damage by not starting any new wpa_radio work items during a scan that was started by another process. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
7c0d8645a1
commit
6428d0a71f
4 changed files with 11 additions and 12 deletions
|
@ -2863,6 +2863,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
||||||
wpa_supplicant_event_scan_results(wpa_s, data);
|
wpa_supplicant_event_scan_results(wpa_s, data);
|
||||||
wpa_s->own_scan_running = 0;
|
wpa_s->own_scan_running = 0;
|
||||||
wpa_s->external_scan_running = 0;
|
wpa_s->external_scan_running = 0;
|
||||||
|
radio_work_check_next(wpa_s);
|
||||||
break;
|
break;
|
||||||
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
#endif /* CONFIG_NO_SCAN_PROCESSING */
|
||||||
case EVENT_ASSOCINFO:
|
case EVENT_ASSOCINFO:
|
||||||
|
|
|
@ -542,17 +542,6 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wpa_s->external_scan_running) {
|
|
||||||
struct os_reltime now, diff;
|
|
||||||
os_get_reltime(&now);
|
|
||||||
os_reltime_sub(&now, &wpa_s->scan_start_time, &diff);
|
|
||||||
if (diff.sec < 30) {
|
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "Externally triggered scan running - Reschedule the incoming scan req");
|
|
||||||
wpa_supplicant_req_scan(wpa_s, 1, 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!wpa_supplicant_enabled_networks(wpa_s) &&
|
if (!wpa_supplicant_enabled_networks(wpa_s) &&
|
||||||
wpa_s->scan_req == NORMAL_SCAN_REQ) {
|
wpa_s->scan_req == NORMAL_SCAN_REQ) {
|
||||||
wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
|
wpa_dbg(wpa_s, MSG_DEBUG, "No enabled networks - do not scan");
|
||||||
|
|
|
@ -3034,6 +3034,7 @@ static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
|
||||||
struct wpa_radio *radio = eloop_ctx;
|
struct wpa_radio *radio = eloop_ctx;
|
||||||
struct wpa_radio_work *work;
|
struct wpa_radio_work *work;
|
||||||
struct os_reltime now, diff;
|
struct os_reltime now, diff;
|
||||||
|
struct wpa_supplicant *wpa_s;
|
||||||
|
|
||||||
work = dl_list_first(&radio->work, struct wpa_radio_work, list);
|
work = dl_list_first(&radio->work, struct wpa_radio_work, list);
|
||||||
if (work == NULL)
|
if (work == NULL)
|
||||||
|
@ -3042,6 +3043,13 @@ static void radio_start_next_work(void *eloop_ctx, void *timeout_ctx)
|
||||||
if (work->started)
|
if (work->started)
|
||||||
return; /* already started and still in progress */
|
return; /* already started and still in progress */
|
||||||
|
|
||||||
|
wpa_s = dl_list_first(&radio->ifaces, struct wpa_supplicant,
|
||||||
|
radio_list);
|
||||||
|
if (wpa_s && wpa_s->external_scan_running) {
|
||||||
|
wpa_printf(MSG_DEBUG, "Delay radio work start until externally triggered scan completes");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
os_get_reltime(&now);
|
os_get_reltime(&now);
|
||||||
os_reltime_sub(&now, &work->time, &diff);
|
os_reltime_sub(&now, &work->time, &diff);
|
||||||
wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting radio work '%s'@%p after %ld.%06ld second wait",
|
wpa_dbg(work->wpa_s, MSG_DEBUG, "Starting radio work '%s'@%p after %ld.%06ld second wait",
|
||||||
|
@ -3097,7 +3105,7 @@ static void radio_remove_interface(struct wpa_supplicant *wpa_s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void radio_work_check_next(struct wpa_supplicant *wpa_s)
|
void radio_work_check_next(struct wpa_supplicant *wpa_s)
|
||||||
{
|
{
|
||||||
struct wpa_radio *radio = wpa_s->radio;
|
struct wpa_radio *radio = wpa_s->radio;
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,7 @@ int radio_add_work(struct wpa_supplicant *wpa_s, unsigned int freq,
|
||||||
void radio_work_done(struct wpa_radio_work *work);
|
void radio_work_done(struct wpa_radio_work *work);
|
||||||
void radio_remove_unstarted_work(struct wpa_supplicant *wpa_s,
|
void radio_remove_unstarted_work(struct wpa_supplicant *wpa_s,
|
||||||
const char *type);
|
const char *type);
|
||||||
|
void radio_work_check_next(struct wpa_supplicant *wpa_s);
|
||||||
|
|
||||||
struct wpa_connect_work {
|
struct wpa_connect_work {
|
||||||
unsigned int sme:1;
|
unsigned int sme:1;
|
||||||
|
|
Loading…
Reference in a new issue