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; } } }