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