Browse Source

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 <jouni@qca.qualcomm.com>
intended-for: hostap-1
Jouni Malinen 12 years ago
parent
commit
223167956c
2 changed files with 40 additions and 16 deletions
  1. 16 7
      wpa_supplicant/config.c
  2. 24 9
      wpa_supplicant/p2p_supplicant.c

+ 16 - 7
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;

+ 24 - 9
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 &&