freeradius-client sequence file replacement

Alex Massover alex at jajah.com
Mon Feb 1 16:47:05 CET 2010


Here's a patch removing seq file. Also there's no need in lib/lock.c anymore.


diff -ur ./BUGS /tmp/freeradius-client-1.1.6/BUGS
--- ./BUGS	2007-06-21 21:35:00.000000000 +0300
+++ /tmp/freeradius-client-1.1.6/BUGS	2010-02-01 16:54:25.203211724 +0200
@@ -3,12 +3,6 @@
 Testing can show the presense of bugs, but not their absence.
                 -- Dijkstra
 
-The get_seqnbr function in build_req.c sometimes returns the same
-number, if invoked from multiple processes at the same time. This
-occurs only if a lot of process try to read the sequence file,
-so I suspect a race condition in the locking code, but I can't
-find one. Any help is appreciated.
-
 Radlogin respectively send_server in sendserver.c does not honour a 
 ACCESS_CHALLENGE packet from the RADIUS server. 
 
diff -ur ./include/freeradius-client.h /tmp/freeradius-client-1.1.6/include/freeradius-client.h
--- ./include/freeradius-client.h	2008-02-11 08:54:23.000000000 +0200
+++ /tmp/freeradius-client-1.1.6/include/freeradius-client.h	2010-02-01 16:47:17.084878041 +0200
@@ -426,7 +426,7 @@
 /*	buildreq.c		*/
 
 void rc_buildreq(rc_handle *, SEND_DATA *, int, char *, unsigned short, char *, int, int);
-unsigned char rc_get_seqnbr(rc_handle *);
+unsigned char rc_get_id();
 int rc_auth(rc_handle *, uint32_t, VALUE_PAIR *, VALUE_PAIR **, char *);
 int rc_auth_proxy(rc_handle *, VALUE_PAIR *, VALUE_PAIR **, char *);
 int rc_acct(rc_handle *, uint32_t, VALUE_PAIR *);
diff -ur ./lib/buildreq.c /tmp/freeradius-client-1.1.6/lib/buildreq.c
--- ./lib/buildreq.c	2008-03-05 18:35:20.000000000 +0200
+++ /tmp/freeradius-client-1.1.6/lib/buildreq.c	2010-02-01 17:29:46.987179691 +0200
@@ -13,7 +13,7 @@
 #include <includes.h>
 #include <freeradius-client.h>
 
-unsigned char rc_get_seqnbr(rc_handle *);
+unsigned char rc_get_id();
 
 /*
  * Function: rc_buildreq
@@ -29,87 +29,26 @@
 	data->server = server;
 	data->secret = secret;
 	data->svc_port = port;
-	data->seq_nbr = rc_get_seqnbr(rh);
+	data->seq_nbr = rc_get_id();
 	data->timeout = timeout;
 	data->retries = retries;
 	data->code = code;
 }
 
 /*
- * Function: rc_guess_seqnbr
+ * Function: rc_get_id
  *
- * Purpose: return a random sequence number
+ * Purpose: generate random id
  *
  */
 
-static unsigned char rc_guess_seqnbr(void)
+unsigned char rc_get_id()
 {
 	srandom((unsigned int)(time(NULL)+getpid()));
 	return (unsigned char)(random() & UCHAR_MAX);
 }
 
 /*
- * Function: rc_get_seqnbr
- *
- * Purpose: generate a sequence number
- *
- */
-
-unsigned char rc_get_seqnbr(rc_handle *rh)
-{
-	FILE *sf;
-	int tries = 1;
-	int seq_nbr;
-	char *seqfile = rc_conf_str(rh, "seqfile");
-
-	if ((sf = fopen(seqfile, "a+")) == NULL)
-	{
-		rc_log(LOG_ERR,"rc_get_seqnbr: couldn't open sequence file %s: %s", seqfile, strerror(errno));
-		/* well, so guess a sequence number */
-		return rc_guess_seqnbr();
-	}
-
-	while (do_lock_exclusive(sf)!= 0)
-	{
-		if (errno != EWOULDBLOCK) {
-			rc_log(LOG_ERR, "rc_get_seqnbr: flock failure: %s: %s", seqfile, strerror(errno));
-			fclose(sf);
-			return rc_guess_seqnbr();
-		}
-		tries++;
-		if (tries <= 10)
-			rc_mdelay(500);
-		else
-			break;
-	}
-
-	if (tries > 10) {
-		rc_log(LOG_ERR,"rc_get_seqnbr: couldn't get lock after %d tries: %s", tries-1, seqfile);
- 		fclose(sf);
-		return rc_guess_seqnbr();
-	}
-
-	rewind(sf);
-	if (fscanf(sf, "%d", &seq_nbr) != 1) {
-		rc_log(LOG_ERR,"rc_get_seqnbr: fscanf failure: %s", seqfile);
-		seq_nbr = rc_guess_seqnbr();
-	}
-
-	rewind(sf);
-	ftruncate(fileno(sf),0);
-	fprintf(sf,"%d\n", (seq_nbr+1) & UCHAR_MAX);
-
-	fflush(sf); /* fflush because a process may read it between the do_unlock and fclose */
-
-	if (do_unlock(sf) != 0)
-		rc_log(LOG_ERR, "rc_get_seqnbr: couldn't release lock on %s: %s", seqfile, strerror(errno));
-
-	fclose(sf);
-
-	return (unsigned char)seq_nbr;
-}
-
-/*
  * Function: rc_aaa
  *
  * Purpose: Builds an authentication/accounting request for port id client_port





> -----Original Message-----
> From: freeradius-devel-bounces+alex=jajah.com at lists.freeradius.org
> [mailto:freeradius-devel-bounces+alex=jajah.com at lists.freeradius.org]
> On Behalf Of Alan DeKok
> Sent: יום ב 01 פברואר 2010 15:20
> To: FreeRadius developers mailing list
> Subject: Re: freeradius-client sequence file replacement
> 
> Alex Massover wrote:
> > That requires a redesign of the way freeradius-client works, because
> currently it opens new socket for every request.
> 
>   Then set the ID field (seq_nbr) to a random number.
> 
> > Now seq file really limits performance, so for short term I can just
> drop rc_get_seqnbr() in favor of random number (random code already
> exists there). Anyway it doesn't matter what id will be there because
> new socket will be used.
> 
>   Yes.  Set it to a random number.  Even rand() here is good enough.
> 
> > For a long term maybe it worth implementing what you described below,
> or maybe it's good enough to stay with new socket?
> 
>   For high performance systems, having multiple packets on one socket
> would be best.
> 
>   Alan DeKok.
> -
> List info/subscribe/unsubscribe? See
> http://www.freeradius.org/list/devel.html
> 
> This mail was received via Mail-SeCure System.
> 


This mail was sent via Mail-SeCure System.






More information about the Freeradius-Devel mailing list