diff --git a/src/common/dpp.h b/src/common/dpp.h index 2fd331b1a..65ee905a7 100644 --- a/src/common/dpp.h +++ b/src/common/dpp.h @@ -348,6 +348,7 @@ struct dpp_authentication { struct wpabuf *cacert; struct wpabuf *certbag; void *cert_resp_ctx; + void *gas_server_ctx; #ifdef CONFIG_TESTING_OPTIONS char *config_obj_override; char *discovery_override; diff --git a/src/common/gas_server.c b/src/common/gas_server.c index c000aeb60..5f44ffebd 100644 --- a/src/common/gas_server.c +++ b/src/common/gas_server.c @@ -489,6 +489,21 @@ int gas_server_set_resp(struct gas_server *gas, void *resp_ctx, } +bool gas_server_response_sent(struct gas_server *gas, void *resp_ctx) +{ + struct gas_server_response *tmp; + + dl_list_for_each(tmp, &gas->responses, struct gas_server_response, + list) { + if (tmp == resp_ctx) + return tmp->resp && + tmp->offset == wpabuf_len(tmp->resp); + } + + return false; +} + + struct gas_server * gas_server_init(void *ctx, void (*tx)(void *ctx, int freq, const u8 *da, diff --git a/src/common/gas_server.h b/src/common/gas_server.h index 2611ddedc..db00f87e8 100644 --- a/src/common/gas_server.h +++ b/src/common/gas_server.h @@ -36,6 +36,7 @@ void gas_server_tx_status(struct gas_server *gas, const u8 *dst, const u8 *data, size_t data_len, int ack); int gas_server_set_resp(struct gas_server *gas, void *resp_ctx, struct wpabuf *resp); +bool gas_server_response_sent(struct gas_server *gas, void *resp_ctx); #else /* CONFIG_GAS_SERVER */ diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c index b2443ae37..2bcf10b4e 100644 --- a/wpa_supplicant/dpp_supplicant.c +++ b/wpa_supplicant/dpp_supplicant.c @@ -1918,9 +1918,22 @@ static void wpas_dpp_rx_conf_result(struct wpa_supplicant *wpa_s, const u8 *src, MAC2STR(src)); if (!auth || !auth->waiting_conf_result) { - wpa_printf(MSG_DEBUG, - "DPP: No DPP Configuration waiting for result - drop"); - return; + if (auth && + os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) == 0 && + gas_server_response_sent(wpa_s->gas_server, + auth->gas_server_ctx)) { + /* This could happen if the TX status event gets delayed + * long enough for the Enrollee to have time to send + * the next frame before the TX status gets processed + * locally. */ + wpa_printf(MSG_DEBUG, + "DPP: GAS response was sent but TX status not yet received - assume it was ACKed since the Enrollee sent the next frame in the sequence"); + auth->waiting_conf_result = 1; + } else { + wpa_printf(MSG_DEBUG, + "DPP: No DPP Configuration waiting for result - drop"); + return; + } } if (os_memcmp(src, auth->peer_mac_addr, ETH_ALEN) != 0) { @@ -2969,6 +2982,7 @@ wpas_dpp_gas_req_handler(void *ctx, void *resp_ctx, const u8 *sa, if (!resp) wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED); auth->conf_resp = resp; + auth->gas_server_ctx = resp_ctx; return resp; } @@ -3006,7 +3020,8 @@ wpas_dpp_gas_status_handler(void *ctx, struct wpabuf *resp, int ok) eloop_cancel_timeout(wpas_dpp_auth_resp_retry_timeout, wpa_s, NULL); #ifdef CONFIG_DPP2 if (ok && auth->peer_version >= 2 && - auth->conf_resp_status == DPP_STATUS_OK) { + auth->conf_resp_status == DPP_STATUS_OK && + !auth->waiting_conf_result) { wpa_printf(MSG_DEBUG, "DPP: Wait for Configuration Result"); auth->waiting_conf_result = 1; auth->conf_resp = NULL;