backout regular_cleanup changes
authorbodea <bodea>
Sun, 3 Jul 2005 02:40:22 +0000 (02:40 +0000)
committerbodea <bodea>
Sun, 3 Jul 2005 02:40:22 +0000 (02:40 +0000)
Changes
Docs/manual.html
Docs/startup-config.5
l2tpns.c
l2tpns.h
l2tpns.spec
radius.c

diff --git a/Changes b/Changes
index 51b2ae8..ac8c547 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,6 @@
+* Sun Jul 3 2005 Brendan O'Dea <bod@optus.net> 2.0.23
+- Backout regular_cleanup changes.
+
 * Tue May 31 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
index b37cba4..f5cf6db 100644 (file)
@@ -282,6 +282,10 @@ second.  Even if this is disabled, you can see this information by running
 the <EM>uptime</EM> command on the CLI.
 </LI>
 
+<LI><B>cleanup_interval</B> (int)<BR>
+Interval between regular cleanups (in seconds).
+</LI>
+
 <LI><B>multi_read_count</B> (int)<BR>
 Number of packets to read off each of the UDP and TUN fds when
 returned as readable by select (default:  10).  Avoids incurring the
index 8378fb7..b424548 100644 (file)
@@ -2,7 +2,7 @@
 .de Id
 .ds Dt \\$4 \\$5
 ..
-.Id $Id: startup-config.5,v 1.3.2.4 2005/05/30 06:35:19 bodea Exp $
+.Id $Id: startup-config.5,v 1.3.2.5 2005/07/03 02:40:23 bodea Exp $
 .TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
 .SH NAME
 startup\-config \- configuration file for l2tpns
@@ -131,6 +131,9 @@ by running the
 uptime
 command on the CLI.
 .TP
+.B cleanup_interval
+Interval between regular cleanups (in seconds).
+.TP
 .B multi_read_count
 Number of packets to read off each of the UDP and TUN fds when
 returned as readable by select (default: 10).  Avoids incurring the
index 0af33b6..e9f768a 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
 
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.16 2005/06/01 01:10:15 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.73.2.17 2005/07/03 02:40:22 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -112,6 +112,7 @@ config_descriptt config_values[] = {
        CONFIG("accounting_dir", accounting_dir, STRING),
        CONFIG("setuid", target_uid, INT),
        CONFIG("dump_speed", dump_speed, BOOL),
+       CONFIG("cleanup_interval", cleanup_interval, INT),
        CONFIG("multi_read_count", multi_read_count, INT),
        CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
        CONFIG("lock_pages", lock_pages, BOOL),
@@ -183,12 +184,11 @@ 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), set f if given
-static clockt now(double *f)
+// return internal time (10ths since process startup)
+static clockt now(void)
 {
        struct timeval t;
        gettimeofday(&t, 0);
-       if (f) *f = t.tv_sec + t.tv_usec / 1000000.0;
        return (t.tv_sec - basetime) * 10 + t.tv_usec / 100000 + 1;
 }
 
@@ -198,7 +198,7 @@ static clockt now(double *f)
 clockt backoff(uint8_t try)
 {
        if (try > 5) try = 5;                  // max backoff
-       return now(NULL) + 10 * (1 << try);
+       return now() + 10 * (1 << try);
 }
 
 
@@ -2062,61 +2062,42 @@ static void processtun(uint8_t * buf, int len)
        // Else discard.
 }
 
