- alarm(1);
-
- {
- // Run timer hooks
- struct param_timer p = { time_now };
- run_plugins(PLUGIN_TIMER, &p);
- }
-
-}
-
-void sigterm_handler(int junk)
-{
- LOG(1, 0, 0, 0, "Shutting down cleanly\n");
- if (config->save_state)
- dump_state();
-
- main_quit++;
-}
-
-void sigquit_handler(int junk)
-{
- 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++;
-}
-
-void sigchild_handler(int signal)
-{
- while (waitpid(-1, NULL, WNOHANG) > 0)
- ;
-}
-
-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++)
- {
- if (fread(&itmp, sizeof(itmp), 1, f) != 1)
- {
- LOG(0, 0, 0, 0, "Error reading ip %d from state file: %s\n", i, strerror(errno));
- exit(1);
- }
-
- if (itmp.address != ip_address_pool[i].address)
- {
- LOG(0, 0, 0, 0, "Mismatched ip %d from state file: pool may only be extended\n", i);
- exit(1);
- }
-
- memcpy(&ip_address_pool[i], &itmp, sizeof(itmp));
- }
-
- if (fread(buf, sizeof(buf), 1, f) != 1 || buf[0] != MAXTUNNEL || buf[1] != sizeof(tunnelt))
- {
- LOG(0, 0, 0, 0, "Error/mismatch reading tunnel header from state file\n");
- exit(1);
- }
-
- LOG(2, 0, 0, 0, "Loading %u tunnels\n", MAXTUNNEL);
- if (fread(tunnel, sizeof(tunnelt), MAXTUNNEL, f) != MAXTUNNEL)
- {
- LOG(0, 0, 0, 0, "Error reading tunnel data from state file\n");
- exit(1);
- }
-
- for (i = 0; i < MAXTUNNEL; i++)
- {
- tunnel[i].controlc = 0;
- tunnel[i].controls = NULL;
- tunnel[i].controle = NULL;
- if (*tunnel[i].hostname)
- LOG(3, 0, 0, 0, "Created tunnel for %s\n", tunnel[i].hostname);
- }
-
- if (fread(buf, sizeof(buf), 1, f) != 1 || buf[0] != MAXSESSION || buf[1] != sizeof(sessiont))
- {
- LOG(0, 0, 0, 0, "Error/mismatch reading session header from state file\n");
- exit(1);
- }
-
- LOG(2, 0, 0, 0, "Loading %u sessions\n", MAXSESSION);
- if (fread(session, sizeof(sessiont), MAXSESSION, f) != MAXSESSION)
- {
- LOG(0, 0, 0, 0, "Error reading session data from state file\n");
- exit(1);
- }
-
- for (i = 0; i < MAXSESSION; i++)
- {
- session[i].tbf_in = 0;
- session[i].tbf_out = 0;
- if (session[i].opened)
- {
- LOG(2, 0, i, 0, "Loaded active session for user %s\n", session[i].user);
- if (session[i].ip)
- sessionsetup(session[i].tunnel, i);
- }
- }
-
- fclose(f);
- LOG(0, 0, 0, 0, "Loaded saved state information\n");
-}
-
-void dump_state()
-{
- FILE *f;
- u32 buf[2];
-
- if (!config->save_state)
- return;
-
- do
- {
- if (!(f = fopen(STATEFILE, "w")))
- break;
-
- LOG(1, 0, 0, 0, "Dumping state information\n");
-
- if (fwrite(DUMP_MAGIC, sizeof(DUMP_MAGIC) - 1, 1, f) != 1)
- break;
-
- LOG(2, 0, 0, 0, "Dumping %u ip addresses\n", ip_pool_size);
- buf[0] = ip_pool_size;
- buf[1] = sizeof(ippoolt);
- if (fwrite(buf, sizeof(buf), 1, f) != 1)
- break;
- if (fwrite(ip_address_pool, sizeof(ippoolt), ip_pool_size, f) != ip_pool_size)
- break;