]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
Reject authentication start during explicit roam requests
authorMatthew Wang <matthewmwang@chromium.org>
Sat, 6 Mar 2021 01:43:44 +0000 (17:43 -0800)
committerJouni Malinen <j@w1.fi>
Sat, 6 Mar 2021 08:59:05 +0000 (10:59 +0200)
The roam D-Bus and ROAM control itnerface commands flip the reassociate
bit before calling wpa_supplicant_connect(). wpa_supplicant connect
eventually aborts ongoing scans (if any), which causes scan results to
be reported. Since the reassociate bit is set, this will trigger a
connection attempt based on the aborted scan's scan results and cancel
the initial connetion request. This often causes wpa_supplicant to
reassociate to the same AP it is currently associated to instead of the
explicitly requested roaming target.

Add a roam_in_progress flag to indicate that we're currently attempting
to roam via an explicitly request to a specific BSS so that we don't
initiate another connection attempt based on the possibly received scan
results from a scan that was in progress at the time the roam command
was received.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/sme.c
wpa_supplicant/wpa_supplicant_i.h

index 0d4c2bc8f0bb3291fe4449657badbcbbdb1f361e..7fc7e7d69b24c2cb1b5b9c517ef7ceec6bd599be 100644 (file)
@@ -5656,6 +5656,7 @@ static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
        u8 bssid[ETH_ALEN];
        struct wpa_bss *bss;
        struct wpa_ssid *ssid = wpa_s->current_ssid;
+       struct wpa_radio_work *already_connecting;
 
        if (hwaddr_aton(addr, bssid)) {
                wpa_printf(MSG_DEBUG, "CTRL_IFACE ROAM: invalid "
@@ -5683,9 +5684,18 @@ static int wpa_supplicant_ctrl_iface_roam(struct wpa_supplicant *wpa_s,
         * allow roaming to other networks
         */
 
+       already_connecting = radio_work_pending(wpa_s, "sme-connect");
        wpa_s->reassociate = 1;
        wpa_supplicant_connect(wpa_s, bss, ssid);
 
+       /*
+        * Indicate that an explicitly requested roam is in progress so scan
+        * results that come in before the 'sme-connect' radio work gets
+        * executed do not override the original connection attempt.
+        */
+       if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
+               wpa_s->roam_in_progress = true;
+
        return 0;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 }
index 7d20f2123a811c24cc5f928b8273ffa56f4ee311..db9f30c9aabf3a2d82dbe7581b46cbbd8feecc22 100644 (file)
@@ -1979,6 +1979,7 @@ DBusMessage * wpas_dbus_handler_roam(DBusMessage *message,
        struct wpa_bss *bss;
        struct wpa_ssid *ssid = wpa_s->current_ssid;
        char *addr;
+       struct wpa_radio_work *already_connecting;
 
        if (!dbus_message_get_args(message, NULL, DBUS_TYPE_STRING, &addr,
                                   DBUS_TYPE_INVALID))
@@ -2002,9 +2003,18 @@ DBusMessage * wpas_dbus_handler_roam(DBusMessage *message,
                        message, "Target BSS not found");
        }
 
+       already_connecting = radio_work_pending(wpa_s, "sme-connect");
        wpa_s->reassociate = 1;
        wpa_supplicant_connect(wpa_s, bss, ssid);
 
+       /*
+        * Indicate that an explicitly requested roam is in progress so scan
+        * results that come in before the 'sme-connect' radio work gets
+        * executed do not override the original connection attempt.
+        */
+       if (!already_connecting && radio_work_pending(wpa_s, "sme-connect"))
+               wpa_s->roam_in_progress = true;
+
        return NULL;
 #endif /* CONFIG_NO_SCAN_PROCESSING */
 }
index 522c8297f7e445c92ead09bc0cf43ebf32ce650f..dde80863a988ce4d64e3e77864cad5507dfba7b3 100644 (file)
@@ -941,6 +941,8 @@ static void sme_auth_start_cb(struct wpa_radio_work *work, int deinit)
        struct wpa_connect_work *cwork = work->ctx;
        struct wpa_supplicant *wpa_s = work->wpa_s;
 
+       wpa_s->roam_in_progress = false;
+
        if (deinit) {
                if (work->started)
                        wpa_s->connect_work = NULL;
@@ -981,6 +983,11 @@ void sme_authenticate(struct wpa_supplicant *wpa_s,
                return;
        }
 
+       if (wpa_s->roam_in_progress) {
+               wpa_dbg(wpa_s, MSG_DEBUG,
+                       "SME: Reject sme_authenticate() in favor of explicit roam request");
+               return;
+       }
        if (radio_work_pending(wpa_s, "sme-connect")) {
                /*
                 * The previous sme-connect work might no longer be valid due to
index 7d14b627d89afc73b0b56cf70ea96518e35058b9..b6c339ab7117164cf783a634a8abb2783fc6a0fa 100644 (file)
@@ -621,6 +621,7 @@ struct wpa_supplicant {
        u8 pending_bssid[ETH_ALEN]; /* If wpa_state == WPA_ASSOCIATING, this
                                     * field contains the target BSSID. */
        int reassociate; /* reassociation requested */
+       bool roam_in_progress; /* roam in progress */
        unsigned int reassoc_same_bss:1; /* reassociating to the same BSS */
        unsigned int reassoc_same_ess:1; /* reassociating to the same ESS */
        int disconnected; /* all connections disabled; i.e., do no reassociate