From 6e03933e627425057e1b5a3358b9c3249cadd338 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Mon, 14 Aug 2017 14:31:19 +0200 Subject: [PATCH] netdev: Allow reassociation if not currently connected Allow attempts to connect to a new AP using the Reassociation frame even if netdev->operational is false. This is needed if we want to continue an ongoing roam attempt after the original connection broke and will be needed when we start using cached PMKSAs in the future. --- src/device.c | 8 ++++++-- src/netdev.c | 17 ++++++++--------- src/netdev.h | 5 +++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/src/device.c b/src/device.c index f53a4290..7a499c89 100644 --- a/src/device.c +++ b/src/device.c @@ -100,6 +100,9 @@ static struct l_queue *device_list; static void device_roam_timeout_rearm(struct device *device, int seconds); +static void device_netdev_event(struct netdev *netdev, enum netdev_event event, + void *user_data); + uint32_t device_watch_add(device_watch_func_t func, void *userdata, device_destroy_func_t destroy) { @@ -807,8 +810,9 @@ static void device_transition_reassociate(struct device *device, struct scan_bss *bss, struct handshake_state *new_hs) { - if (netdev_reassociate(device->netdev, bss, new_hs, - device_reassociate_cb) < 0) { + if (netdev_reassociate(device->netdev, bss, device->connected_bss, + new_hs, device_netdev_event, + device_reassociate_cb, device) < 0) { handshake_state_free(new_hs); device_roam_failed(device); diff --git a/src/netdev.c b/src/netdev.c index b92620ca..42249e38 100644 --- a/src/netdev.c +++ b/src/netdev.c @@ -2187,7 +2187,9 @@ int netdev_disconnect(struct netdev *netdev, } int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss, - struct handshake_state *hs, netdev_connect_cb_t cb) + struct scan_bss *orig_bss, struct handshake_state *hs, + netdev_event_func_t event_filter, + netdev_connect_cb_t cb, void *user_data) { struct l_genl_msg *cmd_connect; struct handshake_state *old_hs; @@ -2195,11 +2197,8 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss, bool is_rsn = hs->own_ie != NULL; int err; - if (!netdev->operational) - return -ENOTCONN; - cmd_connect = netdev_build_cmd_connect(netdev, target_bss, hs, - netdev->handshake->aa); + orig_bss->addr); if (!cmd_connect) return -EINVAL; @@ -2210,12 +2209,11 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss, old_hs = netdev->handshake; err = netdev_connect_common(netdev, cmd_connect, target_bss, hs, sm, - netdev->event_filter, cb, - netdev->user_data); + event_filter, cb, user_data); if (err < 0) return err; - memcpy(netdev->prev_bssid, old_hs->aa, ETH_ALEN); + memcpy(netdev->prev_bssid, orig_bss->addr, ETH_ALEN); netdev->operational = false; @@ -2238,7 +2236,8 @@ int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss, if (old_sm) eapol_sm_free(old_sm); - handshake_state_free(old_hs); + if (old_hs) + handshake_state_free(old_hs); return err; } diff --git a/src/netdev.h b/src/netdev.h index 667008a9..4ea661c5 100644 --- a/src/netdev.h +++ b/src/netdev.h @@ -101,8 +101,9 @@ int netdev_connect_wsc(struct netdev *netdev, struct scan_bss *bss, int netdev_disconnect(struct netdev *netdev, netdev_disconnect_cb_t cb, void *user_data); int netdev_reassociate(struct netdev *netdev, struct scan_bss *target_bss, - struct handshake_state *hs, - netdev_connect_cb_t cb); + struct scan_bss *orig_bss, struct handshake_state *hs, + netdev_event_func_t event_filter, + netdev_connect_cb_t cb, void *user_data); int netdev_fast_transition(struct netdev *netdev, struct scan_bss *target_bss, netdev_connect_cb_t cb); int netdev_preauthenticate(struct netdev *netdev, struct scan_bss *target_bss,