summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-11-05 16:42:28 +0200
committerJouni Malinen <j@w1.fi>2012-11-05 16:57:57 +0200
commit42d235477f2345003b76e4de1f397e21c2fa5b76 (patch)
tree8dabdc67a9472e0c45c6af1d9e433d2d8580c09d
parente50d01b4f1eb68e29b1f6b2f2a078575c146c4de (diff)
downloadhostap-42d235477f2345003b76e4de1f397e21c2fa5b76.tar.gz
Use wpa_drv_{disassociate,deauthenticate} while waiting for connection
wpa_supplicant_{disassociate,deauthenticate}() need to inform the driver about decision to disconnect even if this happens during the time when the driver is still trying to complete association. During that time, wpa_s->bssid is not set, so the code in these functions needs to figure out the correct BSSID based on that field or wpa_s->pending_bssid. In addition, it is possible that the BSSID is not even known at wpa_supplicant at this point in time when using drivers that perform BSS selection internally. In those cases, the disconnect command needs to be sent to the driver without the BSSID. This fixes issues where the driver (or cfg80211 in particular) may be left in mismatching state with wpa_supplicant when disconnection (e.g., due to a ctrl_iface command) happens between connection request and association event. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
-rw-r--r--wpa_supplicant/wpa_supplicant.c56
1 files changed, 52 insertions, 4 deletions
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index f1efe6ba8..076d31301 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -1694,14 +1694,38 @@ void wpa_supplicant_disassociate(struct wpa_supplicant *wpa_s,
{
u8 *addr = NULL;
union wpa_event_data event;
+ int zero_addr = 0;
- if (!is_zero_ether_addr(wpa_s->bssid)) {
- wpa_drv_disassociate(wpa_s, wpa_s->bssid, reason_code);
+ wpa_dbg(wpa_s, MSG_DEBUG, "Request to disassociate - bssid=" MACSTR
+ " pending_bssid=" MACSTR " reason=%d state=%s",
+ MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
+ reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
+
+ if (!is_zero_ether_addr(wpa_s->bssid))
+ addr = wpa_s->bssid;
+ else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
+ (wpa_s->wpa_state == WPA_AUTHENTICATING ||
+ wpa_s->wpa_state == WPA_ASSOCIATING))
+ addr = wpa_s->pending_bssid;
+ else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
+ /*
+ * When using driver-based BSS selection, we may not know the
+ * BSSID with which we are currently trying to associate. We
+ * need to notify the driver of this disconnection even in such
+ * a case, so use the all zeros address here.
+ */
addr = wpa_s->bssid;
+ zero_addr = 1;
+ }
+
+ if (addr) {
+ wpa_drv_disassociate(wpa_s, addr, reason_code);
os_memset(&event, 0, sizeof(event));
event.disassoc_info.reason_code = (u16) reason_code;
event.disassoc_info.locally_generated = 1;
wpa_supplicant_event(wpa_s, EVENT_DISASSOC, &event);
+ if (zero_addr)
+ addr = NULL;
}
wpa_supplicant_clear_connection(wpa_s, addr);
@@ -1721,14 +1745,38 @@ void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,
{
u8 *addr = NULL;
union wpa_event_data event;
+ int zero_addr = 0;
- if (!is_zero_ether_addr(wpa_s->bssid)) {
- wpa_drv_deauthenticate(wpa_s, wpa_s->bssid, reason_code);
+ wpa_dbg(wpa_s, MSG_DEBUG, "Request to deauthenticate - bssid=" MACSTR
+ " pending_bssid=" MACSTR " reason=%d state=%s",
+ MAC2STR(wpa_s->bssid), MAC2STR(wpa_s->pending_bssid),
+ reason_code, wpa_supplicant_state_txt(wpa_s->wpa_state));
+
+ if (!is_zero_ether_addr(wpa_s->bssid))
+ addr = wpa_s->bssid;
+ else if (!is_zero_ether_addr(wpa_s->pending_bssid) &&
+ (wpa_s->wpa_state == WPA_AUTHENTICATING ||
+ wpa_s->wpa_state == WPA_ASSOCIATING))
+ addr = wpa_s->pending_bssid;
+ else if (wpa_s->wpa_state == WPA_ASSOCIATING) {
+ /*
+ * When using driver-based BSS selection, we may not know the
+ * BSSID with which we are currently trying to associate. We
+ * need to notify the driver of this disconnection even in such
+ * a case, so use the all zeros address here.
+ */
addr = wpa_s->bssid;
+ zero_addr = 1;
+ }
+
+ if (addr) {
+ wpa_drv_deauthenticate(wpa_s, addr, reason_code);
os_memset(&event, 0, sizeof(event));
event.deauth_info.reason_code = (u16) reason_code;
event.deauth_info.locally_generated = 1;
wpa_supplicant_event(wpa_s, EVENT_DEAUTH, &event);
+ if (zero_addr)
+ addr = NULL;
}
wpa_supplicant_clear_connection(wpa_s, addr);