-// Handle retries, timeouts.  Runs every 1/10th sec, want to ensure
-// that we look at the whole of the tunnel, radius and session tables
-// every second
-static void regular_cleanups(double period)
-{
-       // Next tunnel, radius and session to check for actions on.
-       static tunnelidt t = 0;
-       static int r = 0;
-       static sessionidt s = 0;
-
-       int t_actions = 0;
-       int r_actions = 0;
-       int s_actions = 0;
-
-       int t_slice;
-       int r_slice;
-       int s_slice;
+//
+// Maximum number of actions to complete.
+// This is to avoid sending out too many packets
+// at once.
+#define MAX_ACTIONS 500
 
-       int i;
+static int regular_cleanups(void)
+{
+       static sessionidt s = 0;        // Next session to check for actions on.
+       tunnelidt t;
+       int count=0,i;
+       uint16_t r;
+       static clockt next_acct = 0;
+       static clockt next_shut_acct = 0;
        int a;
 
-       // divide up tables into slices based on the last run
-       t_slice = config->cluster_highest_tunnelid  * period;
-       r_slice = (MAXRADIUS - 1)                   * period;
-       s_slice = config->cluster_highest_sessionid * period;
+       LOG(3, 0, 0, "Begin regular cleanup\n");
 
-       if (t_slice < 1)
-           t_slice = 1;
-       else if (t_slice > config->cluster_highest_tunnelid)
-           t_slice = config->cluster_highest_tunnelid;
-
-       if (r_slice < 1)
-           r_slice = 1;
-       else if (r_slice > (MAXRADIUS - 1))
-           r_slice = MAXRADIUS - 1;
-
-       if (s_slice < 1)
-           s_slice = 1;
-       else if (s_slice > config->cluster_highest_sessionid)
-           s_slice = config->cluster_highest_sessionid;
-
-       LOG(4, 0, 0, "Begin regular cleanup (last %f seconds ago)\n", period);
-
-       for (i = 0; i < t_slice; i++)
+       for (r = 1; r < MAXRADIUS; r++)
+       {
+               if (!radius[r].state)
+                       continue;
+               if (radius[r].retry)
+               {
+                       if (radius[r].retry <= TIME)
+                               radiusretry(r);
+               } else
+                       radius[r].retry = backoff(radius[r].try+1);     // Is this really needed? --mo
+       }
+       for (t = 1; t <= config->cluster_highest_tunnelid; t++)
        {
-               t++;
-               if (t > config->cluster_highest_tunnelid)
-                       t = 1;
-
                // check for expired tunnels
                if (tunnel[t].die && tunnel[t].die <= TIME)
                {
                        STAT(tunnel_timeout);
                        tunnelkill(t, "Expired");
-                       t_actions++;
                        continue;
                }
                // check for message resend
@@ -2136,8 +2117,6 @@ static void regular_cleanups(double period)
                                                tunnelsend(c->buf, c->length, t);
                                                c = c->next;
                                        }
-
-                               t_actions++;
                        }
                }
                // Send hello
@@ -2146,7 +2125,6 @@ static void regular_cleanups(double period)
                        controlt *c = controlnew(6); // sending HELLO
                        controladd(c, t, 0); // send the message
                        LOG(3, 0, t, "Sending HELLO message\n");
-                       t_actions++;
                }
 
                // Check for tunnel changes requested from the CLI
@@ -2157,28 +2135,13 @@ static void regular_cleanups(double period)
                        {
                                LOG(2, 0, t, "Dropping tunnel by CLI\n");
                                tunnelshutdown(t, "Requested by administrator");
-                               t_actions++;
                        }
                }
-       }
 
-       for (i = 0; i < r_slice; i++)
-       {
-               r++;
-               if (r >= MAXRADIUS)
-                       r = 1;
-
-               if (!radius[r].state)
-                       continue;
-
-               if (radius[r].retry <= TIME)
-               {
-                       radiusretry(r);
-                       r_actions++;
-               }
        }
 
-       for (i = 0; i < s_slice; i++)
+       count = 0;
+       for (i = 1; i <= config->cluster_highest_sessionid; i++)
        {
                s++;
                if (s > config->cluster_highest_sessionid)
@@ -2192,14 +2155,13 @@ static void regular_cleanups(double period)
                        // IPCP has not completed yet. Resend
                        LOG(3, s, session[s].tunnel, "No ACK for initial IPCP ConfigReq... resending\n");
                        sendipcp(session[s].tunnel, s);
-                       s_actions++;
                }
 
                // check for expired sessions
                if (session[s].die && session[s].die <= TIME)
                {
                        sessionkill(s, "Expired");
-                       s_actions++;
+                       if (++count >= MAX_ACTIONS) break;
                        continue;
                }
 
@@ -2208,7 +2170,7 @@ static void regular_cleanups(double period)
                {
                        sessionshutdown(s, "No response to LCP ECHO requests");
                        STAT(session_timeout);
-                       s_actions++;
+                       if (++count >= MAX_ACTIONS) break;
                        continue;
                }
 
@@ -2228,7 +2190,7 @@ static void regular_cleanups(double period)
                        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
-                       s_actions++;
+                       if (++count >= MAX_ACTIONS) break;
                }
 
                // Check for actions requested from the CLI
@@ -2242,7 +2204,6 @@ static void regular_cleanups(double period)
                                LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
                                sessionshutdown(s, "Requested by administrator");
                                a = 0; // dead, no need to check for other actions
-                               s_actions++;
                        }
 
                        if (a & CLI_SESS_NOSNOOP)
