diff mbox series

[v3] Reject auths during explicit roam requests

Message ID 20210306014344.431232-1-matthewmwang@chromium.org
State Accepted
Headers show
Series [v3] Reject auths during explicit roam requests | expand

Commit Message

Matthew Wang March 6, 2021, 1:43 a.m. UTC
The roam D-Bus and wpa_cli commands flip the reassociate bit before
calling wpa_supplicant_connect. wpa_supplicant connect eventually aborts
ongoing scans, 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.

Add a roam_in_progress flag to indicate that we're currently attempting
to roam via D-Bus so that we don't initate another connection attempt.

Signed-off-by: Matthew Wang <matthewmwang@chromium.org>
Series-to: hostap@lists.infradead.org
Series-cc: j@w1.fi, matthewmwang@chromium.org
---
 wpa_supplicant/ctrl_iface.c             | 11 +++++++++++
 wpa_supplicant/dbus/dbus_new_handlers.c | 11 +++++++++++
 wpa_supplicant/sme.c                    |  7 +++++++
 wpa_supplicant/wpa_supplicant_i.h       |  1 +
 4 files changed, 30 insertions(+)

Comments

Jouni Malinen March 6, 2021, 1:51 p.m. UTC | #1
On Fri, Mar 05, 2021 at 05:43:44PM -0800, Matthew Wang wrote:
> The roam D-Bus and wpa_cli commands flip the reassociate bit before
> calling wpa_supplicant_connect. wpa_supplicant connect eventually aborts
> ongoing scans, 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.
> 
> Add a roam_in_progress flag to indicate that we're currently attempting
> to roam via D-Bus so that we don't initate another connection attempt.

Thanks, applied.
diff mbox series

Patch

diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 0d4c2bc8f0b..93cfa9dd18f 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -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,19 @@  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 */
 }
diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c
index 7d20f2123a8..6c3646979c1 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers.c
@@ -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,19 @@  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 */
 }
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 522c8297f7e..dde80863a98 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -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
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 7d14b627d89..b6c339ab711 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -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