- if (config->scheduler_fifo)
- {
- int ret;
- struct sched_param params = {0};
- params.sched_priority = 1;
-
- if (get_nprocs() < 2)
- {
- LOG(0, 0, 0, 0, "Not using FIFO scheduler, there is only 1 processor in the system.\n");
- config->scheduler_fifo = 0;
- }
- else
- {
- if ((ret = sched_setscheduler(0, SCHED_FIFO, ¶ms)) == 0)
- {
- LOG(1, 0, 0, 0, "Using FIFO scheduler. Say goodbye to any other processes running\n");
- }
- else
- {
- LOG(0, 0, 0, 0, "Error setting scheduler to FIFO: %s\n", strerror(errno));
- config->scheduler_fifo = 0;
- }
- }
- }
-
- /* Set up the cluster communications port. */
- if (cluster_init() < 0)
- exit(1);
-
-#ifdef BGP
- signal(SIGPIPE, SIG_IGN);
- bgp_setup(config->as_number);
- bgp_add_route(config->bind_address, 0xffffffff);
- for (i = 0; i < BGP_NUM_PEERS; i++)
- {
- if (config->neighbour[i].name[0])
- bgp_start(&bgp_peers[i], config->neighbour[i].name,
- config->neighbour[i].as, config->neighbour[i].keepalive,
- config->neighbour[i].hold, 0); /* 0 = routing disabled */
- }
-#endif /* BGP */
-
- inittun();
- LOG(1, 0, 0, 0, "Set up on interface %s\n", config->tundevice);
-
- initudp();
- initrad();
- initippool();
-
- read_state();
-
- signal(SIGHUP, sighup_handler);
- signal(SIGTERM, sigterm_handler);
- signal(SIGINT, sigterm_handler);
- signal(SIGQUIT, sigquit_handler);
- signal(SIGCHLD, sigchild_handler);
-
- // Prevent us from getting paged out
- if (config->lock_pages)
- {
- if (!mlockall(MCL_CURRENT))
- LOG(1, 0, 0, 0, "Locking pages into memory\n");
- else
- LOG(0, 0, 0, 0, "Can't lock pages: %s\n", strerror(errno));
- }
-
- alarm(1);
-
- // Drop privileges here
- if (config->target_uid > 0 && geteuid() == 0)
- setuid(config->target_uid);
-
- mainloop();
-
-#ifdef BGP
- /* try to shut BGP down cleanly; with luck the sockets will be
- writable since we're out of the select */
- for (i = 0; i < BGP_NUM_PEERS; i++)
- if (bgp_peers[i].state == Established)
- bgp_stop(&bgp_peers[i]);
-#endif /* BGP */
-
- /* remove plugins (so cleanup code gets run) */
- plugins_done();
-
- // Remove the PID file if we wrote it
- if (config->wrote_pid && *config->pid_file == '/')
- unlink(config->pid_file);
-
- /* kill CLI children */
- signal(SIGTERM, SIG_IGN);
- kill(0, SIGTERM);
- return 0;
-}
-
-static void sighup_handler(int sig)
-{
- if (log_stream && log_stream != stderr)
- {
- fclose(log_stream);
- log_stream = NULL;
- }
-
- read_config_file();
-}
-
-static void sigalrm_handler(int sig)
-{
- // Log current traffic stats
-
- snprintf(config->bandwidth, sizeof(config->bandwidth),
- "UDP-ETH:%1.0f/%1.0f ETH-UDP:%1.0f/%1.0f TOTAL:%0.1f IN:%u OUT:%u",
- (udp_rx / 1024.0 / 1024.0 * 8),
- (eth_tx / 1024.0 / 1024.0 * 8),
- (eth_rx / 1024.0 / 1024.0 * 8),
- (udp_tx / 1024.0 / 1024.0 * 8),
- ((udp_tx + udp_rx + eth_tx + eth_rx) / 1024.0 / 1024.0 * 8),
- udp_rx_pkt, eth_rx_pkt);
-
- udp_tx = udp_rx = 0;
- udp_rx_pkt = eth_rx_pkt = 0;
- eth_tx = eth_rx = 0;
-
- if (config->dump_speed)
- printf("%s\n", config->bandwidth);
-
- // Update the internal time counter
- time(&time_now);
- strftime(time_now_string, sizeof(time_now_string), "%Y-%m-%d %H:%M:%S", localtime(&time_now));
- alarm(1);
-
- {
- // Run timer hooks
- struct param_timer p = { time_now };
- run_plugins(PLUGIN_TIMER, &p);
- }
-
-}
-
-static void sigterm_handler(int sig)
-{
- LOG(1, 0, 0, 0, "Shutting down cleanly\n");
- if (config->save_state)
- dump_state();
-
- main_quit++;
-}
-
-static void sigquit_handler(int sig)
-{
- int i;
-
- LOG(1, 0, 0, 0, "Shutting down without saving sessions\n");
- for (i = 1; i < MAXSESSION; i++)
- {
- if (session[i].opened)
- sessionkill(i, "L2TPNS Closing");
- }
- for (i = 1; i < MAXTUNNEL; i++)
- {
- if (tunnel[i].ip || tunnel[i].state)
- tunnelshutdown(i, "L2TPNS Closing");
- }
-
- main_quit++;
-}
-
-static void sigchild_handler(int sig)
-{
- while (waitpid(-1, NULL, WNOHANG) > 0)
- ;
-}
-
-static void read_state()
-{
- struct stat sb;
- int i;
- ippoolt itmp;
- FILE *f;
- char magic[sizeof(DUMP_MAGIC) - 1];
- u32 buf[2];
-
- if (!config->save_state)
- {
- unlink(STATEFILE);
- return ;
- }
-
- if (stat(STATEFILE, &sb) < 0)
- {
- unlink(STATEFILE);
- return ;
- }
-
- if (sb.st_mtime < (time(NULL) - 60))
- {
- LOG(0, 0, 0, 0, "State file is too old to read, ignoring\n");
- unlink(STATEFILE);
- return ;
- }
-
- f = fopen(STATEFILE, "r");
- unlink(STATEFILE);
-
- if (!f)
- {
- LOG(0, 0, 0, 0, "Can't read state file: %s\n", strerror(errno));
- exit(1);
- }
-
- if (fread(magic, sizeof(magic), 1, f) != 1 || strncmp(magic, DUMP_MAGIC, sizeof(magic)))
- {
- LOG(0, 0, 0, 0, "Bad state file magic\n");
- exit(1);
- }
-
- LOG(1, 0, 0, 0, "Reading state information\n");
- if (fread(buf, sizeof(buf), 1, f) != 1 || buf[0] > MAXIPPOOL || buf[1] != sizeof(ippoolt))
- {
- LOG(0, 0, 0, 0, "Error/mismatch reading ip pool header from state file\n");
- exit(1);
- }
-
- if (buf[0] > ip_pool_size)
- {
- LOG(0, 0, 0, 0, "ip pool has shrunk! state = %d, current = %d\n", buf[0], ip_pool_size);
- exit(1);
- }
-
- LOG(2, 0, 0, 0, "Loading %u ip addresses\n", buf[0]);
- for (i = 0; i < buf[0]; i++)