rpms/wpa_supplicant/F-10 wpa_supplicant-0.6.7-really-disassoc.patch, NONE, 1.1 wpa_supplicant-0.6.8-ap-stability.patch, NONE, 1.1 wpa_supplicant-0.6.8-disconnect-init-deinit.patch, NONE, 1.1 wpa_supplicant-0.6.8-handle-driver-disconnect-spam.patch, NONE, 1.1 wpa_supplicant.spec, 1.50, 1.51

Daniel Williams dcbw at fedoraproject.org
Tue May 12 19:49:20 UTC 2009


Author: dcbw

Update of /cvs/extras/rpms/wpa_supplicant/F-10
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv2635

Modified Files:
	wpa_supplicant.spec 
Added Files:
	wpa_supplicant-0.6.7-really-disassoc.patch 
	wpa_supplicant-0.6.8-ap-stability.patch 
	wpa_supplicant-0.6.8-disconnect-init-deinit.patch 
	wpa_supplicant-0.6.8-handle-driver-disconnect-spam.patch 
Log Message:
* Tue May 12 2009 Dan Williams <dcbw at redhat.com> - 1:0.6.4-4
- Ensure that drivers don't retry association when they aren't supposed to
- Ensure the supplicant starts and ends with clean driver state
- Handle driver disconnect spammage by forcibly clearing SSID
- Don't switch access points unless the current association is dire (rh #493745)



wpa_supplicant-0.6.7-really-disassoc.patch:

--- NEW FILE wpa_supplicant-0.6.7-really-disassoc.patch ---
diff -up wpa_supplicant-0.6.4/src/drivers/driver_wext.c.really-disassoc wpa_supplicant-0.6.4/src/drivers/driver_wext.c
--- wpa_supplicant-0.6.4/src/drivers/driver_wext.c.really-disassoc	2009-05-12 12:25:08.000000000 -0400
+++ wpa_supplicant-0.6.4/src/drivers/driver_wext.c	2009-05-12 12:47:08.000000000 -0400
@@ -2069,13 +2069,49 @@ static int wpa_driver_wext_mlme(struct w
 	return ret;
 }
 
+static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
+{
+	struct iwreq iwr;
+	const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
+	u8 ssid[32];
+	int i;
+
+	/* Only force-disconnect when the card is in infrastructure mode,
+	 * otherwise the driver might interpret the cleared BSSID and random
+	 * SSID as an attempt to create a new ad-hoc network.
+	 */
+	os_memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+	if (ioctl(drv->ioctl_sock, SIOCGIWMODE, &iwr) < 0) {
+		perror("ioctl[SIOCGIWMODE]");
+		iwr.u.mode = IW_MODE_INFRA;
+	}
+
+	if (iwr.u.mode == IW_MODE_INFRA) {
+		/*
+		 * Clear the BSSID selection and set a random SSID to make sure
+		 * the driver will not be trying to associate with something
+		 * even if it does not understand SIOCSIWMLME commands (or tries
+		 * to associate automatically after deauth/disassoc).
+		 */
+		wpa_driver_wext_set_bssid(drv, null_bssid);
+
+		for (i = 0; i < 32; i++)
+			ssid[i] = rand() & 0xFF;
+		wpa_driver_wext_set_ssid(drv, ssid, 32);
+	}
+}
 
 static int wpa_driver_wext_deauthenticate(void *priv, const u8 *addr,
 					  int reason_code)
 {
 	struct wpa_driver_wext_data *drv = priv;
+	int ret;
+
 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-	return wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
+	ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DEAUTH, reason_code);
+	wpa_driver_wext_disconnect(drv);
+	return ret;
 }
 
 
@@ -2083,9 +2119,12 @@ static int wpa_driver_wext_disassociate(
 					int reason_code)
 {
 	struct wpa_driver_wext_data *drv = priv;
+	int ret;
+
 	wpa_printf(MSG_DEBUG, "%s", __FUNCTION__);
-	return wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC,
-				    reason_code);
+	ret = wpa_driver_wext_mlme(drv, addr, IW_MLME_DISASSOC, reason_code);
+	wpa_driver_wext_disconnect(drv);
+	return ret;
 }
 
 

