aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant/bss.c
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2012-07-19 12:16:46 -0700
committerDmitry Shmidt <dimitrysh@google.com>2012-07-19 16:03:19 -0700
commit04949598a23f501be6eec21697465fd46a28840a (patch)
tree6eb315b8d139b0690cb644dc914c53bacb42df42 /wpa_supplicant/bss.c
parentce1e0634ed741293de60d5ba3476b26ccbd58ce2 (diff)
downloadexternal_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.zip
external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.tar.gz
external_wpa_supplicant_8-04949598a23f501be6eec21697465fd46a28840a.tar.bz2
wpa_supplicant: Update to 07-Jul-2012 TOT
commit a5ed45586c63ffd8f9d2b44e27c251d7bacbeaf4 Author: Jouni Malinen <j@w1.fi> Date: Sat Jul 7 13:01:45 2012 +0300 WPS SSDP: Fix socket leaks on error paths Change-Id: I0864aac7fc88fa2a60f5cca7d524b94363410c85 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'wpa_supplicant/bss.c')
-rw-r--r--wpa_supplicant/bss.c87
1 files changed, 60 insertions, 27 deletions
diff --git a/wpa_supplicant/bss.c b/wpa_supplicant/bss.c
index cbed2e0..580a82a 100644
--- a/wpa_supplicant/bss.c
+++ b/wpa_supplicant/bss.c
@@ -35,14 +35,15 @@
#define WPA_BSS_IES_CHANGED_FLAG BIT(8)
-static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
+ const char *reason)
{
dl_list_del(&bss->list);
dl_list_del(&bss->list_id);
wpa_s->num_bss--;
wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Remove id %u BSSID " MACSTR
- " SSID '%s'", bss->id, MAC2STR(bss->bssid),
- wpa_ssid_txt(bss->ssid, bss->ssid_len));
+ " SSID '%s' due to %s", bss->id, MAC2STR(bss->bssid),
+ wpa_ssid_txt(bss->ssid, bss->ssid_len), reason);
wpas_notify_bss_removed(wpa_s, bss->bssid, bss->id);
#ifdef CONFIG_INTERWORKING
wpabuf_free(bss->anqp_venue_name);
@@ -53,6 +54,12 @@ static void wpa_bss_remove(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
wpabuf_free(bss->anqp_3gpp);
wpabuf_free(bss->anqp_domain_name);
#endif /* CONFIG_INTERWORKING */
+#ifdef CONFIG_HS20
+ wpabuf_free(bss->hs20_operator_friendly_name);
+ wpabuf_free(bss->hs20_wan_metrics);
+ wpabuf_free(bss->hs20_connection_capability);
+ wpabuf_free(bss->hs20_operating_class);
+#endif /* CONFIG_HS20 */
os_free(bss);
}
@@ -61,6 +68,8 @@ struct wpa_bss * wpa_bss_get(struct wpa_supplicant *wpa_s, const u8 *bssid,
const u8 *ssid, size_t ssid_len)
{
struct wpa_bss *bss;
+ if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
+ return NULL;
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0 &&
bss->ssid_len == ssid_len &&
@@ -112,13 +121,21 @@ static int wpa_bss_known(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
}
+static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
+{
+ return bss == wpa_s->current_bss ||
+ os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 ||
+ os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0;
+}
+
+
static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
{
struct wpa_bss *bss;
dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
if (!wpa_bss_known(wpa_s, bss)) {
- wpa_bss_remove(wpa_s, bss);
+ wpa_bss_remove(wpa_s, bss, __func__);
return 0;
}
}
@@ -127,21 +144,28 @@ static int wpa_bss_remove_oldest_unknown(struct wpa_supplicant *wpa_s)
}
-static void wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
+static int wpa_bss_remove_oldest(struct wpa_supplicant *wpa_s)
{
+ struct wpa_bss *bss;
+
/*
* Remove the oldest entry that does not match with any configured
* network.
*/
if (wpa_bss_remove_oldest_unknown(wpa_s) == 0)
- return;
+ return 0;
/*
- * Remove the oldest entry since no better candidate for removal was
- * found.
+ * Remove the oldest entry that isn't currently in use.
*/
- wpa_bss_remove(wpa_s, dl_list_first(&wpa_s->bss,
- struct wpa_bss, list));
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+ if (!wpa_bss_in_use(wpa_s, bss)) {
+ wpa_bss_remove(wpa_s, bss, __func__);
+ return 0;
+ }
+ }
+
+ return -1;
}
@@ -170,8 +194,13 @@ static void wpa_bss_add(struct wpa_supplicant *wpa_s,
" SSID '%s'",
bss->id, MAC2STR(bss->bssid), wpa_ssid_txt(ssid, ssid_len));
wpas_notify_bss_added(wpa_s, bss->bssid, bss->id);
- if (wpa_s->num_bss > wpa_s->conf->bss_max_count)
- wpa_bss_remove_oldest(wpa_s);
+ if (wpa_s->num_bss > wpa_s->conf->bss_max_count &&
+ wpa_bss_remove_oldest(wpa_s) != 0) {
+ wpa_printf(MSG_ERROR, "Increasing the MAX BSS count to %d "
+ "because all BSSes are in use. We should normally "
+ "not get here!", (int) wpa_s->num_bss);
+ wpa_s->conf->bss_max_count = wpa_s->num_bss;
+ }
}
@@ -326,6 +355,8 @@ static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
nbss = os_realloc(bss, sizeof(*bss) + res->ie_len +
res->beacon_ie_len);
if (nbss) {
+ if (wpa_s->current_bss == bss)
+ wpa_s->current_bss = nbss;
bss = nbss;
os_memcpy(bss + 1, res + 1,
res->ie_len + res->beacon_ie_len);
@@ -340,14 +371,6 @@ static void wpa_bss_update(struct wpa_supplicant *wpa_s, struct wpa_bss *bss,
}
-static int wpa_bss_in_use(struct wpa_supplicant *wpa_s, struct wpa_bss *bss)
-{
- return bss == wpa_s->current_bss ||
- os_memcmp(bss->bssid, wpa_s->bssid, ETH_ALEN) == 0 ||
- os_memcmp(bss->bssid, wpa_s->pending_bssid, ETH_ALEN) == 0;
-}
-
-
void wpa_bss_update_start(struct wpa_supplicant *wpa_s)
{
wpa_s->bss_update_idx++;
@@ -375,6 +398,18 @@ void wpa_bss_update_scan_res(struct wpa_supplicant *wpa_s,
}
p2p = wpa_scan_get_vendor_ie(res, P2P_IE_VENDOR_TYPE);
+#ifdef CONFIG_P2P
+ if (p2p == NULL &&
+ wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) {
+ /*
+ * If it's a P2P specific interface, then don't update
+ * the scan result without a P2P IE.
+ */
+ wpa_printf(MSG_DEBUG, "BSS: No P2P IE - skipping BSS " MACSTR
+ " update for P2P interface", MAC2STR(res->bssid));
+ return;
+ }
+#endif /* CONFIG_P2P */
if (p2p && ssid[1] == P2P_WILDCARD_SSID_LEN &&
os_memcmp(ssid + 2, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN) == 0)
return; /* Skip P2P listen discovery results here */
@@ -447,9 +482,7 @@ void wpa_bss_update_end(struct wpa_supplicant *wpa_s, struct scan_info *info,
bss->scan_miss_count++;
if (bss->scan_miss_count >=
wpa_s->conf->bss_expiration_scan_count) {
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Expire BSS %u due to "
- "no match in scan", bss->id);
- wpa_bss_remove(wpa_s, bss);
+ wpa_bss_remove(wpa_s, bss, "no match in scan");
}
}
}
@@ -471,9 +504,7 @@ void wpa_bss_flush_by_age(struct wpa_supplicant *wpa_s, int age)
continue;
if (os_time_before(&bss->last_update, &t)) {
- wpa_dbg(wpa_s, MSG_DEBUG, "BSS: Expire BSS %u due to "
- "age", bss->id);
- wpa_bss_remove(wpa_s, bss);
+ wpa_bss_remove(wpa_s, bss, __func__);
} else
break;
}
@@ -510,7 +541,7 @@ void wpa_bss_flush(struct wpa_supplicant *wpa_s)
dl_list_for_each_safe(bss, n, &wpa_s->bss, struct wpa_bss, list) {
if (wpa_bss_in_use(wpa_s, bss))
continue;
- wpa_bss_remove(wpa_s, bss);
+ wpa_bss_remove(wpa_s, bss, __func__);
}
}
@@ -526,6 +557,8 @@ struct wpa_bss * wpa_bss_get_bssid(struct wpa_supplicant *wpa_s,
const u8 *bssid)
{
struct wpa_bss *bss;
+ if (!wpa_supplicant_filter_bssid_match(wpa_s, bssid))
+ return NULL;
dl_list_for_each_reverse(bss, &wpa_s->bss, struct wpa_bss, list) {
if (os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0)
return bss;