Understand the Session-Timeout RADIUS attribute

Store the Filter-Id attribute (we don't do anything with it yet)

Submitted mostly by: andrew pavlov <and@kremenchug.net>
This commit is contained in:
Brian Somers 2002-05-07 10:06:54 +00:00
parent 2df833538e
commit bf1eaec5e8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=96153
5 changed files with 109 additions and 4 deletions

View File

@ -227,6 +227,13 @@ bundle_LinkAdded(struct bundle *bundle, struct datalink *dl)
if (dl->state == DATALINK_OPEN)
bundle->phys_type.open |= dl->physical->type;
#ifndef NORADIUS
if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
!= bundle->phys_type.open && bundle->session.timer.state == TIMER_STOPPED)
if (bundle->radius.sessiontime)
bundle_StartSessionTimer(bundle, 0);
#endif
if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
!= bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED)
/* We may need to start our idle timer */
@ -246,8 +253,13 @@ bundle_LinksRemoved(struct bundle *bundle)
mp_CheckAutoloadTimer(&bundle->ncp.mp);
if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
== bundle->phys_type.open)
== bundle->phys_type.open) {
#ifndef NORADIUS
if (bundle->radius.sessiontime)
bundle_StopSessionTimer(bundle);
#endif
bundle_StopIdleTimer(bundle);
}
}
static void
@ -274,6 +286,10 @@ bundle_LayerUp(void *v, struct fsm *fp)
if (ncp_LayersOpen(&fp->bundle->ncp) == 1) {
bundle_CalculateBandwidth(fp->bundle);
time(&bundle->upat);
#ifndef NORADIUS
if (bundle->radius.sessiontime)
bundle_StartSessionTimer(bundle, 0);
#endif
bundle_StartIdleTimer(bundle, 0);
mp_CheckAutoloadTimer(&fp->bundle->ncp.mp);
}
@ -300,6 +316,10 @@ bundle_LayerDown(void *v, struct fsm *fp)
if (isncp(fp->proto)) {
if (ncp_LayersOpen(&fp->bundle->ncp) == 0) {
#ifndef NORADIUS
if (bundle->radius.sessiontime)
bundle_StopSessionTimer(bundle);
#endif
bundle_StopIdleTimer(bundle);
bundle->upat = 0;
mp_StopAutoloadTimer(&bundle->ncp.mp);
@ -399,6 +419,10 @@ bundle_Close(struct bundle *bundle, const char *name, int how)
}
if (!others_active) {
#ifndef NORADIUS
if (bundle->radius.sessiontime)
bundle_StopSessionTimer(bundle);
#endif
bundle_StopIdleTimer(bundle);
if (ncp_LayersUnfinished(&bundle->ncp))
ncp_Close(&bundle->ncp);
@ -942,6 +966,10 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
ncp2initial(&bundle->ncp);
mp_Down(&bundle->ncp.mp);
bundle_NewPhase(bundle, PHASE_DEAD);
#ifndef NORADIUS
if (bundle->radius.sessiontime)
bundle_StopSessionTimer(bundle);
#endif
bundle_StopIdleTimer(bundle);
}
}
@ -1184,6 +1212,47 @@ bundle_RemainingIdleTime(struct bundle *bundle)
return -1;
}
#ifndef NORADIUS
static void
bundle_SessionTimeout(void *v)
{
struct bundle *bundle = (struct bundle *)v;
log_Printf(LogPHASE, "Session-Timeout timer expired\n");
bundle_StopSessionTimer(bundle);
bundle_Close(bundle, NULL, CLOSE_STAYDOWN);
}
void
bundle_StartSessionTimer(struct bundle *bundle, unsigned secs)
{
timer_Stop(&bundle->session.timer);
if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) !=
bundle->phys_type.open && bundle->radius.sessiontime) {
time_t now = time(NULL);
if (secs == 0)
secs = bundle->radius.sessiontime;
bundle->session.timer.func = bundle_SessionTimeout;
bundle->session.timer.name = "session";
bundle->session.timer.load = secs * SECTICKS;
bundle->session.timer.arg = bundle;
timer_Start(&bundle->session.timer);
bundle->session.done = now + secs;
}
}
void
bundle_StopSessionTimer(struct bundle *bundle)
{
timer_Stop(&bundle->session.timer);
bundle->session.done = 0;
}
#endif
int
bundle_IsDead(struct bundle *bundle)
{
@ -1825,7 +1894,7 @@ bundle_CalculateBandwidth(struct bundle *bundle)
}
}
if(bundle->bandwidth == 0)
if (bundle->bandwidth == 0)
bundle->bandwidth = 115200; /* Shrug */
if (bundle->ncp.mp.active) {

View File

@ -127,6 +127,13 @@ struct bundle {
time_t done;
} idle;
#ifndef NORADIUS
struct {
struct pppTimer timer;
time_t done;
} session;
#endif
struct {
int fd; /* write status here */
} notify;
@ -163,6 +170,11 @@ extern void bundle_StopIdleTimer(struct bundle *);
extern int bundle_IsDead(struct bundle *);
extern struct datalink *bundle2datalink(struct bundle *, const char *);
#ifndef NORADIUS
extern void bundle_StartSessionTimer(struct bundle *, unsigned secs);
extern void bundle_StopSessionTimer(struct bundle *);
#endif
extern void bundle_RegisterDescriptor(struct bundle *, struct fdescriptor *);
extern void bundle_UnRegisterDescriptor(struct bundle *, struct fdescriptor *);

View File

@ -5278,6 +5278,8 @@ If the received compression type is
will request VJ compression during IPCP negotiations despite any
.Dq disable vj
configuration command.
.It RAD_FILTER_ID
This attribute is stored but not yet used.
.It RAD_FRAMED_ROUTE
The received string is expected to be in the format
.Ar dest Ns Op / Ns Ar bits
@ -5324,6 +5326,9 @@ or
.Dv HISADDR
keywords.
.Pp
.It RAD_SESSION_TIMEOUT
If supplied, the client connection is closed after the given number of
seconds.
.El
Values received from the RADIUS server may be viewed using
.Dq show bundle .

View File

@ -167,6 +167,21 @@ radius_Process(struct radius *r, int got)
log_Printf(LogPHASE, " IP %s\n", inet_ntoa(r->ip));
break;
case RAD_FILTER_ID:
free(r->filterid);
if ((r->filterid = rad_cvt_string(data, len)) == NULL) {
log_Printf(LogERROR, "rad_cvt_string: %s\n", rad_strerror(r->cx.rad));
rad_close(r->cx.rad);
return;
}
log_Printf(LogPHASE, " Filter \"%s\"\n", r->filterid);
break;
case RAD_SESSION_TIMEOUT:
r->sessiontime = rad_cvt_int(data);
log_Printf(LogPHASE, " Session-Timeout %lu\n", r->sessiontime);
break;
case RAD_FRAMED_IP_NETMASK:
r->mask = rad_cvt_addr(data);
log_Printf(LogPHASE, " Netmask %s\n", inet_ntoa(r->mask));
@ -365,6 +380,8 @@ radius_Destroy(struct radius *r)
log_Printf(LogDEBUG, "Radius: radius_Destroy\n");
timer_Stop(&r->cx.timer);
route_DeleteAll(&r->routes);
free(r->filterid);
r->filterid = NULL;
if (r->cx.fd != -1) {
r->cx.fd = -1;
rad_close(r->cx.rad);
@ -463,7 +480,7 @@ radius_Authenticate(struct radius *r, struct authinfo *authp, const char *name,
setttyent();
for (slot = 1; (ttyp = getttyent()); ++slot)
if (!strcmp(ttyp->ty_name, authp->physical->name.base)) {
if(rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) {
if (rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) {
log_Printf(LogERROR, "rad_put: rad_put_string: %s\n",
rad_strerror(r->cx.rad));
rad_close(r->cx.rad);
@ -593,7 +610,7 @@ radius_Account(struct radius *r, struct radacct *ac, struct datalink *dl,
setttyent();
for (slot = 1; (ttyp = getttyent()); ++slot)
if (!strcmp(ttyp->ty_name, dl->physical->name.base)) {
if(rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) {
if (rad_put_int(r->cx.rad, RAD_NAS_PORT, slot) != 0) {
log_Printf(LogERROR, "rad_put: rad_put_string: %s\n",
rad_strerror(r->cx.rad));
rad_close(r->cx.rad);

View File

@ -39,6 +39,8 @@ struct radius {
struct in_addr ip; /* FRAMED IP */
struct in_addr mask; /* FRAMED Netmask */
unsigned long mtu; /* FRAMED MTU */
unsigned long sessiontime; /* Session-Timeout */
char *filterid; /* FRAMED Filter Id */
struct sticky_route *routes; /* FRAMED Routes */
struct {
char file[PATH_MAX]; /* Radius config file */