From b866448a74e526665477b5ea055ba4e970852b2f Mon Sep 17 00:00:00 2001 From: bodea Date: Mon, 30 May 2005 02:55:40 +0000 Subject: [PATCH] - 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). --- Changes | 9 ++++++ Docs/manual.html | 6 +++- Docs/startup-config.5 | 7 +++-- cli.c | 3 +- cluster.c | 6 +++- l2tpns.c | 69 ++++++++++++++++++++++++++++--------------- l2tpns.h | 6 ++-- l2tpns.spec | 6 ++-- 8 files changed, 79 insertions(+), 33 deletions(-) diff --git a/Changes b/Changes index 3972fb2..483ce87 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,12 @@ +* Mon May 30 2005 Brendan O'Dea 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 2.0.21 - Cluster changes from Michael, intended to prevent a stray master from trashing a cluster: diff --git a/Docs/manual.html b/Docs/manual.html index f5cf6db..04f5b61 100644 --- a/Docs/manual.html +++ b/Docs/manual.html @@ -283,7 +283,11 @@ the uptime command on the CLI.
  • cleanup_interval (int)
    -Interval between regular cleanups (in seconds). +Interval between regular cleanups in seconds (default: 2). +
  • + +
  • cleanup_limit (int)
    +Maximum number of session actions to perform each cleanup (default: 50).
  • multi_read_count (int)
    diff --git a/Docs/startup-config.5 b/Docs/startup-config.5 index 2af2706..d125433 100644 --- a/Docs/startup-config.5 +++ b/Docs/startup-config.5 @@ -2,7 +2,7 @@ .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 @@ -132,7 +132,10 @@ uptime 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 diff --git a/cli.c b/cli.c index 9f50323..d5a15d7 100644 --- a/cli.c +++ b/cli.c @@ -2,7 +2,7 @@ // 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 #include @@ -406,6 +406,7 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int 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); diff --git a/cluster.c b/cluster.c index 725adc1..645403c 100644 --- a/cluster.c +++ b/cluster.c @@ -1,6 +1,6 @@ // 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 #include @@ -526,6 +526,10 @@ void cluster_check_master(void) 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) diff --git a/l2tpns.c b/l2tpns.c index 055f860..db73793 100644 --- 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 -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 #include @@ -83,7 +83,7 @@ uint32_t eth_tx = 0; 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]; @@ -113,6 +113,7 @@ config_descriptt config_values[] = { 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), @@ -181,6 +182,9 @@ static void processcontrol(uint8_t *buf, int len, struct sockaddr_in *addr, int 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) { @@ -2059,12 +2063,7 @@ static void processtun(uint8_t * buf, int len) // Else discard. } -// -// 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. @@ -2158,7 +2157,7 @@ static int regular_cleanups(void) if (session[s].die && session[s].die <= TIME) { sessionkill(s, "Expired"); - if (++count >= MAX_ACTIONS) break; + if (++count >= config->cleanup_limit) break; continue; } @@ -2167,7 +2166,7 @@ static int regular_cleanups(void) { sessionshutdown(s, "No response to LCP ECHO requests"); STAT(session_timeout); - if (++count >= MAX_ACTIONS) break; + if (++count >= config->cleanup_limit) break; continue; } @@ -2187,7 +2186,7 @@ static int regular_cleanups(void) 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 @@ -2256,7 +2255,7 @@ static int regular_cleanups(void) if (send) cluster_send_session(s); - if (++count >= MAX_ACTIONS) break; + if (++count >= config->cleanup_limit) break; } } @@ -2278,7 +2277,7 @@ static int regular_cleanups(void) } } - 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); @@ -2293,8 +2292,39 @@ static int regular_cleanups(void) static int still_busy(void) { int i; + static time_t stopped_bgp = 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; @@ -2572,7 +2602,6 @@ static void mainloop(void) /* 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) { @@ -2598,6 +2627,7 @@ static void mainloop(void) // // Important!!! We MUST not process any packets past this point! + LOG(1, 0, 0, "Clean shutdown complete\n"); } static void stripdomain(char *host) @@ -3278,14 +3308,6 @@ int main(int argc, char *argv[]) mainloop(); -#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(); @@ -3680,7 +3702,8 @@ static void update_config() } } 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) diff --git a/l2tpns.h b/l2tpns.h index a5fbe8e..fcb896a 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // L2TPNS Global Stuff -// $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__ @@ -15,7 +15,7 @@ #include #include -#define VERSION "2.0.21" +#define VERSION "2.0.22" // Limits #define MAXTUNNEL 500 // could be up to 65535 @@ -421,6 +421,7 @@ typedef struct 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 @@ -648,6 +649,7 @@ if (count++ < max) { \ extern configt *config; extern time_t basetime; // Time when this process started. extern time_t time_now; // Seconds since EPOCH. +extern char main_quit; extern uint32_t last_id; extern struct Tstats *_statistics; extern in_addr_t my_address; diff --git a/l2tpns.spec b/l2tpns.spec index 20e0f4f..919c97f 100644 --- a/l2tpns.spec +++ b/l2tpns.spec @@ -1,6 +1,6 @@ Summary: A high-speed clustered L2TP LNS Name: l2tpns -Version: 2.0.21 +Version: 2.0.22 Release: 1 Copyright: GPL Group: System Environment/Daemons @@ -43,5 +43,5 @@ rm -rf %{buildroot} %attr(644,root,root) /usr/share/man/man[58]/* %changelog -* Mon May 23 2005 Brendan O'Dea 2.0.21-1 -- 2.0.21 release, see /usr/share/doc/l2tpns-2.0.21/Changes +* Mon May 30 2005 Brendan O'Dea 2.0.22-1 +- 2.0.22 release, see /usr/share/doc/l2tpns-2.0.22/Changes -- 2.20.1