Add a radius_Flush() function that waits for the response (or timeout) to

any pending RADIUS transaction.  Use this before sending RAD_STOP RADIUS
messages so that we definitely ``stop'' the session.

It was discovered that sometimes when the link timed out, we got lucky
enough to have an un-ACK'd RADIUS accounting transaction in progress,
resulting in the RAD_STOP message failing to send.

Original report found on:	A russion news group
Text translated by:		glebius
Tested by:			Alexey Popov llp at iteranet dot com
MFC after:			7 days
This commit is contained in:
Brian Somers 2005-01-27 14:09:33 +00:00
parent 174d6a9f73
commit 880447787d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=140905
4 changed files with 23 additions and 0 deletions

View File

@ -871,6 +871,7 @@ IpcpLayerDown(struct fsm *fp)
log_Printf(LogIPCP, "%s: LayerDown: %s\n", fp->link->name, addr);
#ifndef NORADIUS
radius_Flush(&fp->bundle->radius);
radius_Account(&fp->bundle->radius, &fp->bundle->radacct,
fp->bundle->links, RAD_STOP, &ipcp->throughput);

View File

@ -528,6 +528,7 @@ ipv6cp_LayerDown(struct fsm *fp)
log_Printf(LogIPV6CP, "%s: LayerDown: %s\n", fp->link->name, addr);
#ifndef NORADIUS
radius_Flush(&fp->bundle->radius);
radius_Account(&fp->bundle->radius, &fp->bundle->radacct6,
fp->bundle->links, RAD_STOP, &ipv6cp->throughput);

View File

@ -30,6 +30,7 @@
#include <stdint.h>
#include <sys/param.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
@ -680,6 +681,25 @@ radius_Read(struct fdescriptor *d, struct bundle *bundle __unused,
radius_Continue(descriptor2radius(d), 1);
}
/*
* Flush any pending transactions
*/
void
radius_Flush(struct radius *r)
{
struct timeval tv;
fd_set s;
while (r->cx.fd != -1) {
FD_ZERO(&s);
FD_SET(r->cx.fd, &s);
tv.tv_sec = 0;
tv.tv_usec = TICKUNIT;
select(r->cx.fd + 1, &s, NULL, NULL, &tv);
radius_Continue(r, 1);
}
}
/*
* Behave as a struct fdescriptor (descriptor.h)
*/

View File

@ -97,6 +97,7 @@ struct radacct {
struct bundle;
extern void radius_Flush(struct radius *);
extern void radius_Init(struct radius *);
extern void radius_Destroy(struct radius *);