From f7b4ef220845f700a19149a96e0fad54d905e123 Mon Sep 17 00:00:00 2001 From: Sunil Dutt Date: Thu, 1 Aug 2013 10:47:23 +0300 Subject: [PATCH] TDLS: Handle transmission failures of TPK Handshake messages A transmission failure of the TDLS Setup Request frame (TPK Handshake M1) results in no further retries and the peer entry being left in state where all TDLS Setup Request frames from the peer with higher address would be rejected, thus always resulting in a failure to establish a TDLS link. Handle the failures in transmission by disabling the link immediately to ensure the traffic to the peer goes through the AP. This commit also handles similar transmision failures for TPK Handshake M2 and M3 frames (TDLS Setup Response and Confirm). Signed-hostap: Jouni Malinen --- src/rsn_supp/tdls.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/rsn_supp/tdls.c b/src/rsn_supp/tdls.c index 539aa2565..b7ca07522 100644 --- a/src/rsn_supp/tdls.c +++ b/src/rsn_supp/tdls.c @@ -932,6 +932,7 @@ static int wpa_tdls_send_tpk_m1(struct wpa_sm *sm, u8 *rbuf, *pos, *count_pos; u16 count; struct rsn_ie_hdr *hdr; + int status; if (!wpa_tdls_get_privacy(sm)) { wpa_printf(MSG_DEBUG, "TDLS: No security used on the link"); @@ -1092,11 +1093,11 @@ skip_ies: "Handshake Message 1 (peer " MACSTR ")", MAC2STR(peer->addr)); - wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, 1, 0, - rbuf, pos - rbuf); + status = wpa_tdls_tpk_send(sm, peer->addr, WLAN_TDLS_SETUP_REQUEST, + 1, 0, rbuf, pos - rbuf); os_free(rbuf); - return 0; + return status; } @@ -1110,6 +1111,7 @@ static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm, u32 lifetime; struct wpa_tdls_timeoutie timeoutie; struct wpa_tdls_ftie *ftie; + int status; buf_len = 0; if (wpa_tdls_get_privacy(sm)) { @@ -1175,11 +1177,11 @@ static int wpa_tdls_send_tpk_m2(struct wpa_sm *sm, (u8 *) &timeoutie, (u8 *) ftie, ftie->mic); skip_ies: - wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, dtoken, 0, - rbuf, pos - rbuf); + status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_RESPONSE, + dtoken, 0, rbuf, pos - rbuf); os_free(rbuf); - return 0; + return status; } @@ -1193,6 +1195,7 @@ static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm, struct wpa_tdls_ftie *ftie; struct wpa_tdls_timeoutie timeoutie; u32 lifetime; + int status; buf_len = 0; if (wpa_tdls_get_privacy(sm)) { @@ -1256,11 +1259,11 @@ static int wpa_tdls_send_tpk_m3(struct wpa_sm *sm, (u8 *) &timeoutie, (u8 *) ftie, ftie->mic); skip_ies: - wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, 0, - rbuf, pos - rbuf); + status = wpa_tdls_tpk_send(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, + dtoken, 0, rbuf, pos - rbuf); os_free(rbuf); - return 0; + return status; } @@ -2030,7 +2033,10 @@ skip_rsn: wpa_printf(MSG_DEBUG, "TDLS: Sending TDLS Setup Confirm / " "TPK Handshake Message 3"); - wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer); + if (wpa_tdls_send_tpk_m3(sm, src_addr, dtoken, lnkid, peer) < 0) { + wpa_tdls_disable_link(sm, peer->addr); + return -1; + } ret = wpa_tdls_enable_link(sm, peer); if (ret < 0) { @@ -2043,8 +2049,7 @@ skip_rsn: error: wpa_tdls_send_error(sm, src_addr, WLAN_TDLS_SETUP_CONFIRM, dtoken, status); - if (sm->tdls_external_setup) - wpa_sm_tdls_oper(sm, TDLS_DISABLE_LINK, src_addr); + wpa_tdls_disable_link(sm, peer->addr); return -1; }