X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/4db668744a024bb055695bc310bec0abc357be87..8eebdb18f24364bcac9e7a3ce636bdb2e39b55db:/l2tpns.c diff --git a/l2tpns.c b/l2tpns.c index 6896717..f96ac79 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.91 2005-04-27 13:53:15 bodea Exp $"; +char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.93 2005-05-05 10:02:07 bodea Exp $"; #include #include @@ -69,7 +69,7 @@ time_t basetime = 0; // base clock char hostname[1000] = ""; // us. static int tunidx; // ifr_ifindex of tun device 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). +static FILE *log_stream = 0; // 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; // Unique ID for radius accounting @@ -110,6 +110,7 @@ config_descriptt config_values[] = { CONFIG("primary_radius_port", radiusport[0], SHORT), CONFIG("secondary_radius_port", radiusport[1], SHORT), CONFIG("radius_accounting", radius_accounting, BOOL), + CONFIG("radius_interim", radius_interim, INT), CONFIG("radius_secret", radiussecret, STRING), CONFIG("radius_authtypes", radius_authtypes_s, STRING), CONFIG("bind_address", bind_address, IPv4), @@ -1455,7 +1456,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error) if (session[s].ip && !walled_garden && !session[s].die) { // RADIUS Stop message - uint16_t r = session[s].radius; + uint16_t r = sess_local[s].radius; if (!r) { if (!(r = radiusnew(s))) @@ -1537,7 +1538,7 @@ void sessionshutdown(sessionidt s, char *reason, int result, int error) void sendipcp(tunnelidt t, sessionidt s) { uint8_t buf[MAXCONTROL]; - uint16_t r = session[s].radius; + uint16_t r = sess_local[s].radius; uint8_t *q; CSTAT(sendipcp); @@ -1616,8 +1617,8 @@ void sessionkill(sessionidt s, char *reason) session[s].die = TIME; 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 (sess_local[s].radius) + radiusclear(sess_local[s].radius, s); // cant send clean accounting data, session is killed LOG(2, s, session[s].tunnel, "Kill session %d (%s): %s\n", s, session[s].user, reason); @@ -2189,16 +2190,17 @@ void processudp(uint8_t * buf, int len, struct sockaddr_in *addr) } case 31: // Proxy Authentication Challenge { - memcpy(radius[session[s].radius].auth, b, 16); LOG(4, s, t, " Proxy Auth Challenge\n"); + if (sess_local[s].radius) + memcpy(radius[sess_local[s].radius].auth, b, 16); break; } case 32: // Proxy Authentication ID { uint16_t authid = ntohs(*(uint16_t *)(b)); LOG(4, s, t, " Proxy Auth ID (%d)\n", authid); - if (session[s].radius) - radius[session[s].radius].id = authid; + if (sess_local[s].radius) + radius[sess_local[s].radius].id = authid; break; } case 33: // Proxy Authentication Response @@ -2618,19 +2620,22 @@ static int regular_cleanups(void) if (!session[s].opened) // Session isn't in use continue; - if (!session[s].die && session[s].ip && !(session[s].flags & SF_IPCP_ACKED)) + // check for expired sessions + if (session[s].die) { - // 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); + if (session[s].die <= TIME) + { + sessionkill(s, "Expired"); + if (++count >= MAX_ACTIONS) break; + } + continue; } - // check for expired sessions - if (session[s].die && session[s].die <= TIME) + if (session[s].ip && !(session[s].flags & SF_IPCP_ACKED)) { - sessionkill(s, "Expired"); - if (++count >= MAX_ACTIONS) break; - continue; + // 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); } // Drop sessions who have not responded within IDLE_TIMEOUT seconds @@ -2729,6 +2734,31 @@ static int regular_cleanups(void) if (++count >= MAX_ACTIONS) break; } + + // RADIUS interim accounting + if (config->radius_accounting && config->radius_interim > 0 + && session[s].ip && !session[s].walled_garden + && !sess_local[s].radius // RADIUS already in progress + && time_now - sess_local[s].last_interim >= config->radius_interim) + { + if (!radiusnew(s)) + { + LOG(1, s, session[s].tunnel, "No free RADIUS sessions for Interim message\n"); + STAT(radius_overflow); + continue; + } + + random_data(radius[r].auth, sizeof(radius[r].auth)); + + LOG(3, s, session[s].tunnel, "Sending RADIUS Interim for %s (%u)\n", + session[s].user, session[s].unique_id); + + radiussend(r, RADIUSINTERIM); + sess_local[s].last_interim = time_now; + + if (++count >= MAX_ACTIONS) + break; + } } if (*config->accounting_dir) @@ -3141,16 +3171,12 @@ static void initdata(int optdebug, char *optconfig) { int i; - if (!(_statistics = shared_malloc(sizeof(struct Tstats)))) - { - LOG(0, 0, 0, "Error doing malloc for _statistics: %s\n", strerror(errno)); - exit(1); - } if (!(config = shared_malloc(sizeof(configt)))) { - LOG(0, 0, 0, "Error doing malloc for configuration: %s\n", strerror(errno)); + fprintf(stderr, "Error doing malloc for configuration: %s\n", strerror(errno)); exit(1); } + memset(config, 0, sizeof(configt)); time(&config->start_time); strncpy(config->config_file, optconfig, strlen(optconfig)); @@ -3159,6 +3185,22 @@ static void initdata(int optdebug, char *optconfig) config->rl_rate = 28; // 28kbps strcpy(config->random_device, RANDOMDEVICE); + log_stream = stderr; + +#ifdef RINGBUFFER + if (!(ringbuffer = shared_malloc(sizeof(struct Tringbuffer)))) + { + LOG(0, 0, 0, "Error doing malloc for ringbuffer: %s\n", strerror(errno)); + exit(1); + } + memset(ringbuffer, 0, sizeof(struct Tringbuffer)); +#endif + + if (!(_statistics = shared_malloc(sizeof(struct Tstats)))) + { + LOG(0, 0, 0, "Error doing malloc for _statistics: %s\n", strerror(errno)); + exit(1); + } if (!(tunnel = shared_malloc(sizeof(tunnelt) * MAXTUNNEL))) { LOG(0, 0, 0, "Error doing malloc for tunnels: %s\n", strerror(errno)); @@ -3195,15 +3237,6 @@ static void initdata(int optdebug, char *optconfig) } memset(ip_filters, 0, sizeof(ip_filtert) * MAXFILTER); -#ifdef RINGBUFFER - if (!(ringbuffer = shared_malloc(sizeof(struct Tringbuffer)))) - { - LOG(0, 0, 0, "Error doing malloc for ringbuffer: %s\n", strerror(errno)); - exit(1); - } - memset(ringbuffer, 0, sizeof(struct Tringbuffer)); -#endif - if (!(cli_session_actions = shared_malloc(sizeof(struct cli_session_actions) * MAXSESSION))) { LOG(0, 0, 0, "Error doing malloc for cli session actions: %s\n", strerror(errno)); @@ -3771,9 +3804,11 @@ int main(int argc, char *argv[]) static void sighup_handler(int sig) { - if (log_stream && log_stream != stderr) + if (log_stream) { - fclose(log_stream); + if (log_stream != stderr) + fclose(log_stream); + log_stream = NULL; } @@ -3895,7 +3930,9 @@ static void update_config() syslog_log = 0; if (log_stream) { - fclose(log_stream); + if (log_stream != stderr) + fclose(log_stream); + log_stream = NULL; }