X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/fec37812053f43cbe8dda9efbc91aa0f45bedbc3..715e74f4c7f18be79bf019f53ce3404382413f99:/l2tpns.c?ds=sidebyside diff --git a/l2tpns.c b/l2tpns.c index 7b809c3..fdaba0c 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.91 2005/04/27 13:53:15 bodea Exp $"; #include #include @@ -68,11 +68,10 @@ static int rand_fd = -1; // Random data source time_t basetime = 0; // base clock char hostname[1000] = ""; // us. static int tunidx; // ifr_ifindex of tun device -static uint32_t sessionid = 0; // session id for radius accounting static int syslog_log = 0; // are we logging to syslog static FILE *log_stream = NULL; // file handle for direct logging (i.e. direct into file, not via syslog). extern int cluster_sockfd; // Intra-cluster communications socket. -uint32_t last_id = 0; // Last used PPP SID. Can I kill this?? -- mo +uint32_t last_id = 0; // Unique ID for radius accounting struct cli_session_actions *cli_session_actions = NULL; // Pending session changes requested by CLI struct cli_tunnel_actions *cli_tunnel_actions = NULL; // Pending tunnel changes required by CLI @@ -1433,7 +1432,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 error) { int walled_garden = session[s].walled_garden; @@ -1453,7 +1452,7 @@ void sessionshutdown(sessionidt s, char *reason) run_plugins(PLUGIN_KILL_SESSION, &data); } - if (!walled_garden && !session[s].die) + if (session[s].ip && !walled_garden && !session[s].die) { // RADIUS Stop message uint16_t r = session[s].radius; @@ -1508,9 +1507,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 +1555,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 to IPCP.", 3, 0); return; } @@ -1606,7 +1615,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 +1685,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 @@ -2309,7 +2318,6 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr) } c = controlnew(11); // sending ICRP - session[s].id = sessionid++; session[s].opened = time_now; session[s].tunnel = t; session[s].far = asession; @@ -2341,7 +2349,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,13 +2636,13 @@ 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; } - // No data in IDLE_TIMEOUT seconds, send LCP ECHO + // No data in ECHO_TIMEOUT seconds, send LCP ECHO if (session[s].user[0] && (time_now - session[s].last_packet >= ECHO_TIMEOUT)) { uint8_t b[MAXCONTROL] = {0}; @@ -2662,7 +2670,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 +4113,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",