@@ -2250,7 +2211,6 @@ static void regular_cleanups(double period)
                                LOG(2, s, session[s].tunnel, "Unsnooping session by CLI\n");
                                session[s].snoop_ip = 0;
                                session[s].snoop_port = 0;
-                               s_actions++;
                                send++;
                        }
                        else if (a & CLI_SESS_SNOOP)
@@ -2261,7 +2221,6 @@ static void regular_cleanups(double period)
 
                                session[s].snoop_ip = cli_session_actions[s].snoop_ip;
                                session[s].snoop_port = cli_session_actions[s].snoop_port;
-                               s_actions++;
                                send++;
                        }
 
@@ -2269,7 +2228,6 @@ static void regular_cleanups(double period)
                        {
                                LOG(2, s, session[s].tunnel, "Un-throttling session by CLI\n");
                                throttle_session(s, 0, 0);
-                               s_actions++;
                                send++;
                        }
                        else if (a & CLI_SESS_THROTTLE)
@@ -2279,7 +2237,6 @@ static void regular_cleanups(double period)
                                    cli_session_actions[s].throttle_out);
 
                                throttle_session(s, cli_session_actions[s].throttle_in, cli_session_actions[s].throttle_out);
-                               s_actions++;
                                send++;
                        }
 
@@ -2287,7 +2244,6 @@ static void regular_cleanups(double period)
                        {
                                LOG(2, s, session[s].tunnel, "Un-filtering session by CLI\n");
                                filter_session(s, 0, 0);
-                               s_actions++;
                                send++;
                        }
                        else if (a & CLI_SESS_FILTER)
@@ -2297,19 +2253,42 @@ static void regular_cleanups(double period)
                                    cli_session_actions[s].filter_out);
 
                                filter_session(s, cli_session_actions[s].filter_in, cli_session_actions[s].filter_out);
-                               s_actions++;
                                send++;
                        }
 
                        if (send)
                                cluster_send_session(s);
+
+                       if (++count >= MAX_ACTIONS) break;
+               }
+       }
+
+       if (*config->accounting_dir)
+       {
+               if (next_acct <= TIME)
+               {
+                       // Dump accounting data
+                       next_acct = TIME + ACCT_TIME;
+                       next_shut_acct = TIME + ACCT_SHUT_TIME;
+                       dump_acct_info(1);
+               }
+               else if (next_shut_acct <= TIME)
+               {
+                       // Dump accounting data for shutdown sessions
+                       next_shut_acct = TIME + ACCT_SHUT_TIME;
+                       if (shut_acct_n)
+                               dump_acct_info(0);
                }
        }
 
-       LOG(4, 0, 0, "End regular cleanup: checked %d/%d/%d tunnels/radius/sessions; %d/%d/%d actions\n",
-               t_slice, r_slice, s_slice, t_actions, r_actions, s_actions);
+       if (count >= MAX_ACTIONS)
+               return 1;       // Didn't finish!
+
+       LOG(3, 0, 0, "End regular cleanup (%d actions), next in %d seconds\n", count, config->cleanup_interval);
+       return 0;
 }
 
+
 //
 // Are we in the middle of a tunnel update, or radius
 // requests??
@@ -2401,6 +2380,7 @@ static void mainloop(void)
        uint8_t buf[65536];
        struct timeval to;
        clockt next_cluster_ping = 0;   // send initial ping immediately
+       time_t next_clean = time_now + config->cleanup_interval;
 
        LOG(4, 0, 0, "Beginning of main loop.  udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
                udpfd, tunfd, cluster_sockfd, controlfd);
@@ -2425,7 +2405,6 @@ static void mainloop(void)
                fd_set w;
                int bgp_set[BGP_NUM_PEERS];
 #endif /* BGP */
-               int more = 0;
 
                if (config->reload_config)
                {
@@ -2464,7 +2443,7 @@ static void mainloop(void)
 
                STAT(select_called);
 
-               TIME = now(NULL);
+               TIME = now();
                if (n < 0)
                {
                        if (errno == EINTR ||
@@ -2591,7 +2570,6 @@ static void mainloop(void)
                                        config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts);
 
                                STAT(multi_read_exceeded);
-                               more++;
                        }
                }
 
@@ -2614,11 +2592,9 @@ static void mainloop(void)
                                next_cluster_ping = TIME + config->cluster_hb_interval;
                }
 
-               if (!config->cluster_iam_master)
-                       continue;
-
                        // Run token bucket filtering queue..
                        // Only run it every 1/10th of a second.
