aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTova Mussai <tova.mussai@intel.com>2017-08-21 16:42:19 (GMT)
committerJouni Malinen <j@w1.fi>2018-04-19 21:48:49 (GMT)
commitc4315e66207ba948b87cc641ce982784efc7bb19 (patch)
tree2ecada76d2c84e209de257f27ae87cda94c6537a
parent86c998d37a7d8bd230fadc9c689698868754e08f (diff)
downloadhostap-c4315e66207ba948b87cc641ce982784efc7bb19.zip
hostap-c4315e66207ba948b87cc641ce982784efc7bb19.tar.gz
hostap-c4315e66207ba948b87cc641ce982784efc7bb19.tar.bz2
AP: Handle AP initalization failure in async flow
When AP initialization is completed in a callback (e.g., OBSS scan), wpa_supplicant_deinit_ap() is not called in case of failure. Fix this by calling setup_complete_cb in case of failure, too, which in turn calls wpa_supplicant_deinit_ap() if needed. Signed-off-by: Tova Mussai <tova.mussai@intel.com>
-rw-r--r--src/ap/hostapd.c31
-rw-r--r--wpa_supplicant/ap.c7
2 files changed, 37 insertions, 1 deletions
diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c
index 0b6db7b..d2eb044 100644
--- a/src/ap/hostapd.c
+++ b/src/ap/hostapd.c
@@ -56,6 +56,8 @@ static int hostapd_setup_encryption(char *iface, struct hostapd_data *hapd);
static int hostapd_broadcast_wep_clear(struct hostapd_data *hapd);
static int setup_interface2(struct hostapd_iface *iface);
static void channel_list_update_timeout(void *eloop_ctx, void *timeout_ctx);
+static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
+ void *timeout_ctx);
int hostapd_for_each_interface(struct hapd_interfaces *interfaces,
@@ -429,6 +431,8 @@ static void hostapd_cleanup_iface(struct hostapd_iface *iface)
{
wpa_printf(MSG_DEBUG, "%s(%p)", __func__, iface);
eloop_cancel_timeout(channel_list_update_timeout, iface, NULL);
+ eloop_cancel_timeout(hostapd_interface_setup_failure_handler, iface,
+ NULL);
hostapd_cleanup_iface_partial(iface);
hostapd_config_free(iface->conf);
@@ -1779,6 +1783,20 @@ static void hostapd_owe_update_trans(struct hostapd_iface *iface)
}
+static void hostapd_interface_setup_failure_handler(void *eloop_ctx,
+ void *timeout_ctx)
+{
+ struct hostapd_iface *iface = eloop_ctx;
+ struct hostapd_data *hapd;
+
+ if (iface->num_bss < 1 || !iface->bss || !iface->bss[0])
+ return;
+ hapd = iface->bss[0];
+ if (hapd->setup_complete_cb)
+ hapd->setup_complete_cb(hapd->setup_complete_cb_ctx);
+}
+
+
static int hostapd_setup_interface_complete_sync(struct hostapd_iface *iface,
int err)
{
@@ -1979,8 +1997,19 @@ fail:
iface->fst = NULL;
}
#endif /* CONFIG_FST */
- if (iface->interfaces && iface->interfaces->terminate_on_error)
+
+ if (iface->interfaces && iface->interfaces->terminate_on_error) {
eloop_terminate();
+ } else if (hapd->setup_complete_cb) {
+ /*
+ * Calling hapd->setup_complete_cb directly may cause iface
+ * deinitialization which may be accessed later by the caller.
+ */
+ eloop_register_timeout(0, 0,
+ hostapd_interface_setup_failure_handler,
+ iface, NULL);
+ }
+
return -1;
}
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index fe7ffe1..9e4fc1c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -633,6 +633,13 @@ static void wpas_ap_configured_cb(void *ctx)
{
struct wpa_supplicant *wpa_s = ctx;
+ wpa_printf(MSG_DEBUG, "AP interface setup completed - state %s",
+ hostapd_state_text(wpa_s->ap_iface->state));
+ if (wpa_s->ap_iface->state == HAPD_IFACE_DISABLED) {
+ wpa_supplicant_ap_deinit(wpa_s);
+ return;
+ }
+
#ifdef CONFIG_ACS
if (wpa_s->current_ssid && wpa_s->current_ssid->acs) {
wpa_s->assoc_freq = wpa_s->ap_iface->freq;