DPP2: Accept Config Result before GAS response TX status

The TX event for the next frame in the sequence might be received before
the TX status for the final GAS response frame is processed. This used
to result in the Config Result getting discarded and the negotiation not
completing successfully on the Configurator side.

Accept the Config Result message as an indication of the final GAS
response frame having went through fine even if the TX status has not
yet been processed to avoid this issue from a potential race condition
on kernel events.

Signed-off-by: Jouni Malinen <j@w1.fi>
master
Jouni Malinen 3 years ago
parent 6518c72b02
commit 976c3c161f

@ -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;

@ -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,

@ -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 */

@ -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;

Loading…
Cancel
Save