diff mbox

Acct-Delay-Time missing with RADIUS accounting

Message ID 20160229161557.GA19178@w1.fi
State Accepted
Headers show

Commit Message

Jouni Malinen Feb. 29, 2016, 4:15 p.m. UTC
On Mon, Feb 29, 2016 at 12:10:07PM +0200, Jouni Malinen wrote:
> We can do following for interim updates. Need to think a bit more about
> Acct-Delay-Time in other accounting messages (with the need to update
> Identifier and Request Authenticator).

Actually, this change is not needed at all. It is straightforward to
handle the retransmission case as well and a generic addition of
Acct-Delay-Time with value 0 to all new accounting messages will work
for both needs:

[PATCH] RADIUS: Add Acct-Delay-Time into accounting messages

This tells to the server how long we have been trying to transmit the
message so that the actual time of the message generation can be
determined from receive time (ignoring network delays and only at
accuracy of one second).

For interim updates, only value 0 is used since there are no
retransmissions of the same message. For other accounting messages, the
initial attempt goes out with value 0 and the retransmissions, if
needed, show the number of seconds the message has been waiting in the
queue.

Update the Identifier and Authenticator in the messages whenever
updating the Acct-Delay-Time per RFC 2866, 4.1 requirements.

Signed-off-by: Jouni Malinen <j@w1.fi>
---
 src/ap/accounting.c        |  9 +++++++++
 src/radius/radius_client.c | 30 ++++++++++++++++++++++++++++++
 2 files changed, 39 insertions(+)

Comments

Alan DeKok Feb. 29, 2016, 6:35 p.m. UTC | #1
On Feb 29, 2016, at 11:15 AM, Jouni Malinen <j@w1.fi> wrote:
> Actually, this change is not needed at all. It is straightforward to
> handle the retransmission case as well and a generic addition of
> Acct-Delay-Time with value 0 to all new accounting messages will work
> for both needs:

  That's good.

  Alan DeKok.
diff mbox

Patch

diff --git a/src/ap/accounting.c b/src/ap/accounting.c
index 010ba05..854174e 100644
--- a/src/ap/accounting.c
+++ b/src/ap/accounting.c
@@ -152,6 +152,15 @@  static struct radius_msg * accounting_msg(struct hostapd_data *hapd,
 		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:
diff --git a/src/radius/radius_client.c b/src/radius/radius_client.c
index 5e705e6..a4edd5f 100644
--- a/src/radius/radius_client.c
+++ b/src/radius/radius_client.c
@@ -365,6 +365,8 @@  static int radius_client_retransmit(struct radius_client_data *radius,
 	int s;
 	struct wpabuf *buf;
 	size_t prev_num_msgs;
+	u8 *acct_delay_time;
+	size_t acct_delay_time_len;
 
 	if (entry->msg_type == RADIUS_ACCT ||
 	    entry->msg_type == RADIUS_ACCT_INTERIM) {
@@ -418,6 +420,34 @@  static int radius_client_retransmit(struct radius_client_data *radius,
 		return 1;
 	}
 
+	if (entry->msg_type == RADIUS_ACCT &&
+	    radius_msg_get_attr_ptr(entry->msg, RADIUS_ATTR_ACCT_DELAY_TIME,
+				    &acct_delay_time, &acct_delay_time_len,
+				    NULL) == 0 &&
+	    acct_delay_time_len == 4) {
+		struct radius_hdr *hdr;
+		u32 delay_time;
+
+		/*
+		 * Need to assign a new identifier since attribute contents
+		 * changes.
+		 */
+		hdr = radius_msg_get_hdr(entry->msg);
+		hdr->identifier = radius_client_get_id(radius);
+
+		/* Update Acct-Delay-Time to show wait time in queue */
+		delay_time = now - entry->first_try;
+		WPA_PUT_BE32(acct_delay_time, delay_time);
+
+		wpa_printf(MSG_DEBUG,
+			   "RADIUS: Updated Acct-Delay-Time to %u for retransmission",
+			   delay_time);
+		radius_msg_finish_acct(entry->msg, entry->shared_secret,
+				       entry->shared_secret_len);
+		if (radius->conf->msg_dumps)
+			radius_msg_dump(entry->msg);
+	}
+
 	/* retransmit; remove entry if too many attempts */
 	entry->attempts++;
 	hostapd_logger(radius->ctx, entry->addr, HOSTAPD_MODULE_RADIUS,