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:
Jouni Malinen 2014-01-04 10:33:14 +02:00
parent 7c0d8645a1
commit 6428d0a71f
4 changed files with 11 additions and 12 deletions

View file

@ -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:

View file

@ -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");

View file

@ -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;

View file

@ -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;