Cumulative patch from commit 12c1fdf19a721aaf29e1c77d63445c7f5b8c61c0

12c1fdf P2P: Update peer listen channel from Probe Request frames
a805731 P2P: Abort ongoing scan when p2p_find is stopped
7441698 nl80211: Abort an ongoing scan upon scan timeout indication
1446afc wpa_supplicant: Handle EVENT_SCAN_RESULTS when an interface is disabled
d14e63a WNM: Do not scan based on malformed BSS Transition Management Request
f420577 WNM: Fix candidates count in BSS Transition Management Request
3c58df7 wpa_cli: Support running action script on global control interface
b8f02d8 EAP-PWD peer: Fix possible memory leak on error path
8f38eed Android: Remove superfluous OpenSSL include paths
cbf8d18 HS 2.0R2: Clear fetch_anqp_in_progress if fopen fails
4a6e9e5 Fix CONFIG_WPA_TRACE=y compilation without CONFIG_WPA_TRACE_BFD=y
2bf9a53 Add EAP-AKA' and EAP-pwd to wpa_supplicant README
4196c08 Update notes about OpenSSL versions
5d7b1a3 Fix some typos in wpa_supplicant README files
4194fee README-P2P: Fix a typo
c58eed6 P2P: Add Dev Info attribute to Probe Request frames in 60 GHz
2b6e9f9 wpa_supplicant: Expose wpas_get_bands() and related API
94ad3c3 P2P: Change order of P2P IE and frequencies set up
61697c7 Android: Allow wpa_supplicant to write files to osu-info dir
0147afa FST: Enlarge State Transition Timeout (STT)
e1d00d4 Add error handling for offloaded ACS with vendor command failures
bef5e9a Fix scan rescheduling from wpas_stop_pno to check postponed case
b9ca12a nl80211: Add more address fields into RX frame debug message
debde14 RADIUS: Add Acct-Delay-Time into accounting messages
669b532 RADIUS: Update full message for interim accounting updates
251953b Document nas_identifier requirements for RADIUS accounting
902c07a Replace hostapd_mac_comp_empty() with is_zero_ether_addr()
5aef495 VLAN: Avoid use of libnl cache
732b1d2 nl80211: Clean up ifidx properly if interface in a bridge is removed
170c545 FT: Check destination MAC address on RRB receive
57b2c91 RADIUS: Allow RADIUS server to provide PSK instead of passphrase
d8912fd Cache hashed passphrase in RADIUS-based PSK delivery
f8e09bc Defer passphrase-to-PSK hashing out of 802.11 authentication ACL check
cc9c805 VLAN: Use stack instead of heap allocation for new interface name
d48d1b8 FT: Use BSSID as r1_key_holder if no value is configured
71456db FT: Check hapd->wpa_auth before RRB internal delivery
0270bde FT: Fix R0KH-R1KH protocol data length values
96a26ab P2P: Support dedicated P2P_DEVICE without separate group interface
ba307f8 P2P: Add a separate pointer to the P2P Device instance
e040197 GAS client: Make PMF check on RX more consistent
0645492 WNM: Optimize a single BSS transition management candidate scan
eb20cea nl80211: Add an option to specify the BSSID to scan for
adf0478 AP: Store STA supported operating classes information

Change-Id: If0ce28aae5591be783c38e5b60f7f9ff0fb9f8f2
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/ap/accounting.c b/src/ap/accounting.c
index 9357a46..854174e 100644
--- a/src/ap/accounting.c
+++ b/src/ap/accounting.c
@@ -152,6 +152,15 @@
 		goto fail;
 	}
 
+	/*
+	 * Add Acct-Delay-Time with zero value for the first transmission. This
+	 * will be updated within radius_client.c when retransmitting the frame.
+	 */
+	if (!radius_msg_add_attr_int32(msg, RADIUS_ATTR_ACCT_DELAY_TIME, 0)) {
+		wpa_printf(MSG_INFO, "Could not add Acct-Delay-Time");
+		goto fail;
+	}
+
 	return msg;
 
  fail:
@@ -450,6 +459,63 @@
 }
 
 
+static void accounting_interim_error_cb(const u8 *addr, void *ctx)
+{
+	struct hostapd_data *hapd = ctx;
+	struct sta_info *sta;
+	unsigned int i, wait_time;
+	int res;
+
+	sta = ap_get_sta(hapd, addr);
+	if (!sta)
+		return;
+	sta->acct_interim_errors++;
+	if (sta->acct_interim_errors > 10 /* RADIUS_CLIENT_MAX_RETRIES */) {
+		wpa_printf(MSG_DEBUG,
+			   "Interim RADIUS accounting update failed for " MACSTR
+			   " - too many errors, abandon this interim accounting update",
+			   MAC2STR(addr));
+		sta->acct_interim_errors = 0;
+		/* Next update will be tried after normal update interval */
+		return;
+	}
+
+	/*
+	 * Use a shorter update interval as an improved retransmission mechanism
+	 * for failed interim accounting updates. This allows the statistics to
+	 * be updated for each retransmission.
+	 *
+	 * RADIUS client code has already waited RADIUS_CLIENT_FIRST_WAIT.
+	 * Schedule the first retry attempt immediately and every following one
+	 * with exponential backoff.
+	 */
+	if (sta->acct_interim_errors == 1) {
+		wait_time = 0;
+	} else {
+		wait_time = 3; /* RADIUS_CLIENT_FIRST_WAIT */
+		for (i = 1; i < sta->acct_interim_errors; i++)
+			wait_time *= 2;
+	}
+	res = eloop_deplete_timeout(wait_time, 0, accounting_interim_update,
+				    hapd, sta);
+	if (res == 1)
+		wpa_printf(MSG_DEBUG,
+			   "Interim RADIUS accounting update failed for " MACSTR
+			   " (error count: %u) - schedule next update in %u seconds",
+			   MAC2STR(addr), sta->acct_interim_errors, wait_time);
+	else if (res == 0)
+		wpa_printf(MSG_DEBUG,
+			   "Interim RADIUS accounting update failed for " MACSTR
+			   " (error count: %u)", MAC2STR(addr),
+			   sta->acct_interim_errors);
+	else
+		wpa_printf(MSG_DEBUG,
+			   "Interim RADIUS accounting update failed for " MACSTR
+			   " (error count: %u) - no timer found", MAC2STR(addr),
+			   sta->acct_interim_errors);
+}
+
+
 /**
  * accounting_init: Initialize accounting
  * @hapd: hostapd BSS data
@@ -464,6 +530,8 @@
 	if (radius_client_register(hapd->radius, RADIUS_ACCT,
 				   accounting_receive, hapd))
 		return -1;
+	radius_client_set_interim_error_cb(hapd->radius,
+					   accounting_interim_error_cb, hapd);
 
 	accounting_report_state(hapd, 1);