From 57aa5ef53d3515024f1af84bffa0ffe13482b3b7 Mon Sep 17 00:00:00 2001 From: Brendan O'Dea Date: Thu, 10 Mar 2005 06:16:05 +0000 Subject: [PATCH] add result/error codes to CDN; use "try another" on out of IP addresses --- Changes | 5 ++++- l2tpns.c | 30 ++++++++++++++++++++---------- l2tpns.h | 4 ++-- ppp.c | 8 ++++---- radius.c | 4 ++-- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/Changes b/Changes index 1652cab..cf623df 100644 --- a/Changes +++ b/Changes @@ -35,7 +35,10 @@ - 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 2.0.13 - Better cluster master collision resolution: keep a counter of state diff --git a/l2tpns.c b/l2tpns.c index b988b78..9e34768 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.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 #include @@ -1433,7 +1433,7 @@ static void filter_session(sessionidt s, int filter_in, int filter_out) } // 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; @@ -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 (result) { // 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 } @@ -1546,7 +1556,7 @@ void sendipcp(tunnelidt t, sessionidt s) 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; } @@ -1606,7 +1616,7 @@ void sessionkill(sessionidt s, char *reason) } 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 @@ -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) - sessionshutdown(s, reason); + sessionshutdown(s, reason, 3, 0); 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 - sessionshutdown(s, "Closed (Received CDN)"); + sessionshutdown(s, "Closed (Received CDN)", 0, 0); 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)) { - 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; @@ -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"); - sessionshutdown(s, "Requested by administrator"); + sessionshutdown(s, "Requested by administrator", 3, 0); 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"); - 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", diff --git a/l2tpns.h b/l2tpns.h index 9786bff..562feee 100644 --- a/l2tpns.h +++ b/l2tpns.h @@ -1,5 +1,5 @@ // 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__ @@ -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); -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); diff --git a/ppp.c b/ppp.c index d48c044..328c14b 100644 --- a/ppp.c +++ b/ppp.c @@ -1,6 +1,6 @@ // 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 #include @@ -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 - sessionshutdown(s, "Remote end closed connection."); + sessionshutdown(s, "Remote end closed connection.", 3, 0); } else if (*p == TerminateAck) { - sessionshutdown(s, "Connection closed."); + sessionshutdown(s, "Connection closed.", 3, 0); } 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) { - sessionshutdown(s, "Timeout CHAP"); + sessionshutdown(s, "Timeout CHAP", 3, 0); STAT(tunnel_tx_errors); return ; } diff --git a/radius.c b/radius.c index 6a206ea..1e09792 100644 --- a/radius.c +++ b/radius.c @@ -1,6 +1,6 @@ // 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 #include @@ -140,7 +140,7 @@ void radiussend(uint16_t r, uint8_t state) 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", -- 2.20.1