Reject delay fractional value

Eugene Grosbein fr at grosbein.net
Tue Oct 28 20:35:34 CET 2014


On Tue, Oct 28, 2014 at 11:51:11AM -0400, Alan DeKok wrote:
> Eugene Grosbein wrote:
> > Small feature request: please make it possible to specify fractional values of seconds
> > for Reject delay values. I need this for dhcp module, 1 second is too small for me
> > but 2 is too large :-) I'd like to specify 1.5 or 1.8 seconds.
> > 
> > 1/100th second precision ought be enough :-)
> 
>   Sure.  Send a patch. :)
> 
>   It's probably not hard to do.  There is already code to do similar
> things for home servers in 3.0.4.

Well, here it is. Not sure about "#include <sys/time.h>" policy
in the FreeRADIUS code, though it compiles and works for me.

The patch is for 3.0.4 release source code.

--- raddb/radiusd.conf.in.orig	2014-10-29 00:10:21.000000000 +0700
+++ raddb/radiusd.conf.in	2014-10-29 00:10:32.000000000 +0700
@@ -453,7 +453,7 @@
 	#  is deleted from the internal cache of requests.
 	#
 	#  Useful ranges: 1 to 5
-	reject_delay = 1
+	reject_delay = 1.0
 
 	#
 	#  status_server: Whether or not the server will respond
--- src/include/libradius.h.orig	2014-10-29 00:43:21.000000000 +0700
+++ src/include/libradius.h	2014-10-29 00:50:38.000000000 +0700
@@ -67,6 +67,7 @@
 /*
  *  Include system headers.
  */
+#include <sys/time.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
@@ -262,6 +263,8 @@
 
 	uint8_t			*tlv;				//!< Nested TLV (should go away).
 	void const		*ptr;				//!< generic pointer.
+
+	struct timeval		tv;				//!< Timer
 } value_data_t;
 
 /** The type of value a VALUE_PAIR contains
@@ -356,6 +359,7 @@
 #define vp_integer64	data.integer64
 #define vp_ipv4prefix	data.ipv4prefix
 #define vp_tlv		data.tlv
+#define vp_tv		data.tv
 
 typedef struct fr_ipaddr_t {
 	int		af;	/* address family */
--- src/include/radiusd.h.orig	2014-10-29 00:14:23.000000000 +0700
+++ src/include/radiusd.h	2014-10-29 00:58:53.000000000 +0700
@@ -47,6 +47,8 @@
 #  define REQUEST_MAGIC (0xdeadbeef)
 #endif
 
+#include <sys/time.h>
+
 /*
  *	WITH_VMPS is handled by src/include/features.h
  */
@@ -277,7 +279,7 @@
 	rad_child_state_t	child_state;
 	RAD_LISTEN_TYPE		priority;
 
-	int			response_delay;
+	struct timeval		response_delay;
 	int			timer_action;
 	fr_event_t		*ev;
 
@@ -435,7 +437,7 @@
 #ifdef WITH_PROXY
 	bool		proxy_requests;
 #endif
-	uint32_t	reject_delay;
+	struct timeval	reject_delay;
 	bool		status_server;
 	char const	*allow_vulnerable_openssl;
 