+                       // Runs on all machines both master and slave.
                {
                        static clockt last_run = 0;
                        if (last_run != TIME)
@@ -2628,42 +2604,20 @@ static void mainloop(void)
                        }
                }
 
-                       // Handle timeouts, retries etc.
-               {
-                       static double last_clean = 0;
-                       double this_clean;
-                       double diff;
-
-                       TIME = now(&this_clean);
-                       diff = this_clean - last_clean;
-
-                       // Run during idle time (after we've handled
-                       // all incoming packets) or every 1/10th sec
-                       if (!more || diff > 0.1)
-                       {
-                               regular_cleanups(diff);
-                               last_clean = this_clean;
-                       }
-               }
-
-               if (*config->accounting_dir)
+               /* 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)
                {
-                       static clockt next_acct = 0;
-                       static clockt next_shut_acct = 0;
-
-                       if (next_acct <= TIME)
+                       if (regular_cleanups())
                        {
-                               // Dump accounting data
-                               next_acct = TIME + ACCT_TIME;
-                               next_shut_acct = TIME + ACCT_SHUT_TIME;
-                               dump_acct_info(1);
+                               // Did it finish?
+                               next_clean = time_now + 1 ;     // Didn't finish. Check quickly.
                        }
-                       else if (next_shut_acct <= TIME)
+                       else
                        {
-                               // Dump accounting data for shutdown sessions
-                               next_shut_acct = TIME + ACCT_SHUT_TIME;
-                               if (shut_acct_n)
-                                       dump_acct_info(0);
+                               next_clean = time_now + config->cleanup_interval; // Did. Move to next interval.
                        }
                }
        }
@@ -3753,6 +3707,7 @@ static void update_config()
                }
        }
        memcpy(config->old_plugins, config->plugins, sizeof(config->plugins));
+       if (!config->cleanup_interval) config->cleanup_interval = 10;
        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)
index d97bd81..9dfd22a 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1,5 +1,5 @@
 // L2TPNS Global Stuff
-// $Id: l2tpns.h,v 1.49.2.15 2005/05/30 06:35:19 bodea Exp $
+// $Id: l2tpns.h,v 1.49.2.16 2005/07/03 02:40:22 bodea Exp $
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
@@ -15,7 +15,7 @@
 #include <sys/types.h>
 #include <libcli.h>
 
-#define VERSION        "2.0.22"
+#define VERSION        "2.0.23"
 
 // Limits
 #define MAXTUNNEL      500             // could be up to 65535
@@ -420,6 +420,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             multi_read_count;               // amount of packets to read per fd in processing loop
 
        char            tundevice[10];                  // tun device name
index b00361b..93ced36 100644 (file)
@@ -1,6 +1,6 @@
 Summary: A high-speed clustered L2TP LNS
 Name: l2tpns
-Version: 2.0.22
+Version: 2.0.23
 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
-* Tue May 31 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
+* Sun Jul 3 2005 Brendan O'Dea <bod@optus.net> 2.0.23-1
+- 2.0.23 release, see /usr/share/doc/l2tpns-2.0.23/Changes
index d6e3abb..a4ceea1 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -1,6 +1,6 @@
 // L2TPNS Radius Stuff
 
-char const *cvs_id_radius = "$Id: radius.c,v 1.20.2.3 2005/05/30 06:35:19 bodea Exp $";
+char const *cvs_id_radius = "$Id: radius.c,v 1.20.2.4 2005/07/03 02:40:23 bodea Exp $";
 
 #include <time.h>
 #include <stdio.h>
@@ -142,7 +142,7 @@ void radiussend(uint16_t r, uint8_t state)
        if (radius[r].state != state)
                radius[r].try = 0;
        radius[r].state = state;
-       radius[r].retry = backoff(radius[r].try++) + 20; // 3s, 4s, 6s, 10s...
+       radius[r].retry = backoff(radius[r].try++);
        LOG(4, s, session[s].tunnel, "Send RADIUS id %d sock %d state %s try %d\n",
                r >> RADIUS_SHIFT, r & RADIUS_MASK,
                radius_state(radius[r].state), radius[r].try);
@@ -691,6 +691,7 @@ void radiusretry(uint16_t r)
        if (s)
                t = session[s].tunnel;
 
+       radius[r].retry = backoff(radius[r].try + 1);
        switch (radius[r].state)
        {
                case RADIUSCHAP:           // sending CHAP down PPP