add result/error codes to CDN; use "try another" on out of IP addresses
authorBrendan O'Dea <bod@optus.net>
Thu, 10 Mar 2005 06:16:05 +0000 (06:16 +0000)
committerBrendan O'Dea <bod@optus.net>
Thu, 10 Mar 2005 06:16:05 +0000 (06:16 +0000)
Changes
l2tpns.c
l2tpns.h
ppp.c
radius.c

diff --git a/Changes b/Changes
index 1652cab..cf623df 100644 (file)
--- a/Changes
+++ b/Changes
 - Simplify AVP unhiding code.
 - Add optional "username" parameter to ungarden control, allowing the
   username to be reset before going online.
 - Simplify AVP unhiding code.
 - Add optional "username" parameter to ungarden control, allowing the
   username to be reset before going online.
-- Add result/error codes to StopCCN when shutting down tunnels.
+- Add result/error codes and message to StopCCN when shutting down tunnels.
+- Add result/error codes to CDN when shutting down sessions.  Sends 2/7
+  (general error, try another LNS) when out of IP addresses, and 3
+  (adminstrative) for everything else (suggestion from Chris Gates).
 
 * Fri Dec 17 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.13
 - Better cluster master collision resolution: keep a counter of state
 
 * Fri Dec 17 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.13
 - Better cluster master collision resolution: keep a counter of state
index b988b78..9e34768 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.86 2005-03-10 05:47:24 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.87 2005-03-10 06:16:05 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -1433,7 +1433,7 @@ static void filter_session(sessionidt s, int filter_in, int filter_out)
 }
 
 // start tidy shutdown of session
 }
 
 // start tidy shutdown of session
-void sessionshutdown(sessionidt s, char *reason)
+void sessionshutdown(sessionidt s, char *reason, int result, int code)
 {
        int walled_garden = session[s].walled_garden;
 
 {
        int walled_garden = session[s].walled_garden;
 
@@ -1508,9 +1508,19 @@ void sessionshutdown(sessionidt s, char *reason)
        if (session[s].throttle_in || session[s].throttle_out) // Unthrottle if throttled.
                throttle_session(s, 0, 0);
 
        if (session[s].throttle_in || session[s].throttle_out) // Unthrottle if throttled.
                throttle_session(s, 0, 0);
 
+       if (result)
        {                            // Send CDN
                controlt *c = controlnew(14); // sending CDN
        {                            // Send CDN
                controlt *c = controlnew(14); // sending CDN
-               control16(c, 1, 3, 1);    // result code (admin reasons - TBA make error, general error, add message
+               if (error)
+               {
+                       char buf[4];
+                       *(uint16_t *) buf     = htons(result);
+                       *(uint16_t *) (buf+2) = htons(error);
+                       controlb(c, 1, buf, 4, 1);
+               }
+               else
+                       control16(c, 1, result, 1);
+
                control16(c, 14, s, 1);   // assigned session (our end)
                controladd(c, session[s].tunnel, s); // send the message
        }
                control16(c, 14, s, 1);   // assigned session (our end)
                controladd(c, session[s].tunnel, s); // send the message
        }
@@ -1546,7 +1556,7 @@ void sendipcp(tunnelidt t, sessionidt s)
        if (radius[r].try > 10)
        {
                radiusclear(r, s);      // Clear radius session.
        if (radius[r].try > 10)
        {
                radiusclear(r, s);      // Clear radius session.
-               sessionshutdown(s, "No reply on IPCP");
+               sessionshutdown(s, "No reply on IPCP", 3, 0);
                return;
        }
 
                return;
        }
 
@@ -1606,7 +1616,7 @@ void sessionkill(sessionidt s, char *reason)
        }
 
        session[s].die = TIME;
        }
 
        session[s].die = TIME;
-       sessionshutdown(s, reason);  // close radius/routes, etc.
+       sessionshutdown(s, reason, 3, 0);  // close radius/routes, etc.
        if (session[s].radius)
                radiusclear(session[s].radius, s); // cant send clean accounting data, session is killed
 
        if (session[s].radius)
                radiusclear(session[s].radius, s); // cant send clean accounting data, session is killed
 
@@ -1676,7 +1686,7 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
        // close session
        for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
                if (session[s].tunnel == t)
        // close session
        for (s = 1; s <= config->cluster_highest_sessionid ; ++s)
                if (session[s].tunnel == t)
-                       sessionshutdown(s, reason);
+                       sessionshutdown(s, reason, 3, 0);
 
        tunnel[t].state = TUNNELDIE;
        tunnel[t].die = TIME + 700; // Clean up in 70 seconds
 
        tunnel[t].state = TUNNELDIE;
        tunnel[t].die = TIME + 700; // Clean up in 70 seconds
@@ -2341,7 +2351,7 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr)
                                        break;
                                case 14:      // CDN
                                        controlnull(t); // ack
                                        break;
                                case 14:      // CDN
                                        controlnull(t); // ack
-                                       sessionshutdown(s, "Closed (Received CDN)");
+                                       sessionshutdown(s, "Closed (Received CDN)", 0, 0);
                                        break;
                                case 0xFFFF:
                                        LOG(1, s, t, "Missing message type\n");
                                        break;
                                case 0xFFFF:
                                        LOG(1, s, t, "Missing message type\n");