--- src/main/mainconfig.c.orig	2014-10-29 00:15:57.000000000 +0700
+++ src/main/mainconfig.c	2014-10-29 01:04:26.000000000 +0700
@@ -97,7 +97,7 @@ static char const	*radius_dir = NULL;	//
  */
 static const CONF_PARSER security_config[] = {
 	{ "max_attributes",  FR_CONF_POINTER(PW_TYPE_INTEGER, &fr_max_attributes), STRINGIFY(0) },
-	{ "reject_delay",  FR_CONF_POINTER(PW_TYPE_INTEGER, &main_config.reject_delay), STRINGIFY(0) },
+	{ "reject_delay",  FR_CONF_POINTER(PW_TYPE_TIMEVAL, &main_config.reject_delay), STRINGIFY(0) },
 	{ "status_server", FR_CONF_POINTER(PW_TYPE_BOOLEAN, &main_config.status_server), "no"},
 	{ "allow_vulnerable_openssl", FR_CONF_POINTER(PW_TYPE_STRING, &main_config.allow_vulnerable_openssl), "no"},
 	{ NULL, -1, 0, NULL, NULL }
@@ -908,7 +908,7 @@ do {\
 	fr_debug_flag = debug_flag;
 
 	FR_INTEGER_COND_CHECK("max_request_time", main_config.max_request_time, (main_config.max_request_time != 0), 100);
-	FR_INTEGER_BOUND_CHECK("reject_delay", main_config.reject_delay, <=, 10);
+	FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, <=, 10, 0);
 	FR_INTEGER_BOUND_CHECK("cleanup_delay", main_config.cleanup_delay, <=, 10);
 
 	/*
@@ -955,7 +955,7 @@ do {\
 	 *	Sanity check the configuration for internal
 	 *	consistency.
 	 */
-	FR_INTEGER_BOUND_CHECK("reject_delay", main_config.reject_delay, <=, main_config.cleanup_delay);
+	FR_TIMEVAL_BOUND_CHECK("reject_delay", &main_config.reject_delay, <=, main_config.cleanup_delay, 0);
 
 	if (chroot_dir) {
 		if (chdir(radlog_dir) < 0) {
--- src/main/process.c.orig	2014-09-10 20:57:22.000000000 +0700
+++ src/main/process.c	2014-10-29 01:12:27.000000000 +0700
@@ -353,6 +353,17 @@ static void tv_add(struct timeval *tv, i
 	}
 }
 
+static void tv_inc(struct timeval *tv, struct timeval *inc)
+{
+	tv->tv_sec += inc->tv_sec;
+	tv->tv_usec += inc->tv_usec;
+
+	if (tv->tv_usec >= USEC) {
+		tv->tv_sec += tv->tv_usec / USEC;
+		tv->tv_usec %= USEC;
+	}
+}
+
 /*
  *	Debug the packet if requested.
  */
@@ -945,7 +971,7 @@ static void request_process_timer(REQUES
 #endif	/* WITH_PROXY */
 
 	case REQUEST_RESPONSE_DELAY:
-		rad_assert(request->response_delay > 0);
+		rad_assert(request->response_delay.tv_sec > 0 && request->response_delay.tv_usec > 0);
 #ifdef WITH_COA
 		rad_assert(!request->proxy || (request->packet->code == request->proxy->code));
 #endif
@@ -954,7 +980,7 @@ static void request_process_timer(REQUES
 
 		when = request->reply->timestamp;
 
-		tv_add(&when, request->response_delay * USEC);
+		tv_inc(&when, &request->response_delay);
 
 		if (timercmp(&when, &now, >)) {
 #ifdef DEBUG_STATE_MACHINE
@@ -1401,7 +1437,8 @@ STATE_MACHINE_DECL(request_finish)
 	 *	See if we need to delay an Access-Reject packet.
 	 */
 	if ((request->reply->code == PW_CODE_ACCESS_REJECT) &&
-	    (request->root->reject_delay > 0)) {
+	    (request->root->reject_delay.tv_sec > 0 &&
+	     request->root->reject_delay.tv_usec > 0 )) {
 		request->response_delay = request->root->reject_delay;
 
 #ifdef WITH_PROXY
@@ -1410,7 +1447,8 @@ STATE_MACHINE_DECL(request_finish)
 		 *	the reject any more.
 		 */
 		if (request->proxy && !request->proxy_reply) {
-			request->response_delay = 0;
+			request->response_delay.tv_sec = 0;
+			request->response_delay.tv_usec = 0;
 		}
 #endif
 
@@ -1419,7 +1457,8 @@ STATE_MACHINE_DECL(request_finish)
 	/*
 	 *	Send the reply.
 	 */
-	if (!request->response_delay) {
+	if (request->response_delay.tv_sec == 0 &&
+	    request->response_delay.tv_usec == 0) {
 		DEBUG_PACKET(request, request->reply, 1);
 		request->listener->send(request->listener,
 					request);
@@ -1443,8 +1482,9 @@ STATE_MACHINE_DECL(request_finish)
 			request->child_state = REQUEST_CLEANUP_DELAY;
 		}
 	} else {
-		RDEBUG2("Delaying response for %d seconds",
-			request->response_delay);
+		RDEBUG2("Delaying response for %d.%d seconds",
+			(int)request->response_delay.tv_sec,
+			(int)request->response_delay.tv_usec);
 		NO_CHILD_THREAD;
 		request->child_state = REQUEST_RESPONSE_DELAY;
 	}
--- src/modules/proto_dhcp/dhcpd.c.orig	2014-09-10 20:57:22.000000000 +0700
+++ src/modules/proto_dhcp/dhcpd.c	2014-10-29 01:23:47.000000000 +0700
@@ -424,10 +424,11 @@ static int dhcp_process(REQUEST *request
 	if (request->reply->code == PW_DHCP_NAK) {
 		vp = pairfind(request->reply->vps, PW_FREERADIUS_RESPONSE_DELAY, 0, TAG_ANY);
 		if (vp) {
-			if (vp->vp_integer <= 10) {
-				request->response_delay = vp->vp_integer;
+ 			if (vp->vp_tv.tv_sec*1000000+vp->vp_tv.tv_usec <= 10000000) {
+ 				request->response_delay = vp->vp_tv;
 			} else {
-				request->response_delay = 10;
+ 				request->response_delay.tv_sec = 10;
+ 				request->response_delay.tv_usec = 0;
 			}
 		}
 	}


More information about the Freeradius-Users mailing list