- Have slaves with BGP configured drop BGP on receipt of a shutdown
signal, but hang about for an additional 5s to process any remaining
traffic.
- Replace MAX_ACTIONS with a "cleanup_limit" config option, drop the
default for "cleanup_interval" to 2s (so as to process tunnel/RADIUS
retries more promptly).
+* Mon May 30 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.22
+- Show session open time in "show session"/"show user" detailed output.
+- Have slaves with BGP configured drop BGP on receipt of a shutdown
+ signal, but hang about for an additional 5s to process any remaining
+ traffic.
+- Replace MAX_ACTIONS with a "cleanup_limit" config option, drop the
+ default for "cleanup_interval" to 2s (so as to process tunnel/RADIUS
+ retries more promptly).
+
* Mon May 23 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.21
- Cluster changes from Michael, intended to prevent a stray master
from trashing a cluster:
* Mon May 23 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.21
- Cluster changes from Michael, intended to prevent a stray master
from trashing a cluster:
</LI>
<LI><B>cleanup_interval</B> (int)<BR>
</LI>
<LI><B>cleanup_interval</B> (int)<BR>
-Interval between regular cleanups (in seconds).
+Interval between regular cleanups in seconds (default: 2).
+</LI>
+
+<LI><B>cleanup_limit</B> (int)<BR>
+Maximum number of session actions to perform each cleanup (default: 50).
</LI>
<LI><B>multi_read_count</B> (int)<BR>
</LI>
<LI><B>multi_read_count</B> (int)<BR>
.de Id
.ds Dt \\$4 \\$5
..
.de Id
.ds Dt \\$4 \\$5
..
-.Id $Id: startup-config.5,v 1.3.2.2 2005/05/23 13:48:30 bodea Exp $
+.Id $Id: startup-config.5,v 1.3.2.3 2005/05/30 02:55:42 bodea Exp $
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
.SH NAME
startup\-config \- configuration file for l2tpns
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
.SH NAME
startup\-config \- configuration file for l2tpns
command on the CLI.
.TP
.B cleanup_interval
command on the CLI.
.TP
.B cleanup_interval
-Interval between regular cleanups (in seconds).
+Interval between regular cleanups in seconds (default: 2).
+.TP
+.B cleanup_limit
+Maximum number of session actions to perform each cleanup (default: 50).
.TP
.B multi_read_count
Number of packets to read off each of the UDP and TUN fds when
.TP
.B multi_read_count
Number of packets to read off each of the UDP and TUN fds when
// vim: sw=8 ts=8
char const *cvs_name = "$Name: $";
// vim: sw=8 ts=8
char const *cvs_name = "$Name: $";
-char const *cvs_id_cli = "$Id: cli.c,v 1.43.2.5 2005/01/13 08:26:51 bodea Exp $";
+char const *cvs_id_cli = "$Id: cli.c,v 1.43.2.6 2005/05/30 02:55:40 bodea Exp $";
#include <stdio.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdarg.h>
cli_print(cli, "\tTunnel ID:\t%d", session[s].tunnel);
cli_print(cli, "\tIP address:\t%s", fmtaddr(htonl(session[s].ip), 0));
cli_print(cli, "\tUnique SID:\t%lu", session[s].unique_id);
cli_print(cli, "\tTunnel ID:\t%d", session[s].tunnel);
cli_print(cli, "\tIP address:\t%s", fmtaddr(htonl(session[s].ip), 0));
cli_print(cli, "\tUnique SID:\t%lu", session[s].unique_id);
+ cli_print(cli, "\tOpened:\t\t%u seconds", abs(time_now - session[s].opened));
cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet));
cli_print(cli, "\tNext Recv:\t%u", session[s].nr);
cli_print(cli, "\tNext Send:\t%u", session[s].ns);
cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet));
cli_print(cli, "\tNext Recv:\t%u", session[s].nr);
cli_print(cli, "\tNext Send:\t%u", session[s].ns);
// L2TPNS Clustering Stuff
// L2TPNS Clustering Stuff
-char const *cvs_id_cluster = "$Id: cluster.c,v 1.26.2.10 2005/05/23 13:48:29 bodea Exp $";
+char const *cvs_id_cluster = "$Id: cluster.c,v 1.26.2.11 2005/05/30 02:55:40 bodea Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
LOG(0, 0, 0, "Master timed out! Holding election...\n");
LOG(0, 0, 0, "Master timed out! Holding election...\n");
+ // In the process of shutting down, can't be master
+ if (main_quit)
+ return;
+
for (i = have_peers = 0; i < num_peers; i++)
{
if ((peers[i].timestamp + config->cluster_hb_timeout) < t)
for (i = have_peers = 0; i < num_peers; i++)
{
if ((peers[i].timestamp + config->cluster_hb_timeout) < t)
// 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.10 2005/05/23 13:48:29 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.11 2005/05/30 02:55:41 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
#include <arpa/inet.h>
#include <assert.h>
static uint32_t ip_pool_size = 1; // Size of the pool of addresses used for dynamic address allocation.
time_t time_now = 0; // Current time in seconds since epoch.
static char time_now_string[64] = {0}; // Current time as a string.
static uint32_t ip_pool_size = 1; // Size of the pool of addresses used for dynamic address allocation.
time_t time_now = 0; // Current time in seconds since epoch.
static char time_now_string[64] = {0}; // Current time as a string.
-static char main_quit = 0; // True if we're in the process of exiting.
+char main_quit = 0; // True if we're in the process of exiting.
linked_list *loaded_plugins;
linked_list *plugins[MAX_PLUGIN_TYPES];
linked_list *loaded_plugins;
linked_list *plugins[MAX_PLUGIN_TYPES];
CONFIG("setuid", target_uid, INT),
CONFIG("dump_speed", dump_speed, BOOL),
CONFIG("cleanup_interval", cleanup_interval, INT),
CONFIG("setuid", target_uid, INT),
CONFIG("dump_speed", dump_speed, BOOL),
CONFIG("cleanup_interval", cleanup_interval, INT),
+ CONFIG("cleanup_limit", cleanup_limit, INT),
CONFIG("multi_read_count", multi_read_count, INT),
CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
CONFIG("lock_pages", lock_pages, BOOL),
CONFIG("multi_read_count", multi_read_count, INT),
CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
CONFIG("lock_pages", lock_pages, BOOL),
static tunnelidt new_tunnel(void);
static int unhide_avp(uint8_t *avp, tunnelidt t, sessionidt s, uint16_t length);
static tunnelidt new_tunnel(void);
static int unhide_avp(uint8_t *avp, tunnelidt t, sessionidt s, uint16_t length);
+// on slaves, alow BGP to withdraw cleanly before exiting
+#define QUIT_DELAY 5
+
// return internal time (10ths since process startup)
static clockt now(void)
{
// return internal time (10ths since process startup)
static clockt now(void)
{
-//
-// Maximum number of actions to complete.
-// This is to avoid sending out too many packets
-// at once.
-#define MAX_ACTIONS 500
-
+// Handle retries, timeouts
static int regular_cleanups(void)
{
static sessionidt s = 0; // Next session to check for actions on.
static int regular_cleanups(void)
{
static sessionidt s = 0; // Next session to check for actions on.
if (session[s].die && session[s].die <= TIME)
{
sessionkill(s, "Expired");
if (session[s].die && session[s].die <= TIME)
{
sessionkill(s, "Expired");
- if (++count >= MAX_ACTIONS) break;
+ if (++count >= config->cleanup_limit) break;
{
sessionshutdown(s, "No response to LCP ECHO requests");
STAT(session_timeout);
{
sessionshutdown(s, "No response to LCP ECHO requests");
STAT(session_timeout);
- if (++count >= MAX_ACTIONS) break;
+ if (++count >= config->cleanup_limit) break;
LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n",
(int)(time_now - session[s].last_packet));
tunnelsend(b, 24, session[s].tunnel); // send it
LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n",
(int)(time_now - session[s].last_packet));
tunnelsend(b, 24, session[s].tunnel); // send it
- if (++count >= MAX_ACTIONS) break;
+ if (++count >= config->cleanup_limit) break;
}
// Check for actions requested from the CLI
}
// Check for actions requested from the CLI
if (send)
cluster_send_session(s);
if (send)
cluster_send_session(s);
- if (++count >= MAX_ACTIONS) break;
+ if (++count >= config->cleanup_limit) break;
- if (count >= MAX_ACTIONS)
+ if (count >= config->cleanup_limit)
return 1; // Didn't finish!
LOG(3, 0, 0, "End regular cleanup (%d actions), next in %d seconds\n", count, config->cleanup_interval);
return 1; // Didn't finish!
LOG(3, 0, 0, "End regular cleanup (%d actions), next in %d seconds\n", count, config->cleanup_interval);
static int still_busy(void)
{
int i;
static int still_busy(void)
{
int i;
+ static time_t stopped_bgp = 0;
static clockt last_talked = 0;
static clockt start_busy_wait = 0;
static clockt last_talked = 0;
static clockt start_busy_wait = 0;
+
+ if (!config->cluster_iam_master)
+ {
+#ifdef BGP
+ if (bgp_configured)
+ {
+ if (!stopped_bgp)
+ {
+ LOG(1, 0, 0, "Shutting down in %d seconds, stopping BGP...\n", QUIT_DELAY);
+
+ for (i = 0; i < BGP_NUM_PEERS; i++)
+ if (bgp_peers[i].state == Established)
+ bgp_stop(&bgp_peers[i]);
+
+ stopped_bgp = time_now;
+
+ // we don't want to become master
+ cluster_send_ping(0);
+
+ return 1;
+ }
+
+ if (time_now < (stopped_bgp + QUIT_DELAY))
+ return 1;
+ }
+#endif /* BGP */
+
+ return 0;
+ }
+
if (start_busy_wait == 0)
start_busy_wait = TIME;
if (start_busy_wait == 0)
start_busy_wait = TIME;
/* Handle timeouts. Make sure that this gets run anyway, even if there was
* something to read, else under load this will never actually run....
/* Handle timeouts. Make sure that this gets run anyway, even if there was
* something to read, else under load this will never actually run....
*/
if (config->cluster_iam_master && next_clean <= time_now)
{
*/
if (config->cluster_iam_master && next_clean <= time_now)
{
//
// Important!!! We MUST not process any packets past this point!
//
// Important!!! We MUST not process any packets past this point!
+ LOG(1, 0, 0, "Clean shutdown complete\n");
}
static void stripdomain(char *host)
}
static void stripdomain(char *host)
-#ifdef BGP
- /* try to shut BGP down cleanly; with luck the sockets will be
- writable since we're out of the select */
- for (i = 0; i < BGP_NUM_PEERS; i++)
- if (bgp_peers[i].state == Established)
- bgp_stop(&bgp_peers[i]);
-#endif /* BGP */
-
/* remove plugins (so cleanup code gets run) */
plugins_done();
/* remove plugins (so cleanup code gets run) */
plugins_done();
}
}
memcpy(config->old_plugins, config->plugins, sizeof(config->plugins));
}
}
memcpy(config->old_plugins, config->plugins, sizeof(config->plugins));
- if (!config->cleanup_interval) config->cleanup_interval = 10;
+ if (!config->cleanup_interval) config->cleanup_interval = 2;
+ if (!config->cleanup_limit) config->cleanup_limit = 50;
if (!config->multi_read_count) config->multi_read_count = 10;
if (!config->cluster_address) config->cluster_address = inet_addr(DEFAULT_MCAST_ADDR);
if (!*config->cluster_interface)
if (!config->multi_read_count) config->multi_read_count = 10;
if (!config->cluster_address) config->cluster_address = inet_addr(DEFAULT_MCAST_ADDR);
if (!*config->cluster_interface)
-// $Id: l2tpns.h,v 1.49.2.13 2005/05/23 13:48:29 bodea Exp $
+// $Id: l2tpns.h,v 1.49.2.14 2005/05/30 02:55:41 bodea Exp $
#ifndef __L2TPNS_H__
#define __L2TPNS_H__
#ifndef __L2TPNS_H__
#define __L2TPNS_H__
#include <sys/types.h>
#include <libcli.h>
#include <sys/types.h>
#include <libcli.h>
-#define VERSION "2.0.21"
+#define VERSION "2.0.22"
// Limits
#define MAXTUNNEL 500 // could be up to 65535
// Limits
#define MAXTUNNEL 500 // could be up to 65535
char config_file[128];
int reload_config; // flag to re-read config (set by cli)
int cleanup_interval; // interval between regular cleanups (in seconds)
char config_file[128];
int reload_config; // flag to re-read config (set by cli)
int cleanup_interval; // interval between regular cleanups (in seconds)
+ int cleanup_limit; // maximum number of actions to perform on sessions in each cleanup
int multi_read_count; // amount of packets to read per fd in processing loop
char tundevice[10]; // tun device name
int multi_read_count; // amount of packets to read per fd in processing loop
char tundevice[10]; // tun device name
extern configt *config;
extern time_t basetime; // Time when this process started.
extern time_t time_now; // Seconds since EPOCH.
extern configt *config;
extern time_t basetime; // Time when this process started.
extern time_t time_now; // Seconds since EPOCH.
extern uint32_t last_id;
extern struct Tstats *_statistics;
extern in_addr_t my_address;
extern uint32_t last_id;
extern struct Tstats *_statistics;
extern in_addr_t my_address;
Summary: A high-speed clustered L2TP LNS
Name: l2tpns
Summary: A high-speed clustered L2TP LNS
Name: l2tpns
Release: 1
Copyright: GPL
Group: System Environment/Daemons
Release: 1
Copyright: GPL
Group: System Environment/Daemons
%attr(644,root,root) /usr/share/man/man[58]/*
%changelog
%attr(644,root,root) /usr/share/man/man[58]/*
%changelog
-* Mon May 23 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.21-1
-- 2.0.21 release, see /usr/share/doc/l2tpns-2.0.21/Changes
+* Mon May 30 2005 Brendan O'Dea <bod@optusnet.com.au> 2.0.22-1
+- 2.0.22 release, see /usr/share/doc/l2tpns-2.0.22/Changes