Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Dec 2012 18:57:23 +0700
From:      Eugene Grosbein <eugen@grosbein.net>
To:        "net@freebsd.org" <net@freebsd.org>
Cc:        Sergey Matveychuk <sem@freebsd.org>
Subject:   libradius dead_time option
Message-ID:  <50D2FD23.90505@grosbein.net>

next in thread | raw e-mail | index | archive | help
Hi!

Recently libradius(3) got long-awaited 'dead_time' option
that allows to skip 'dead' radius servers for 'dead_time' timeout
while dealing with multiple servers.

I'd like to ask for small improvement of the code.
Presently it will fail without a try if all servers marked 'dead'.

Instead, in that case it shoud ignore 'dead' state of servers and
make at try as if all of them were marked 'alive'. That would greatly
increase recovery time after great network disasters.

Also, I'd like to be able to see notification of such disasters in system logs
(as an option). Something like this (compile-tested only):

--- radlib.c.orig	2012-12-20 18:13:25.000000000 +0700
+++ radlib.c	2012-12-20 18:54:43.000000000 +0700
@@ -55,6 +55,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#ifdef LIBRADIUS_USE_SYSLOG
+#include <syslog.h>
+#endif
 #include <unistd.h>
 
 #include "radlib_private.h"
@@ -686,9 +689,35 @@
 	if (h->servers[h->srv].num_tries >= h->servers[h->srv].max_tries) {
 		/* Set next probe time for this server */
 		if (h->servers[h->srv].dead_time) {
+			int alldead = 1;
+			int i;
+#ifdef LIBRADIUS_USE_SYSLOG
+			char host[13]; /* AF_INET in dot notation */
+			syslog(LOG_INFO,
+			    "RADIUS server %s:%u is not responding and is being marked dead.",
+			    inet_ntop(AF_INET, &(h->servers[h->srv].addr.sin_addr),
+				host, sizeof(host)),
+			    (int)ntohs(h->servers[h->srv].addr.sin_port));
+#endif
 			h->servers[h->srv].is_dead = 1;
 			h->servers[h->srv].next_probe = now +
 			    h->servers[h->srv].dead_time;
+			for (i = 0; i < h->num_servers; i++) {
+			    if (!h->servers[i].is_dead) {
+				alldead = 0;
+				break;
+			    }
+			}
+			if (alldead) {
+#ifdef LIBRADIUS_USE_SYSLOG
+			    syslog(LOG_NOTICE, "ALL RADIUS servers are dead.");
+#endif
+			    /* don't be idle */
+			    for (i = 0; i < h->num_servers; i++) {
+				h->servers[i].is_dead = 0;
+				h->servers[i].num_tries = 0;
+			    }
+			}
 		}
 		do {
 		    	h->srv++;
@@ -698,6 +727,14 @@
 			    	break;
 			if (h->servers[h->srv].dead_time &&
 			    h->servers[h->srv].next_probe <= now) {
+#ifdef LIBRADIUS_USE_SYSLOG
+			    	char host[13]; /* AF_INET in dot notation */
+			    	syslog(LOG_INFO,
+				    "RADIUS server %s:%u is being marked alive.",
+				    inet_ntop(AF_INET, &(h->servers[h->srv].addr.sin_addr),
+					host, sizeof(host)),
+				    (int)ntohs(h->servers[h->srv].addr.sin_port));
+#endif
 			    	h->servers[h->srv].is_dead = 0;
 				h->servers[h->srv].num_tries = 0;
 				break;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?50D2FD23.90505>