From 223167956cee676fae65de5a4cbd7fb6aa0482ca Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Thu, 23 Aug 2012 23:56:51 +0300 Subject: [PATCH] Improve p2p_client_list updates in configuration file This list can get truncated due to too many addresses getting added. Reorder the entries in a way that allows the most recently added values to be maintained in the list and use better debug/error messages when parsing the value. Signed-hostap: Jouni Malinen intended-for: hostap-1 --- wpa_supplicant/config.c | 23 ++++++++++++++++------- wpa_supplicant/p2p_supplicant.c | 33 ++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 163a6182a..cecf648d2 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -1376,10 +1376,18 @@ static int wpa_config_parse_p2p_client_list(const struct parse_data *data, pos++; if (hwaddr_aton(pos, addr)) { - wpa_printf(MSG_ERROR, "Line %d: Invalid " - "p2p_client_list address '%s'.", - line, value); - /* continue anyway */ + if (count == 0) { + wpa_printf(MSG_ERROR, "Line %d: Invalid " + "p2p_client_list address '%s'.", + line, value); + os_free(buf); + return -1; + } + /* continue anyway since this could have been from a + * truncated configuration file line */ + wpa_printf(MSG_INFO, "Line %d: Ignore likely " + "truncated p2p_client_list address '%s'", + line, pos); } else { n = os_realloc_array(buf, count + 1, ETH_ALEN); if (n == NULL) { @@ -1387,7 +1395,8 @@ static int wpa_config_parse_p2p_client_list(const struct parse_data *data, return -1; } buf = n; - os_memcpy(buf + count * ETH_ALEN, addr, ETH_ALEN); + os_memmove(buf + ETH_ALEN, buf, count * ETH_ALEN); + os_memcpy(buf, addr, ETH_ALEN); count++; wpa_hexdump(MSG_MSGDUMP, "p2p_client_list", addr, ETH_ALEN); @@ -1421,10 +1430,10 @@ static char * wpa_config_write_p2p_client_list(const struct parse_data *data, pos = value; end = value + 20 * ssid->num_p2p_clients; - for (i = 0; i < ssid->num_p2p_clients; i++) { + for (i = ssid->num_p2p_clients; i > 0; i--) { res = os_snprintf(pos, end - pos, MACSTR " ", MAC2STR(ssid->p2p_client_list + - i * ETH_ALEN)); + (i - 1) * ETH_ALEN)); if (res < 0 || res >= end - pos) { os_free(value); return NULL; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index b47cf66a4..cf4b3f21b 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -523,6 +523,7 @@ static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, *s; u8 *n; size_t i; + int found = 0; ssid = wpa_s->current_ssid; if (ssid == NULL || ssid->mode != WPAS_MODE_P2P_GO || @@ -543,17 +544,31 @@ static void wpas_p2p_add_persistent_group_client(struct wpa_supplicant *wpa_s, for (i = 0; s->p2p_client_list && i < s->num_p2p_clients; i++) { if (os_memcmp(s->p2p_client_list + i * ETH_ALEN, addr, - ETH_ALEN) == 0) - return; /* already in list */ + ETH_ALEN) != 0) + continue; + + if (i == s->num_p2p_clients - 1) + return; /* already the most recent entry */ + + /* move the entry to mark it most recent */ + os_memmove(s->p2p_client_list + i * ETH_ALEN, + s->p2p_client_list + (i + 1) * ETH_ALEN, + (s->num_p2p_clients - i - 1) * ETH_ALEN); + os_memcpy(s->p2p_client_list + + (s->num_p2p_clients - 1) * ETH_ALEN, addr, ETH_ALEN); + found = 1; + break; } - n = os_realloc_array(s->p2p_client_list, s->num_p2p_clients + 1, - ETH_ALEN); - if (n == NULL) - return; - os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN); - s->p2p_client_list = n; - s->num_p2p_clients++; + if (!found) { + n = os_realloc_array(s->p2p_client_list, + s->num_p2p_clients + 1, ETH_ALEN); + if (n == NULL) + return; + os_memcpy(n + s->num_p2p_clients * ETH_ALEN, addr, ETH_ALEN); + s->p2p_client_list = n; + s->num_p2p_clients++; + } #ifndef CONFIG_NO_CONFIG_WRITE if (wpa_s->parent->conf->update_config &&