mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-22 06:29:23 +01:00
dpp: fix fragile scan/connecting logic
The post-DPP connection was never done quite right due to station's state being unknown. The state is now tracked in DPP by a previous patch but the scan path in DPP is still wrong. It relies on station autoconnect logic which has the potential to connect to a different network than what was configured with DPP. Its unlikely but still could happen in theory. In addition the scan was not selectively filtering results by the SSID that DPP configured. This fixes the above problems by first filtering the scan by the SSID. Then setting the scan results into station without triggering autoconnect. And finally using network_autoconnect() directly instead of relying on station to choose the SSID.
This commit is contained in:
parent
e2f28312e2
commit
c8a86edffe
44
src/dpp.c
44
src/dpp.c
@ -853,13 +853,42 @@ static bool dpp_scan_results(int err, struct l_queue *bss_list,
|
||||
{
|
||||
struct dpp_sm *dpp = userdata;
|
||||
struct station *station = station_find(netdev_get_ifindex(dpp->netdev));
|
||||
struct scan_bss *bss;
|
||||
char ssid[33];
|
||||
struct network *network;
|
||||
|
||||
if (err < 0)
|
||||
return false;
|
||||
goto reset;
|
||||
|
||||
station_set_scan_results(station, bss_list, freqs, true);
|
||||
if (!bss_list || l_queue_length(bss_list) == 0)
|
||||
goto reset;
|
||||
|
||||
/*
|
||||
* The station watch _should_ detect this and reset, which cancels the
|
||||
* scan. But just in case...
|
||||
*/
|
||||
if (L_WARN_ON(station_get_connected_network(station)))
|
||||
goto reset;
|
||||
|
||||
/* Purely for grabbing the SSID */
|
||||
bss = l_queue_peek_head(bss_list);
|
||||
|
||||
memcpy(ssid, bss->ssid, bss->ssid_len);
|
||||
ssid[bss->ssid_len] = '\0';
|
||||
|
||||
station_set_scan_results(station, bss_list, freqs, false);
|
||||
|
||||
network = station_network_find(station, ssid, SECURITY_PSK);
|
||||
|
||||
dpp_reset(dpp);
|
||||
|
||||
bss = network_bss_select(network, true);
|
||||
network_autoconnect(network, bss);
|
||||
|
||||
return true;
|
||||
|
||||
reset:
|
||||
return false;
|
||||
}
|
||||
|
||||
static void dpp_scan_destroy(void *userdata)
|
||||
@ -898,6 +927,7 @@ static void dpp_handle_config_response_frame(const struct mmpdu_header *frame,
|
||||
struct network *network = NULL;
|
||||
struct scan_bss *bss = NULL;
|
||||
char ssid[33];
|
||||
size_t ssid_len;
|
||||
|
||||
if (dpp->state != DPP_STATE_CONFIGURING)
|
||||
return;
|
||||
@ -1027,6 +1057,7 @@ static void dpp_handle_config_response_frame(const struct mmpdu_header *frame,
|
||||
*/
|
||||
if (station) {
|
||||
memcpy(ssid, config->ssid, config->ssid_len);
|
||||
ssid_len = config->ssid_len;
|
||||
ssid[config->ssid_len] = '\0';
|
||||
|
||||
network = station_network_find(station, ssid, SECURITY_PSK);
|
||||
@ -1045,7 +1076,14 @@ static void dpp_handle_config_response_frame(const struct mmpdu_header *frame,
|
||||
__station_connect_network(station, network, bss,
|
||||
STATION_STATE_CONNECTING);
|
||||
else if (station) {
|
||||
dpp->connect_scan_id = scan_active(dpp->wdev_id, NULL, 0,
|
||||
struct scan_parameters params = {0};
|
||||
|
||||
params.ssid = (void *) ssid;
|
||||
params.ssid_len = ssid_len;
|
||||
|
||||
l_debug("Scanning for %s", ssid);
|
||||
|
||||
dpp->connect_scan_id = scan_active_full(dpp->wdev_id, ¶ms,
|
||||
dpp_scan_triggered,
|
||||
dpp_scan_results, dpp,
|
||||
dpp_scan_destroy);
|
||||
|
Loading…
Reference in New Issue
Block a user