Interworking: Keep up to two pending GAS_REQUEST responses
Previously, only the last response data was kept in memory. This increases that to hold up to two last responses to allow some more parallel operations to be requested. In addition, the response data is now freed as soon as the external program has fetched it. Signed-hostap: Jouni Malinen <j@w1.fi>
This commit is contained in:
parent
090b8e3d14
commit
b6a9590b34
4 changed files with 45 additions and 15 deletions
|
@ -4849,9 +4849,8 @@ static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf,
|
||||||
int used;
|
int used;
|
||||||
char *pos;
|
char *pos;
|
||||||
size_t resp_len, start, requested_len;
|
size_t resp_len, start, requested_len;
|
||||||
|
struct wpabuf *resp;
|
||||||
if (!wpa_s->last_gas_resp)
|
int ret;
|
||||||
return -1;
|
|
||||||
|
|
||||||
used = hwaddr_aton2(cmd, addr);
|
used = hwaddr_aton2(cmd, addr);
|
||||||
if (used < 0)
|
if (used < 0)
|
||||||
|
@ -4862,11 +4861,18 @@ static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf,
|
||||||
pos++;
|
pos++;
|
||||||
dialog_token = atoi(pos);
|
dialog_token = atoi(pos);
|
||||||
|
|
||||||
if (os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) != 0 ||
|
if (wpa_s->last_gas_resp &&
|
||||||
dialog_token != wpa_s->last_gas_dialog_token)
|
os_memcmp(addr, wpa_s->last_gas_addr, ETH_ALEN) == 0 &&
|
||||||
|
dialog_token == wpa_s->last_gas_dialog_token)
|
||||||
|
resp = wpa_s->last_gas_resp;
|
||||||
|
else if (wpa_s->prev_gas_resp &&
|
||||||
|
os_memcmp(addr, wpa_s->prev_gas_addr, ETH_ALEN) == 0 &&
|
||||||
|
dialog_token == wpa_s->prev_gas_dialog_token)
|
||||||
|
resp = wpa_s->prev_gas_resp;
|
||||||
|
else
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
resp_len = wpabuf_len(wpa_s->last_gas_resp);
|
resp_len = wpabuf_len(resp);
|
||||||
start = 0;
|
start = 0;
|
||||||
requested_len = resp_len;
|
requested_len = resp_len;
|
||||||
|
|
||||||
|
@ -4887,9 +4893,24 @@ static int gas_response_get(struct wpa_supplicant *wpa_s, char *cmd, char *buf,
|
||||||
if (requested_len * 2 + 1 > buflen)
|
if (requested_len * 2 + 1 > buflen)
|
||||||
return os_snprintf(buf, buflen, "FAIL-Too long response");
|
return os_snprintf(buf, buflen, "FAIL-Too long response");
|
||||||
|
|
||||||
return wpa_snprintf_hex(buf, buflen,
|
ret = wpa_snprintf_hex(buf, buflen, wpabuf_head_u8(resp) + start,
|
||||||
wpabuf_head_u8(wpa_s->last_gas_resp) + start,
|
|
||||||
requested_len);
|
requested_len);
|
||||||
|
|
||||||
|
if (start + requested_len == resp_len) {
|
||||||
|
/*
|
||||||
|
* Free memory by dropping the response after it has been
|
||||||
|
* fetched.
|
||||||
|
*/
|
||||||
|
if (resp == wpa_s->prev_gas_resp) {
|
||||||
|
wpabuf_free(wpa_s->prev_gas_resp);
|
||||||
|
wpa_s->prev_gas_resp = NULL;
|
||||||
|
} else {
|
||||||
|
wpabuf_free(wpa_s->last_gas_resp);
|
||||||
|
wpa_s->last_gas_resp = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_INTERWORKING */
|
#endif /* CONFIG_INTERWORKING */
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Interworking (IEEE 802.11u)
|
* Interworking (IEEE 802.11u)
|
||||||
* Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
|
* Copyright (c) 2011-2013, Qualcomm Atheros, Inc.
|
||||||
|
* Copyright (c) 2011-2014, Jouni Malinen <j@w1.fi>
|
||||||
*
|
*
|
||||||
* This software may be distributed under the terms of the BSD license.
|
* This software may be distributed under the terms of the BSD license.
|
||||||
* See README for more details.
|
* See README for more details.
|
||||||
|
@ -2231,6 +2232,7 @@ static void gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
|
||||||
const struct wpabuf *resp, u16 status_code)
|
const struct wpabuf *resp, u16 status_code)
|
||||||
{
|
{
|
||||||
struct wpa_supplicant *wpa_s = ctx;
|
struct wpa_supplicant *wpa_s = ctx;
|
||||||
|
struct wpabuf *n;
|
||||||
|
|
||||||
wpa_msg(wpa_s, MSG_INFO, GAS_RESPONSE_INFO "addr=" MACSTR
|
wpa_msg(wpa_s, MSG_INFO, GAS_RESPONSE_INFO "addr=" MACSTR
|
||||||
" dialog_token=%d status_code=%d resp_len=%d",
|
" dialog_token=%d status_code=%d resp_len=%d",
|
||||||
|
@ -2239,10 +2241,14 @@ static void gas_resp_cb(void *ctx, const u8 *addr, u8 dialog_token,
|
||||||
if (!resp)
|
if (!resp)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
wpabuf_free(wpa_s->last_gas_resp);
|
n = wpabuf_dup(resp);
|
||||||
wpa_s->last_gas_resp = wpabuf_dup(resp);
|
if (n == NULL)
|
||||||
if (wpa_s->last_gas_resp == NULL)
|
|
||||||
return;
|
return;
|
||||||
|
wpabuf_free(wpa_s->prev_gas_resp);
|
||||||
|
wpa_s->prev_gas_resp = wpa_s->last_gas_resp;
|
||||||
|
os_memcpy(wpa_s->prev_gas_addr, wpa_s->last_gas_addr, ETH_ALEN);
|
||||||
|
wpa_s->prev_gas_dialog_token = wpa_s->last_gas_dialog_token;
|
||||||
|
wpa_s->last_gas_resp = n;
|
||||||
os_memcpy(wpa_s->last_gas_addr, addr, ETH_ALEN);
|
os_memcpy(wpa_s->last_gas_addr, addr, ETH_ALEN);
|
||||||
wpa_s->last_gas_dialog_token = dialog_token;
|
wpa_s->last_gas_dialog_token = dialog_token;
|
||||||
}
|
}
|
||||||
|
|
|
@ -477,6 +477,9 @@ static void wpa_supplicant_cleanup(struct wpa_supplicant *wpa_s)
|
||||||
wpa_s->ext_pw = NULL;
|
wpa_s->ext_pw = NULL;
|
||||||
|
|
||||||
wpabuf_free(wpa_s->last_gas_resp);
|
wpabuf_free(wpa_s->last_gas_resp);
|
||||||
|
wpa_s->last_gas_resp = NULL;
|
||||||
|
wpabuf_free(wpa_s->prev_gas_resp);
|
||||||
|
wpa_s->prev_gas_resp = NULL;
|
||||||
|
|
||||||
os_free(wpa_s->last_scan_res);
|
os_free(wpa_s->last_scan_res);
|
||||||
wpa_s->last_scan_res = NULL;
|
wpa_s->last_scan_res = NULL;
|
||||||
|
|
|
@ -770,9 +770,9 @@ struct wpa_supplicant {
|
||||||
|
|
||||||
struct ext_password_data *ext_pw;
|
struct ext_password_data *ext_pw;
|
||||||
|
|
||||||
struct wpabuf *last_gas_resp;
|
struct wpabuf *last_gas_resp, *prev_gas_resp;
|
||||||
u8 last_gas_addr[ETH_ALEN];
|
u8 last_gas_addr[ETH_ALEN], prev_gas_addr[ETH_ALEN];
|
||||||
u8 last_gas_dialog_token;
|
u8 last_gas_dialog_token, prev_gas_dialog_token;
|
||||||
|
|
||||||
unsigned int no_keep_alive:1;
|
unsigned int no_keep_alive:1;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue