projects
/
l2tpns.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Ensure that sessionkill is not called on an unopened session (borks the freelist).
[l2tpns.git]
/
l2tpns.c
diff --git
a/l2tpns.c
b/l2tpns.c
index
56e1377
..
e65a9c1
100644
(file)
--- a/
l2tpns.c
+++ b/
l2tpns.c
@@
-4,7
+4,7
@@
// 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>
@@
-479,7
+479,7
@@
sessionidt sessionbyip(in_addr_t ip)
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;
@@
-579,8
+579,11
@@
sessionidt sessionbyuser(char *username)
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.
@@
-622,17
+625,16
@@
void send_garp(in_addr_t ip)
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;
return val;
}
return val;
}
@@
-1012,7
+1014,7
@@
static void controladd(controlt * c, tunnelidt t, sessionidt s)
//
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)
@@
-1050,7
+1052,7
@@
void throttle_session(sessionidt s, int rate_in, int rate_out)
// 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)
@@
-1093,9
+1095,9
@@
void sessionshutdown(sessionidt s, char *reason)
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 a
n unopened session
.\n");
return; // not a live session
}
return; // not a live session
}
@@
-1167,7
+1169,7
@@
void sessionshutdown(sessionidt s, char *reason)
}
if (!session[s].die)
}
if (!session[s].die)
- 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--;
@@
-1218,12
+1220,21
@@
void sendipcp(tunnelidt t, sessionidt s)
}
// kill a session now
}
// kill a session now
-
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
@@
-1265,7
+1276,7
@@
static void tunnelkill(tunnelidt t, char *reason)
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);
@@
-1292,12
+1303,12
@@
static void tunnelshutdown(tunnelidt t, char *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
@@
-1836,7
+1847,8
@@
void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
if (!sessionfree)
{
STAT(session_overflow);
if (!sessionfree)
{
STAT(session_overflow);
- tunnelshutdown(t, "No free sessions");
+ LOG(1, 0, t, "No free sessions");
+ return;
}
else
{
}
else
{
@@
-1860,7
+1872,7
@@
void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
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;
@@
-1943,7
+1955,7
@@
void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
l -= 2;
}
l -= 2;
}
- 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)
{
@@
-1952,10
+1964,7
@@
void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
return;
}
return;
}
-
- 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;
}
@@
-2123,7
+2132,7
@@
static int regular_cleanups(void)
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))
@@
-2731,7
+2740,7
@@
memset(ip_filters, 0, sizeof(ip_filtert) * MAXFILTER);
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.
@@
-2740,7
+2749,7
@@
memset(ip_filters, 0, sizeof(ip_filtert) * MAXFILTER);
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)
@@
-2866,7
+2875,7
@@
void rebuild_address_pool(void)
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));
@@
-3739,7
+3748,7
@@
int sessionsetup(tunnelidt t, sessionidt s)
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
)
+ if (!session[s].ip)
{
assign_ip_address(s);
if (!session[s].ip)
{
assign_ip_address(s);
if (!session[s].ip)
@@
-4337,7
+4346,7
@@
void become_master(void)
{
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]);
@@
-4369,7
+4378,7
@@
int cmd_show_hist_idle(struct cli_def *cli, char *command, char **argv, int argc
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;
@@
-4407,7
+4416,7
@@
int cmd_show_hist_open(struct cli_def *cli, char *command, char **argv, int argc
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;