summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
f60c61f)
Fix off-by-one errors in session/tunnel initialisation and sessiont <-> sessionidt functions.
Use session[s].opened consistently when checking for in-use sessions (rather than session[s].tunnel).
Use <= cluster_highest_sessionid rather than < MAXSESSION in a couple of loops.
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
// vim: sw=8 ts=8
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
// vim: sw=8 ts=8
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.4 2005/01/13 08:43:19 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.5 2005/02/14 06:00:57 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
#include <arpa/inet.h>
#include <assert.h>
int s = lookup_ipmap(ip);
CSTAT(call_sessionbyip);
int s = lookup_ipmap(ip);
CSTAT(call_sessionbyip);
- if (s > 0 && s < MAXSESSION && session[s].tunnel)
+ if (s > 0 && s < MAXSESSION && session[s].opened)
return (sessionidt) s;
return 0;
return (sessionidt) s;
return 0;
int s;
CSTAT(call_sessionbyuser);
int s;
CSTAT(call_sessionbyuser);
- for (s = 1; s < MAXSESSION ; ++s)
+ for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
+ if (!session[s].opened)
+ continue;
+
if (session[s].walled_garden)
continue; // Skip walled garden users.
if (session[s].walled_garden)
continue; // Skip walled garden users.
sendarp(ifr.ifr_ifindex, mac, ip);
}
sendarp(ifr.ifr_ifindex, mac, ip);
}
-// Find session by username, 0 for not found
static sessiont *sessiontbysessionidt(sessionidt s)
{
static sessiont *sessiontbysessionidt(sessionidt s)
{
- if (!s || s > MAXSESSION) return NULL;
+ if (!s || s >= MAXSESSION) return NULL;
return &session[s];
}
static sessionidt sessionidtbysessiont(sessiont *s)
{
sessionidt val = s-session;
return &session[s];
}
static sessionidt sessionidtbysessiont(sessiont *s)
{
sessionidt val = s-session;
- if (s < session || val > MAXSESSION) return 0;
+ if (s < session || val >= MAXSESSION) return 0;
//
void throttle_session(sessionidt s, int rate_in, int rate_out)
{
//
void throttle_session(sessionidt s, int rate_in, int rate_out)
{
- if (!session[s].tunnel)
+ if (!session[s].opened)
return; // No-one home.
if (!*session[s].user)
return; // No-one home.
if (!*session[s].user)
// add/remove filters from session (-1 = no change)
void filter_session(sessionidt s, int filter_in, int filter_out)
{
// add/remove filters from session (-1 = no change)
void filter_session(sessionidt s, int filter_in, int filter_out)
{
- if (!session[s].tunnel)
+ if (!session[s].opened)
return; // No-one home.
if (!*session[s].user)
return; // No-one home.
if (!*session[s].user)
CSTAT(call_sessionshutdown);
CSTAT(call_sessionshutdown);
- if (!session[s].tunnel)
+ if (!session[s].opened)
- LOG(3, s, session[s].tunnel, "Called sessionshutdown on a session with no tunnel.\n");
+ LOG(3, s, session[s].tunnel, "Called sessionshutdown on an unopened session.\n");
return; // not a live session
}
return; // not a live session
}
- session[s].die = now() + 150; // Clean up in 15 seconds
+ session[s].die = TIME + 150; // Clean up in 15 seconds
// update filter refcounts
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
// update filter refcounts
if (session[s].filter_in) ip_filters[session[s].filter_in - 1].used--;
-static void sessionkill(sessionidt s, char *reason)
+void sessionkill(sessionidt s, char *reason)
{
CSTAT(call_sessionkill);
{
CSTAT(call_sessionkill);
- session[s].die = now();
+ if (!session[s].opened) // not alive
+ return;
+
+ if (session[s].next)
+ {
+ LOG(0, s, session[s].tunnel, "Tried to kill a session with next pointer set (%d)\n", session[s].next);
+ return;
+ }
+
+ session[s].die = TIME;
sessionshutdown(s, reason); // close radius/routes, etc.
if (session[s].radius)
radiusclear(session[s].radius, s); // cant send clean accounting data, session is killed
sessionshutdown(s, reason); // close radius/routes, etc.
if (session[s].radius)
radiusclear(session[s].radius, s); // cant send clean accounting data, session is killed
controlfree = c;
}
// kill sessions
controlfree = c;
}
// kill sessions
- for (s = 1; s < MAXSESSION; s++)
+ for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
if (session[s].tunnel == t)
sessionkill(s, reason);
if (session[s].tunnel == t)
sessionkill(s, reason);
LOG(1, 0, t, "Shutting down tunnel %d (%s)\n", t, reason);
// close session
LOG(1, 0, t, "Shutting down tunnel %d (%s)\n", t, reason);
// close session
- for (s = 1; s < MAXSESSION; s++)
+ for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
if (session[s].tunnel == t)
sessionshutdown(s, reason);
tunnel[t].state = TUNNELDIE;
if (session[s].tunnel == t)
sessionshutdown(s, reason);
tunnel[t].state = TUNNELDIE;
- tunnel[t].die = now() + 700; // Clean up in 70 seconds
+ tunnel[t].die = TIME + 700; // Clean up in 70 seconds
cluster_send_tunnel(t);
// TBA - should we wait for sessions to stop?
{ // Send StopCCN
cluster_send_tunnel(t);
// TBA - should we wait for sessions to stop?
{ // Send StopCCN
if (!sessionfree)
{
STAT(session_overflow);
if (!sessionfree)
{
STAT(session_overflow);
- tunnelshutdown(t, "No free sessions");
+ LOG(1, 0, t, "No free sessions");
+ return;
c = controlnew(11); // sending ICRP
session[s].id = sessionid++;
c = controlnew(11); // sending ICRP
session[s].id = sessionid++;
- session[s].opened = time(NULL);
+ session[s].opened = time_now;
session[s].tunnel = t;
session[s].far = asession;
session[s].last_packet = time_now;
session[s].tunnel = t;
session[s].far = asession;
session[s].last_packet = time_now;
- if (s && !session[s].tunnel) // Is something wrong??
+ if (s && !session[s].opened) // Is something wrong??
{
if (!config->cluster_iam_master)
{
{
if (!config->cluster_iam_master)
{
-
- LOG(1, s, t, "UDP packet contains session %d but no session[%d].tunnel "
- "exists (LAC said tunnel = %d). Dropping packet.\n", s, s, t);
-
+ LOG(1, s, t, "UDP packet contains session which is not opened. Dropping packet.\n");
STAT(tunnel_rx_errors);
return;
}
STAT(tunnel_rx_errors);
return;
}
if (s > config->cluster_highest_sessionid)
s = 1;
if (s > config->cluster_highest_sessionid)
s = 1;
- if (!session[s].tunnel) // Session isn't in use
+ if (!session[s].opened) // Session isn't in use
continue;
if (!session[s].die && session[s].ip && !(session[s].flags & SF_IPCP_ACKED))
continue;
if (!session[s].die && session[s].ip && !(session[s].flags & SF_IPCP_ACKED))
memset(ip_address_pool, 0, sizeof(ippoolt) * MAXIPPOOL);
// Put all the sessions on the free list marked as undefined.
memset(ip_address_pool, 0, sizeof(ippoolt) * MAXIPPOOL);
// Put all the sessions on the free list marked as undefined.
- for (i = 1; i < MAXSESSION - 1; i++)
+ for (i = 1; i < MAXSESSION; i++)
{
session[i].next = i + 1;
session[i].tunnel = T_UNDEF; // mark it as not filled in.
{
session[i].next = i + 1;
session[i].tunnel = T_UNDEF; // mark it as not filled in.
sessionfree = 1;
// Mark all the tunnels as undefined (waiting to be filled in by a download).
sessionfree = 1;
// Mark all the tunnels as undefined (waiting to be filled in by a download).
- for (i = 1; i < MAXTUNNEL- 1; i++)
+ for (i = 1; i < MAXTUNNEL; i++)
tunnel[i].state = TUNNELUNDEF; // mark it as not filled in.
if (!*hostname)
tunnel[i].state = TUNNELUNDEF; // mark it as not filled in.
if (!*hostname)
for (i = 0; i < MAXSESSION; ++i)
{
int ipid;
for (i = 0; i < MAXSESSION; ++i)
{
int ipid;
- if (!session[i].ip || !session[i].tunnel)
+ if (!(session[i].opened && session[i].ip))
continue;
ipid = - lookup_ipmap(htonl(session[i].ip));
continue;
ipid = - lookup_ipmap(htonl(session[i].ip));
LOG(3, s, t, "Doing session setup for session\n");
LOG(3, s, t, "Doing session setup for session\n");
- if (!session[s].ip || session[s].ip == 0xFFFFFFFE)
{
assign_ip_address(s);
if (!session[s].ip)
{
assign_ip_address(s);
if (!session[s].ip)
{
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
{
{
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
{
- if (!session[s].tunnel) // Not an in-use session.
+ if (!session[s].opened) // Not an in-use session.
continue;
run_plugins(PLUGIN_NEW_SESSION_MASTER, &session[s]);
continue;
run_plugins(PLUGIN_NEW_SESSION_MASTER, &session[s]);
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
{
int idle;
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
{
int idle;
- if (!session[s].tunnel)
+ if (!session[s].opened)
continue;
idle = time_now - session[s].last_packet;
continue;
idle = time_now - session[s].last_packet;
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
{
int open = 0, d;
for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
{
int open = 0, d;
- if (!session[s].tunnel)
+ if (!session[s].opened)
continue;
d = time_now - session[s].opened;
continue;
d = time_now - session[s].opened;