wpa_supplicant-0.6.8-ap-stability.patch:

--- NEW FILE wpa_supplicant-0.6.8-ap-stability.patch ---
diff -up wpa_supplicant-0.6.4/src/drivers/driver.h.ap-bouncing wpa_supplicant-0.6.4/src/drivers/driver.h
--- wpa_supplicant-0.6.4/src/drivers/driver.h.ap-bouncing	2009-05-12 15:32:40.000000000 -0400
+++ wpa_supplicant-0.6.4/src/drivers/driver.h	2009-05-12 15:33:51.000000000 -0400
@@ -943,6 +943,21 @@ struct wpa_driver_ops {
 	 * Returns: 0 on success, -1 on failure
 	 */
 	int (*set_mode)(void *priv, int mode);
+
+ 	/**
+	 * get_signal_quality - Request signal quality of the current association
+	 * @priv: private driver interface data
+	 * @qual: signal "quality", perhaps including TX errors, missed beacons,
+	 *        etc.  If not provided, set to 0.
+	 * @max_qual: maximum possible signal quality.  If not provided set to 0.
+	 *
+	 * This handler may be called at any time to retrieve the signal quality
+	 * of the current association.  If there is no association, the handler
+	 * must return -1.  If the signal level isn't known or is not provided,
+	 * the handler must return -1.
+	 * Returns: 0 on success, -1 on failure
+	 */
+	int (*get_signal_quality)(void *priv, int *qual, int *max_qual);
 };
 
 /**
diff -up wpa_supplicant-0.6.4/src/drivers/driver_wext.c.ap-bouncing wpa_supplicant-0.6.4/src/drivers/driver_wext.c
--- wpa_supplicant-0.6.4/src/drivers/driver_wext.c.ap-bouncing	2009-05-12 15:32:40.000000000 -0400
+++ wpa_supplicant-0.6.4/src/drivers/driver_wext.c	2009-05-12 15:36:14.000000000 -0400
@@ -1785,6 +1785,10 @@ static int wpa_driver_wext_get_range(voi
 		if (range->enc_capa & IW_ENC_CAPA_4WAY_HANDSHAKE)
 			drv->capa.flags |= WPA_DRIVER_FLAGS_4WAY_HANDSHAKE;
 
+		drv->max_qual.qual = range->max_qual.qual;
+		drv->max_qual.level = range->max_qual.level;
+		drv->max_qual.updated = range->max_qual.updated;
+
 		wpa_printf(MSG_DEBUG, "  capabilities: key_mgmt 0x%x enc 0x%x "
 			   "flags 0x%x",
 			   drv->capa.key_mgmt, drv->capa.enc, drv->capa.flags);
@@ -2418,6 +2422,51 @@ done:
 }
 
 
+/**
+ * wpa_driver_wext_get_signal_quality - Get wireless signal quality, SIOCSIWSTATS
+ * @priv: Pointer to private wext data from wpa_driver_wext_init()
+ * @qual: signal quality
+ * @max_qual: maximum signal quality
+ * Returns: 0 on success, -1 on failure
+ */
+int wpa_driver_wext_get_signal_quality(void *priv, int *qual, int *max_qual)
+{
+	struct wpa_driver_wext_data *drv = priv;
+	struct iwreq iwr;
+	struct iw_statistics stats;
+	s8 level = 0;
+
+	os_memset(&iwr, 0, sizeof(iwr));
+	os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
+
+	memset (&stats, 0, sizeof (stats));
+	iwr.u.data.pointer = &stats;
+	iwr.u.data.length = sizeof (stats);
+	iwr.u.data.flags = 1;		/* Clear updated flag */
+
+	if (ioctl(drv->ioctl_sock, SIOCGIWSTATS, &iwr)) {
+		wpa_printf(MSG_DEBUG, "%s: IWSTATS returned error: %d",
+		           __FUNCTION__, errno);
+		return -1;
+	}
+
+	if (   !(drv->max_qual.updated & IW_QUAL_LEVEL_INVALID)
+	    && !(stats.qual.updated & IW_QUAL_LEVEL_INVALID)) {
+		level = stats.qual.level;
+	}
+
+	if (   !(drv->max_qual.updated & IW_QUAL_QUAL_INVALID)
+	    && !(stats.qual.updated & IW_QUAL_QUAL_INVALID)) {
+		*qual = stats.qual.qual;
+		*max_qual = drv->max_qual.qual;
+	}
+
+	wpa_printf(MSG_DEBUG, "%s: level %d (%d), qual %d (%d)", __FUNCTION__,
+	           level, drv->max_qual.level, *qual, drv->max_qual.qual);
+	return 0;
+}
+
+
 static int wpa_driver_wext_pmksa(struct wpa_driver_wext_data *drv,
 				 u32 cmd, const u8 *bssid, const u8 *pmkid)
 {
@@ -2829,6 +2878,7 @@ const struct wpa_driver_ops wpa_driver_w
 	.deauthenticate = wpa_driver_wext_deauthenticate,
 	.disassociate = wpa_driver_wext_disassociate,
 	.set_mode = wpa_driver_wext_set_mode,
+	.get_signal_quality = wpa_driver_wext_get_signal_quality,
 	.associate = wpa_driver_wext_associate,
 	.set_auth_alg = wpa_driver_wext_set_auth_alg,
 	.init = wpa_driver_wext_init,
diff -up wpa_supplicant-0.6.4/src/drivers/driver_wext.h.ap-bouncing wpa_supplicant-0.6.4/src/drivers/driver_wext.h
--- wpa_supplicant-0.6.4/src/drivers/driver_wext.h.ap-bouncing	2008-08-10 13:33:12.000000000 -0400
+++ wpa_supplicant-0.6.4/src/drivers/driver_wext.h	2009-05-12 15:32:40.000000000 -0400
@@ -16,6 +16,7 @@
 #define DRIVER_WEXT_H
 
 #include <net/if.h>
+#include "wireless.h"
 
 struct wpa_driver_wext_data {
 	void *ctx;
@@ -43,6 +44,8 @@ struct wpa_driver_wext_data {
 	char mlmedev[IFNAMSIZ + 1];
 
 	int scan_complete_events;
+
+	struct iw_quality max_qual;
 };
 
 int wpa_driver_wext_get_ifflags(struct wpa_driver_wext_data *drv, int *flags);
diff -up wpa_supplicant-0.6.4/wpa_supplicant/events.c.ap-bouncing wpa_supplicant-0.6.4/wpa_supplicant/events.c
--- wpa_supplicant-0.6.4/wpa_supplicant/events.c.ap-bouncing	2009-05-12 15:32:40.000000000 -0400
+++ wpa_supplicant-0.6.4/wpa_supplicant/events.c	2009-05-12 15:41:04.000000000 -0400
@@ -363,9 +363,58 @@ static int wpa_supplicant_ssid_bss_match
 	return 0;
 }
 
+struct cur_ap {
+	int bssid_valid;
+	u8 bssid[ETH_ALEN];
+	int qual;
+	int max_qual;
+};
+
+#define CUR_AP_THRESHOLD 50
+
+/* Return 1 if 'bss' should be used instead of the current association */
+static int
+bss_better_quality(struct wpa_scan_res *bss, struct cur_ap *cur)
+{
+	int cur_pqual, bss_pqual;
+
+	/* If there was no current association then 'bss' is better than nothing */
+	if (!cur->bssid_valid) {
+		wpa_printf(MSG_DEBUG, "   no current BSSID");
+		return 1;
+	}
+
+	/* If the max quality is invalid, quality is pretty meaningless */
+	if (!cur->max_qual) {
+		wpa_printf(MSG_DEBUG, "   no max quality");
+		return 1;
+	}
+
+	cur_pqual = (int) (((float) cur->qual / (float) cur->max_qual) * 100);
+	bss_pqual = (int) (((float) bss->qual / (float) cur->max_qual) * 100);
+
+	/* If 'bss' is the current associated BSS and it's still got OK quality,
+	 * stick with it.
+	 */
+	if (!os_memcmp(cur->bssid, bss->bssid, ETH_ALEN) && (cur_pqual >= CUR_AP_THRESHOLD)) {
+		wpa_printf(MSG_DEBUG, "   matched associated BSSID");
+		return 1;
+	}
+
+	wpa_printf(MSG_DEBUG, "     cur AP qual: %d  candidate qual: %d", cur_pqual, bss_pqual);
+
+	/* Otherwise if the current association is worse than 50% quality and
+	 * 'bss' is at least 15% better, then use 'bss'.
+	 */
+	if ((cur_pqual < CUR_AP_THRESHOLD) && (bss_pqual >= cur_pqual + 15))
+		return 1;
+
+	return 0;
+}
 
 static struct wpa_scan_res *
 wpa_supplicant_select_bss(struct wpa_supplicant *wpa_s, struct wpa_ssid *group,
+			  int use_qual, struct cur_ap *cur,
 			  struct wpa_ssid **selected_ssid)
 {
 	struct wpa_ssid *ssid;
@@ -373,10 +422,29 @@ wpa_supplicant_select_bss(struct wpa_sup
 	size_t i;
 	struct wpa_blacklist *e;
 	const u8 *ie;
+	int have_cur = 0;
 
 	wpa_printf(MSG_DEBUG, "Selecting BSS from priority group %d",
 		   group->priority);
 
+	if (cur->bssid_valid) {
+		wpa_printf(MSG_DEBUG, "Try to find current BSSID "
+		           "%02x:%02x:%02x:%02x:%02x:%02x",
+		           cur->bssid[0], cur->bssid[1], cur->bssid[2],
+		           cur->bssid[3], cur->bssid[4], cur->bssid[5]);
+		for (i = 0; i < wpa_s->scan_res->num; i++) {
+			bss = wpa_s->scan_res->res[i];
+			if (os_memcmp(bss->bssid, cur->bssid, ETH_ALEN) != 0) {
+				wpa_printf(MSG_DEBUG, "   skip - "
+					   "BSSID mismatch");
+				continue;
+			}
+			wpa_printf(MSG_DEBUG, "   found");
+			have_cur = 1;
+			break;
+		}
+	}
+
 	bss = NULL;
 	ssid = NULL;
 	/* First, try to find WPA-enabled AP */
@@ -431,6 +499,14 @@ wpa_supplicant_select_bss(struct wpa_sup
 				continue;
 			}
 			if (wpa_supplicant_ssid_bss_match(ssid, bss)) {
+				if (use_qual && have_cur) {
+					if (!bss_better_quality(bss, cur)) {
+						wpa_printf(MSG_DEBUG, "   skip - "
+							   "signal strength not high enough");
+						continue;
+					}
+				}
+
 				selected = bss;
 				*selected_ssid = ssid;
 				wpa_printf(MSG_DEBUG, "   selected WPA AP "
@@ -519,6 +595,14 @@ wpa_supplicant_select_bss(struct wpa_sup
 				continue;
 			}
 
+			if (use_qual && have_cur) {
+				if (!bss_better_quality(bss, cur)) {
+					wpa_printf(MSG_DEBUG, "   skip - "
+						   "signal strength not high enough");
+					continue;
+				}
+			}
+
 			selected = bss;
 			*selected_ssid = ssid;
 			wpa_printf(MSG_DEBUG, "   selected non-WPA AP "
@@ -538,6 +622,9 @@ static void wpa_supplicant_event_scan_re
 	int prio, timeout;
 	struct wpa_scan_res *selected = NULL;
 	struct wpa_ssid *ssid = NULL;
+	int qual = 0, max_qual = 0, qual_valid = 0;
+	struct cur_ap cur;
+	int i;
 
 	if (wpa_supplicant_get_scan_results(wpa_s) < 0) {
 		if (wpa_s->conf->ap_scan == 2)
@@ -564,10 +651,42 @@ static void wpa_supplicant_event_scan_re
 	if (wpa_s->conf->ap_scan == 2 || wpa_s->disconnected)
 		return;
 
+	/* Get current driver BSSID and signal strength */
+	os_memset(&cur, 0, sizeof(cur));
+
+	for (i = 0; i < 4 && !cur.bssid_valid; i++) {
+		static u8 bad1[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+		static u8 bad2[ETH_ALEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+		static u8 bad3[ETH_ALEN] = {0x44, 0x44, 0x44, 0x44, 0x44, 0x44};
+
+		if (wpa_drv_get_bssid(wpa_s, (u8 *) &cur.bssid))
+			continue;
+
+		if (!memcmp(cur.bssid, bad1, ETH_ALEN) ||
+		    !memcmp(cur.bssid, bad2, ETH_ALEN) ||
+		    !memcmp(cur.bssid, bad3, ETH_ALEN))
+			continue;
+
+		cur.bssid_valid = 1;
+	}
+
+	for (i = 0; i < 4 && !qual_valid; i++) {
+		qual_valid = !wpa_drv_get_signal_quality(wpa_s, &qual, &max_qual);
+		if (qual_valid && qual)
+			break;
+		qual = max_qual = 0;
+	}
+	cur.qual = qual;
+	cur.max_qual = max_qual;
+
+	wpa_printf(MSG_DEBUG, "%s: qual %d (%d)  qual_valid %d",
+		   __FUNCTION__, qual, max_qual, qual_valid);
+
 	while (selected == NULL) {
 		for (prio = 0; prio < wpa_s->conf->num_prio; prio++) {
 			selected = wpa_supplicant_select_bss(
-				wpa_s, wpa_s->conf->pssid[prio], &ssid);
+				wpa_s, wpa_s->conf->pssid[prio],
+				qual_valid, &cur, &ssid);
 			if (selected)
 				break;
 		}
diff -up wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h.ap-bouncing wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h
--- wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h.ap-bouncing	2009-05-12 15:32:40.000000000 -0400
+++ wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h	2009-05-12 15:38:52.000000000 -0400
@@ -459,6 +459,15 @@ static inline int wpa_drv_set_mode(struc
 	return 0;
 }
 
+static inline int wpa_drv_get_signal_quality(struct wpa_supplicant *wpa_s,
+	int *qual, int *max_qual)
+{
+	if (wpa_s->driver->get_signal_quality) {
+		return wpa_s->driver->get_signal_quality(wpa_s->drv_priv, qual, max_qual);
+	}
+	return -1;
+}
+
 static inline int wpa_drv_associate(struct wpa_supplicant *wpa_s,
 				    struct wpa_driver_associate_params *params)
 {

wpa_supplicant-0.6.8-disconnect-init-deinit.patch:

--- NEW FILE wpa_supplicant-0.6.8-disconnect-init-deinit.patch ---
diff -up wpa_supplicant-0.6.4/src/drivers/driver_wext.c.disconnect-on-init wpa_supplicant-0.6.4/src/drivers/driver_wext.c
--- wpa_supplicant-0.6.4/src/drivers/driver_wext.c.disconnect-on-init	2009-05-12 14:38:30.000000000 -0400
+++ wpa_supplicant-0.6.4/src/drivers/driver_wext.c	2009-05-12 15:00:09.000000000 -0400
@@ -155,6 +155,7 @@ enum {
 static int wpa_driver_wext_flush_pmkid(void *priv);
 static int wpa_driver_wext_get_range(void *priv);
 static void wpa_driver_wext_finish_drv_init(struct wpa_driver_wext_data *drv);
+static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv);
 
 
 static int wpa_driver_wext_send_oper_ifla(struct wpa_driver_wext_data *drv,
@@ -1142,6 +1143,12 @@ static void wpa_driver_wext_finish_drv_i
 
 	wpa_driver_wext_get_range(drv);
 
+	/* Unlock the driver's BSSID and force to a random SSID so clear any
+	 * previous association the driver might have when the supplicant starts
+	 * up.
+	 */
+	wpa_driver_wext_disconnect(drv);
+
 	drv->ifindex = if_nametoindex(drv->ifname);
 
 	if (os_strncmp(drv->ifname, "wlan", 4) == 0) {
@@ -1181,8 +1188,7 @@ void wpa_driver_wext_deinit(void *priv)
 	 * Clear possibly configured driver parameters in order to make it
 	 * easier to use the driver after wpa_supplicant has been terminated.
 	 */
-	(void) wpa_driver_wext_set_bssid(drv,
-					 (u8 *) "\x00\x00\x00\x00\x00\x00");
+	wpa_driver_wext_disconnect(drv);
 
 	wpa_driver_wext_send_oper_ifla(priv, 0, IF_OPER_UP);
 
@@ -2072,7 +2078,6 @@ static int wpa_driver_wext_mlme(struct w
 static void wpa_driver_wext_disconnect(struct wpa_driver_wext_data *drv)
 {
 	struct iwreq iwr;
-	const u8 null_bssid[ETH_ALEN] = { 0, 0, 0, 0, 0, 0 };
 	u8 ssid[32];
 	int i;
 
@@ -2094,7 +2099,8 @@ static void wpa_driver_wext_disconnect(s
 		 * even if it does not understand SIOCSIWMLME commands (or tries
 		 * to associate automatically after deauth/disassoc).
 		 */
-		wpa_driver_wext_set_bssid(drv, null_bssid);
+		(void) wpa_driver_wext_set_bssid(drv,
+					     (u8 *) "\x00\x00\x00\x00\x00\x00");
 
 		for (i = 0; i < 32; i++)
 			ssid[i] = rand() & 0xFF;

wpa_supplicant-0.6.8-handle-driver-disconnect-spam.patch:

--- NEW FILE wpa_supplicant-0.6.8-handle-driver-disconnect-spam.patch ---
diff -up wpa_supplicant-0.6.4/wpa_supplicant/events.c.disassoc-stream wpa_supplicant-0.6.4/wpa_supplicant/events.c
--- wpa_supplicant-0.6.4/wpa_supplicant/events.c.disassoc-stream	2009-04-16 15:08:23.000000000 -0400
+++ wpa_supplicant-0.6.4/wpa_supplicant/events.c	2009-04-16 15:44:14.000000000 -0400
@@ -941,6 +941,15 @@ static void wpa_supplicant_event_disasso
 		wpa_s->keys_cleared = 0;
 		wpa_clear_keys(wpa_s, wpa_s->bssid);
 	}
+
+	if (wpa_s->wpa_state == WPA_DISCONNECTED) {
+		wpa_s->disconnect_count++;
+		if (!eloop_is_timeout_registered(wpa_disconnect_spam_handle, wpa_s, NULL)) {
+			eloop_register_timeout(6, 0, wpa_disconnect_spam_handle, wpa_s, NULL);
+			wpa_printf(MSG_DEBUG, "%s: scheduled DISCONNECT spam handler", __FUNCTION__);
+		}
+	}
+
 	wpa_supplicant_mark_disassoc(wpa_s);
 }
 
diff -up wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant.c.disassoc-stream wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant.c
--- wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant.c.disassoc-stream	2009-04-16 15:27:23.000000000 -0400
+++ wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant.c	2009-04-16 15:44:21.000000000 -0400
@@ -460,6 +460,23 @@ const char * wpa_supplicant_state_txt(in
 }
 
 
+void wpa_disconnect_spam_handle(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	const u8 bssid[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+	wpa_printf(MSG_DEBUG, "%s: %d disconnect events in 6 seconds",
+		   __FUNCTION__, wpa_s->disconnect_count);
+
+	if (wpa_s->disconnect_count >= 3) {
+		wpa_printf(MSG_DEBUG, "%s: forcing SSID/BSSID reset", __FUNCTION__);
+		wpa_drv_disassociate(wpa_s, bssid, WLAN_REASON_DEAUTH_LEAVING);
+		wpa_supplicant_req_scan(wpa_s, 1, 0);
+	}
+	wpa_s->disconnect_count = 0;
+}
+
+
 /**
  * wpa_supplicant_set_state - Set current connection state
  * @wpa_s: Pointer to wpa_supplicant data
@@ -477,6 +492,18 @@ void wpa_supplicant_set_state(struct wpa
 	wpa_supplicant_dbus_notify_state_change(wpa_s, state,
 						wpa_s->wpa_state);
 
+	if (state != WPA_DISCONNECTED && state != WPA_SCANNING) {
+		/* If the state isn't disconnected, cancel any registered
+		 * disconnect spam handler, which should only live while
+		 * disconnect events are coming in quickly.
+		 */
+		wpa_s->disconnect_count = 0;
+		if (eloop_is_timeout_registered(wpa_disconnect_spam_handle, wpa_s, NULL)) {
+			wpa_printf(MSG_DEBUG, "%s: canceling DISCONNECT spam handler", __FUNCTION__);
+			eloop_cancel_timeout(wpa_disconnect_spam_handle, wpa_s, NULL);
+		}
+	}
+
 	if (state == WPA_COMPLETED && wpa_s->new_connection) {
 #if defined(CONFIG_CTRL_IFACE) || !defined(CONFIG_NO_STDOUT_DEBUG)
 		struct wpa_ssid *ssid = wpa_s->current_ssid;
diff -up wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h.disassoc-stream wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h
--- wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h.disassoc-stream	2009-04-16 15:12:48.000000000 -0400
+++ wpa_supplicant-0.6.4/wpa_supplicant/wpa_supplicant_i.h	2009-04-16 15:26:48.000000000 -0400
@@ -334,6 +334,8 @@ struct wpa_supplicant {
 	struct wpa_client_mlme mlme;
 	int use_client_mlme;
 	int driver_4way_handshake;
+
+	int disconnect_count;
 };
 
 
@@ -357,6 +359,7 @@ void wpa_clear_keys(struct wpa_supplican
 void wpa_supplicant_req_auth_timeout(struct wpa_supplicant *wpa_s,
 				     int sec, int usec);
 void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s, wpa_states state);
+void wpa_disconnect_spam_handle(void *eloop_ctx, void *timeout_ctx);
 struct wpa_ssid * wpa_supplicant_get_ssid(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_deauthenticate(struct wpa_supplicant *wpa_s,


Index: wpa_supplicant.spec
===================================================================
RCS file: /cvs/extras/rpms/wpa_supplicant/F-10/wpa_supplicant.spec,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -p -r1.50 -r1.51
--- wpa_supplicant.spec	30 Jan 2009 17:59:12 -0000	1.50
+++ wpa_supplicant.spec	12 May 2009 19:48:50 -0000	1.51
@@ -2,7 +2,7 @@ Summary: WPA/WPA2/IEEE 802.1X Supplicant
 Name: wpa_supplicant
 Epoch: 1
 Version: 0.6.4
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: BSD
 Group: System Environment/Base
 Source0: http://hostap.epitest.fi/releases/%{name}-%{version}.tar.gz
@@ -24,6 +24,10 @@ Patch8: wpa_supplicant-0.6.4-validate-we
 Patch9: wpa_supplicant-0.6.4-set-mode-handler.patch
 Patch10: wpa_supplicant-0.6.4-fix-peap-with-windows-server-2008.patch
 Patch11: wpa_supplicant-0.6.7-quiet-scan-results-message.patch
+Patch12: wpa_supplicant-0.6.7-really-disassoc.patch
+Patch13: wpa_supplicant-0.6.8-disconnect-init-deinit.patch
+Patch14: wpa_supplicant-0.6.8-handle-driver-disconnect-spam.patch
+Patch15: wpa_supplicant-0.6.8-ap-stability.patch
 
 URL: http://w1.fi/wpa_supplicant/
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -63,6 +67,10 @@ Graphical User Interface for wpa_supplic
 %patch9 -p1 -b .set-mode-handler
 %patch10 -p1 -b .fix-peap-windows-server-2008
 %patch11 -p1 -b .quiet-scan-results-msg
+%patch12 -p1 -b .really-disassoc
+%patch13 -p1 -b .disconnect-init-deinit
+%patch14 -p1 -b .disconnect-spam
+%patch15 -p1 -b .ap-stability
 
 %build
 pushd wpa_supplicant
@@ -153,6 +161,12 @@ fi
 %{_bindir}/wpa_gui
 
 %changelog
+* Tue May 12 2009 Dan Williams <dcbw at redhat.com> - 1:0.6.4-4
+- Ensure that drivers don't retry association when they aren't supposed to
+- Ensure the supplicant starts and ends with clean driver state
+- Handle driver disconnect spammage by forcibly clearing SSID
+- Don't switch access points unless the current association is dire (rh #493745)
+
 * Fri Jan 30 2009 Dan Williams <dcbw at redhat.com> - 1:0.6.4-3
 - Fix PEAP connections to Windows Server 2008 authenticators (rh #465022)
 - Stop supplicant on uninstall (rh #447843)




More information about the scm-commits mailing list