summaryrefslogtreecommitdiff
path: root/source/n/wpa_supplicant/patches/squelch-driver-disconnect-spam.diff
blob: b8d2be6ad3848cb3e08e8351a41a2a5f777e1a63 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
diff -Nur wpa_supplicant-1.0-rc3.orig/wpa_supplicant/events.c wpa_supplicant-1.0-rc3/wpa_supplicant/events.c
--- wpa_supplicant-1.0-rc3.orig/wpa_supplicant/events.c	2012-04-16 15:15:40.000000000 -0500
+++ wpa_supplicant-1.0-rc3/wpa_supplicant/events.c	2012-05-06 01:01:17.529134316 -0500
@@ -1593,6 +1593,15 @@
 		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);
 
 	if (authenticating && (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME))
diff -Nur wpa_supplicant-1.0-rc3.orig/wpa_supplicant/wpa_supplicant.c wpa_supplicant-1.0-rc3/wpa_supplicant/wpa_supplicant.c
--- wpa_supplicant-1.0-rc3.orig/wpa_supplicant/wpa_supplicant.c	2012-04-16 15:15:40.000000000 -0500
+++ wpa_supplicant-1.0-rc3/wpa_supplicant/wpa_supplicant.c	2012-05-06 01:01:17.530134303 -0500
@@ -434,6 +434,9 @@
 
 	wpa_supplicant_cancel_scan(wpa_s);
 	wpa_supplicant_cancel_auth_timeout(wpa_s);
+	if (eloop_is_timeout_registered(wpa_disconnect_spam_handle, wpa_s, NULL))
+		eloop_cancel_timeout(wpa_disconnect_spam_handle, wpa_s, NULL);
+
 	eloop_cancel_timeout(wpa_supplicant_stop_countermeasures, wpa_s, NULL);
 #ifdef CONFIG_DELAYED_MIC_ERROR_REPORT
 	eloop_cancel_timeout(wpa_supplicant_delayed_mic_error_report,
@@ -592,6 +595,23 @@
 #endif /* CONFIG_BGSCAN */
 
 
+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
@@ -612,6 +632,18 @@
 	if (state != WPA_SCANNING)
 		wpa_supplicant_notify_scanning(wpa_s, 0);
 
+	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 -Nur wpa_supplicant-1.0-rc3.orig/wpa_supplicant/wpa_supplicant_i.h wpa_supplicant-1.0-rc3/wpa_supplicant/wpa_supplicant_i.h
--- wpa_supplicant-1.0-rc3.orig/wpa_supplicant/wpa_supplicant_i.h	2012-04-16 15:15:40.000000000 -0500
+++ wpa_supplicant-1.0-rc3/wpa_supplicant/wpa_supplicant_i.h	2012-05-06 01:01:17.530134303 -0500
@@ -355,6 +355,8 @@
 	struct wps_er *wps_er;
 	int blacklist_cleared;
 
+	int disconnect_count;
+
 	struct wpabuf *pending_eapol_rx;
 	struct os_time pending_eapol_rx_time;
 	u8 pending_eapol_rx_src[ETH_ALEN];
@@ -535,6 +537,7 @@
 				     int sec, int usec);
 void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
 			      enum 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);
 const char * wpa_supplicant_get_eap_mode(struct wpa_supplicant *wpa_s);
 void wpa_supplicant_cancel_auth_timeout(struct wpa_supplicant *wpa_s);