@@ -2628,7 +2638,7 @@ static int regular_cleanups(void)
                // Drop sessions who have not responded within IDLE_TIMEOUT seconds
                if (session[s].last_packet && (time_now - session[s].last_packet >= IDLE_TIMEOUT))
                {
                // Drop sessions who have not responded within IDLE_TIMEOUT seconds
                if (session[s].last_packet && (time_now - session[s].last_packet >= IDLE_TIMEOUT))
                {
-                       sessionshutdown(s, "No response to LCP ECHO requests");
+                       sessionshutdown(s, "No response to LCP ECHO requests", 3, 0);
                        STAT(session_timeout);
                        if (++count >= MAX_ACTIONS) break;
                        continue;
                        STAT(session_timeout);
                        if (++count >= MAX_ACTIONS) break;
                        continue;
@@ -2662,7 +2672,7 @@ static int regular_cleanups(void)
                        if (a & CLI_SESS_KILL)
                        {
                                LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
                        if (a & CLI_SESS_KILL)
                        {
                                LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
-                               sessionshutdown(s, "Requested by administrator");
+                               sessionshutdown(s, "Requested by administrator", 3, 0);
                                a = 0; // dead, no need to check for other actions
                        }
 
                                a = 0; // dead, no need to check for other actions
                        }
 
@@ -4105,7 +4115,7 @@ int sessionsetup(tunnelidt t, sessionidt s)
                if (!session[s].ip)
                {
                        LOG(0, s, t, "   No IP allocated.  The IP address pool is FULL!\n");
                if (!session[s].ip)
                {
                        LOG(0, s, t, "   No IP allocated.  The IP address pool is FULL!\n");
-                       sessionshutdown(s, "No IP addresses available");
+                       sessionshutdown(s, "No IP addresses available", 2, 7);
                        return 0;
                }
                LOG(3, s, t, "   No IP allocated.  Assigned %s from pool\n",
                        return 0;
                }
                LOG(3, s, t, "   No IP allocated.  Assigned %s from pool\n",
index 9786bff..562feee 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1,5 +1,5 @@
 // L2TPNS Global Stuff
 // L2TPNS Global Stuff
-// $Id: l2tpns.h,v 1.59 2005-03-10 05:46:55 bodea Exp $
+// $Id: l2tpns.h,v 1.60 2005-03-10 06:16:05 bodea Exp $
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
@@ -617,7 +617,7 @@ sessionidt sessionbyipv6(struct in6_addr ip);
 sessionidt sessionbyuser(char *username);
 void random_data(uint8_t *buf, int len);
 void sessionkill(sessionidt s, char *reason);
 sessionidt sessionbyuser(char *username);
 void random_data(uint8_t *buf, int len);
 void sessionkill(sessionidt s, char *reason);
-void sessionshutdown(sessionidt s, char *reason);
+void sessionshutdown(sessionidt s, char *reason, int result, error);
 void send_garp(in_addr_t ip);
 void tunnelsend(uint8_t *buf, uint16_t l, tunnelidt t);
 void sendipcp(tunnelidt t, sessionidt s);
 void send_garp(in_addr_t ip);
 void tunnelsend(uint8_t *buf, uint16_t l, tunnelidt t);
 void sendipcp(tunnelidt t, sessionidt s);
diff --git a/ppp.c b/ppp.c
index d48c044..328c14b 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -1,6 +1,6 @@
 // L2TPNS PPP Stuff
 
 // L2TPNS PPP Stuff
 
-char const *cvs_id_ppp = "$Id: ppp.c,v 1.45 2005-03-10 03:31:25 bodea Exp $";
+char const *cvs_id_ppp = "$Id: ppp.c,v 1.46 2005-03-10 06:16:05 bodea Exp $";
 
 #include <stdio.h>
 #include <string.h>
 
 #include <stdio.h>
 #include <string.h>
@@ -488,11 +488,11 @@ void processlcp(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
                q = makeppp(b, sizeof(b),  p, l, t, s, PPPLCP);
                if (!q) return;
                tunnelsend(b, l + (q - b), t); // send it
                q = makeppp(b, sizeof(b),  p, l, t, s, PPPLCP);
                if (!q) return;
                tunnelsend(b, l + (q - b), t); // send it
-               sessionshutdown(s, "Remote end closed connection.");
+               sessionshutdown(s, "Remote end closed connection.", 3, 0);
        }
        else if (*p == TerminateAck)
        {
        }
        else if (*p == TerminateAck)
        {
-               sessionshutdown(s, "Connection closed.");
+               sessionshutdown(s, "Connection closed.", 3, 0);
        }
        else if (*p == ProtocolRej)
        {
        }
        else if (*p == ProtocolRej)
        {
@@ -1105,7 +1105,7 @@ void sendchap(tunnelidt t, sessionidt s)
        radius[r].retry = backoff(radius[r].try++);
        if (radius[r].try > 5)
        {
        radius[r].retry = backoff(radius[r].try++);
        if (radius[r].try > 5)
        {
-               sessionshutdown(s, "Timeout CHAP");
+               sessionshutdown(s, "Timeout CHAP", 3, 0);
                STAT(tunnel_tx_errors);
                return ;
        }
                STAT(tunnel_tx_errors);
                return ;
        }
index 6a206ea..1e09792 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -1,6 +1,6 @@
 // L2TPNS Radius Stuff
 
 // L2TPNS Radius Stuff
 
-char const *cvs_id_radius = "$Id: radius.c,v 1.24 2005-02-14 06:58:39 bodea Exp $";
+char const *cvs_id_radius = "$Id: radius.c,v 1.25 2005-03-10 06:16:05 bodea Exp $";
 
 #include <time.h>
 #include <stdio.h>
 
 #include <time.h>
 #include <stdio.h>
@@ -140,7 +140,7 @@ void radiussend(uint16_t r, uint8_t state)
                if (s)
                {
                        if (state == RADIUSAUTH)
                if (s)
                {
                        if (state == RADIUSAUTH)
-                               sessionshutdown(s, "RADIUS timeout");
+                               sessionshutdown(s, "RADIUS timeout", 3, 0);
                        else
                        {
                                LOG(1, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n",
                        else
                        {
                                LOG(1, s, session[s].tunnel, "RADIUS timeout, but in state %s so don't timeout session\n",