aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2017-11-23 11:08:45 (GMT)
committerJouni Malinen <j@w1.fi>2017-11-23 11:08:45 (GMT)
commit0db637ca8046332a053df7acb157ee003de48221 (patch)
treea4e7824f47e3a81e7c080833443e9db6d6c99c21 /wpa_supplicant
parent921f5acd17240ba05639628732d86f5eaeabf3e7 (diff)
downloadhostap-0db637ca8046332a053df7acb157ee003de48221.zip
hostap-0db637ca8046332a053df7acb157ee003de48221.tar.gz
hostap-0db637ca8046332a053df7acb157ee003de48221.tar.bz2
DPP: Fix number of Authentication Request retry cases
Previous implementation did not handle number of sequences correctly. Make sure the iteration continues in both unicast and broadcast cases until the five attempts have been made. In addition, improve timing by checking 10 second time from the beginning of each iteration round and not the last channel on which the Auth Req frame has been transmitted. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/dpp_supplicant.c87
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h2
2 files changed, 65 insertions, 24 deletions
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index f8a450d..3f3fd02 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -443,41 +443,64 @@ static void wpas_dpp_reply_wait_timeout(void *eloop_ctx, void *timeout_ctx)
struct wpa_supplicant *wpa_s = eloop_ctx;
struct dpp_authentication *auth = wpa_s->dpp_auth;
unsigned int freq;
- struct os_reltime now;
+ struct os_reltime now, diff;
+ unsigned int wait_time, diff_ms;
- if (!auth)
+ if (!auth || !auth->waiting_auth_resp)
return;
- if (auth->waiting_auth_resp && auth->auth_req_ack) {
+ wait_time = wpa_s->dpp_resp_wait_time ?
+ wpa_s->dpp_resp_wait_time : 2000;
+ os_get_reltime(&now);
+ os_reltime_sub(&now, &wpa_s->dpp_last_init, &diff);
+ diff_ms = diff.sec * 1000 + diff.usec / 1000;
+ wpa_printf(MSG_DEBUG,
+ "DPP: Reply wait timeout - wait_time=%u diff_ms=%u",
+ wait_time, diff_ms);
+
+ if (auth->auth_req_ack && diff_ms >= wait_time) {
+ /* Peer ACK'ed Authentication Request frame, but did not reply
+ * with Authentication Response frame within two seconds. */
wpa_printf(MSG_INFO,
"DPP: No response received from responder - stopping initiation attempt");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
offchannel_send_action_done(wpa_s);
+ wpas_dpp_listen_stop(wpa_s);
dpp_auth_deinit(auth);
wpa_s->dpp_auth = NULL;
return;
}
- if (auth->waiting_auth_resp) {
- unsigned int wait_time;
-
- wait_time = wpa_s->dpp_resp_wait_time ?
- wpa_s->dpp_resp_wait_time : 2;
- os_get_reltime(&now);
- if (os_reltime_expired(&now, &wpa_s->dpp_last_init,
- wait_time)) {
- offchannel_send_action_done(wpa_s);
- wpas_dpp_auth_init_next(wpa_s);
- return;
- }
+ if (diff_ms >= wait_time) {
+ /* Authentication Request frame was not ACK'ed and no reply
+ * was receiving within two seconds. */
+ wpa_printf(MSG_DEBUG,
+ "DPP: Continue Initiator channel iteration");
+ offchannel_send_action_done(wpa_s);
+ wpas_dpp_listen_stop(wpa_s);
+ wpas_dpp_auth_init_next(wpa_s);
+ return;
}
+ /* Driver did not support 2000 ms long wait_time with TX command, so
+ * schedule listen operation to continue waiting for the response.
+ *
+ * DPP listen operations continue until stopped, so simply schedule a
+ * new call to this function at the point when the two second reply
+ * wait has expired. */
+ wait_time -= diff_ms;
+
freq = auth->curr_freq;
if (auth->neg_freq > 0)
freq = auth->neg_freq;
- wpa_printf(MSG_DEBUG, "DPP: Continue reply wait on channel %u MHz",
- freq);
+ wpa_printf(MSG_DEBUG,
+ "DPP: Continue reply wait on channel %u MHz for %u ms",
+ freq, wait_time);
+ wpa_s->dpp_in_response_listen = 1;
wpas_dpp_listen_start(wpa_s, freq);
+
+ eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
+ wpas_dpp_reply_wait_timeout, wpa_s, NULL);
}
@@ -657,11 +680,16 @@ static int wpas_dpp_auth_init_next(struct wpa_supplicant *wpa_s)
{
struct dpp_authentication *auth = wpa_s->dpp_auth;
const u8 *dst;
- unsigned int wait_time, freq, max_tries, used;
+ unsigned int wait_time, max_wait_time, freq, max_tries, used;
struct os_reltime now, diff;
+ wpa_s->dpp_in_response_listen = 0;
if (!auth)
return -1;
+
+ if (auth->freq_idx == 0)
+ os_get_reltime(&wpa_s->dpp_init_iter_start);
+
if (auth->freq_idx >= auth->num_freq) {
auth->num_freq_iters++;
if (wpa_s->dpp_init_max_tries)
@@ -686,7 +714,7 @@ static int wpas_dpp_auth_init_next(struct wpa_supplicant *wpa_s)
else
wait_time = 10000;
os_get_reltime(&now);
- os_reltime_sub(&now, &wpa_s->dpp_last_init, &diff);
+ os_reltime_sub(&now, &wpa_s->dpp_init_iter_start, &diff);
used = diff.sec * 1000 + diff.usec / 1000;
if (used > wait_time)
wait_time = 0;
@@ -710,11 +738,15 @@ static int wpas_dpp_auth_init_next(struct wpa_supplicant *wpa_s)
wpa_s->dpp_auth_ok_on_ack = 0;
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout, wpa_s, NULL);
wait_time = wpa_s->max_remain_on_chan;
- if (wait_time > 2000)
- wait_time = 2000;
+ max_wait_time = wpa_s->dpp_resp_wait_time ?
+ wpa_s->dpp_resp_wait_time : 2000;
+ if (wait_time > max_wait_time)
+ wait_time = max_wait_time;
+ wait_time += 10; /* give the driver some extra time to complete */
eloop_register_timeout(wait_time / 1000, (wait_time % 1000) * 1000,
wpas_dpp_reply_wait_timeout,
wpa_s, NULL);
+ wait_time -= 10;
if (auth->neg_freq > 0 && freq != auth->neg_freq) {
wpa_printf(MSG_DEBUG,
"DPP: Initiate on %u MHz and move to neg_freq %u MHz for response",
@@ -942,6 +974,7 @@ int wpas_dpp_listen(struct wpa_supplicant *wpa_s, const char *cmd)
void wpas_dpp_listen_stop(struct wpa_supplicant *wpa_s)
{
+ wpa_s->dpp_in_response_listen = 0;
if (!wpa_s->dpp_listen_freq)
return;
@@ -981,12 +1014,18 @@ void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
{
wpas_dpp_listen_work_done(wpa_s);
- if (wpa_s->dpp_auth && !wpa_s->dpp_gas_client) {
+ if (wpa_s->dpp_auth && wpa_s->dpp_in_response_listen) {
+ unsigned int new_freq;
+
/* Continue listen with a new remain-on-channel */
+ if (wpa_s->dpp_auth->neg_freq > 0)
+ new_freq = wpa_s->dpp_auth->neg_freq;
+ else
+ new_freq = wpa_s->dpp_auth->curr_freq;
wpa_printf(MSG_DEBUG,
"DPP: Continue wait on %u MHz for the ongoing DPP provisioning session",
- wpa_s->dpp_auth->curr_freq);
- wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->curr_freq);
+ new_freq);
+ wpas_dpp_listen_start(wpa_s, new_freq);
return;
}
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 099c8d0..383ef9d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1190,6 +1190,7 @@ struct wpa_supplicant {
int dpp_qr_mutual;
int dpp_netrole_ap;
int dpp_auth_ok_on_ack;
+ int dpp_in_response_listen;
int dpp_gas_client;
u8 dpp_intro_bssid[ETH_ALEN];
void *dpp_intro_network;
@@ -1200,6 +1201,7 @@ struct wpa_supplicant {
char *dpp_pkex_auth_cmd;
char *dpp_configurator_params;
struct os_reltime dpp_last_init;
+ struct os_reltime dpp_init_iter_start;
unsigned int dpp_init_max_tries;
unsigned int dpp_init_retry_time;
unsigned int dpp_resp_wait_time;