/* We only use privsep to get in-kernel SADB and SPD snapshots via sysctl */ void monitor_loop(void) { u_int32_t v, vn; ssize_t r; fd_set rfds; int ret; struct timeval *tvp, tv; FD_ZERO(&rfds); tvp = NULL; vn = 0; for (;;) { ret = 0; v = 0; if (sigchld) { pid_t pid; int status; do { pid = waitpid(m_state.pid, &status, WNOHANG); } while (pid == -1 && errno == EINTR); if (pid == m_state.pid && (WIFEXITED(status) || WIFSIGNALED(status))) break; } FD_SET(m_state.s, &rfds); if (select(m_state.s + 1, &rfds, NULL, NULL, tvp) == -1) { if (errno == EINTR || errno == EAGAIN) continue; log_err(0, "monitor_loop: select() "); break; } /* Wait for next task */ if (FD_ISSET(m_state.s, &rfds)) { if ((r = m_read(m_state.s, &v, sizeof v)) < 1) { if (r == -1) log_err(0, "monitor_loop: read() "); break; } } /* Retry after timeout */ if (v == 0 && tvp != NULL) { v = vn; tvp = NULL; vn = 0; } switch (v) { case MONITOR_GETSNAP: /* Get the data. */ m_priv_pfkey_snap(m_state.s); break; case MONITOR_CARPINC: carp_demote(CARP_INC, 1); break; case MONITOR_CARPDEC: carp_demote(CARP_DEC, 1); break; case MONITOR_CONTROL_ACTIVATE: ret = m_priv_control_activate(); break; case MONITOR_CONTROL_PASSIVATE: ret = m_priv_control_passivate(); break; } if (ret == -1) { /* Trigger retry after timeout */ tv.tv_sec = MONITOR_RETRY_TIMEOUT; tv.tv_usec = 0; tvp = &tv; vn = v; } } monitor_carpundemote(NULL); if (!sigchld) log_msg(0, "monitor_loop: priv process exiting abnormally"); exit(0); }
int main(int argc, char **argv) { extern char *__progname; char *cfgfile = 0; int ch; if (geteuid() != 0) { /* No point in continuing. */ fprintf(stderr, "%s: This daemon needs to be run as root.\n", __progname); return 1; } while ((ch = getopt(argc, argv, "c:dv")) != -1) { switch (ch) { case 'c': if (cfgfile) usage(); cfgfile = optarg; break; case 'd': cfgstate.debug++; break; case 'v': cfgstate.verboselevel++; break; default: usage(); } } argc -= optind; argv += optind; if (argc > 0) usage(); log_init(__progname); timer_init(); cfgstate.runstate = INIT; LIST_INIT(&cfgstate.peerlist); cfgstate.listen_port = SASYNCD_DEFAULT_PORT; cfgstate.flags |= CTL_DEFAULT; if (!cfgfile) cfgfile = SASYNCD_CFGFILE; if (conf_parse_file(cfgfile) == 0 ) { if (!cfgstate.sharedkey) { fprintf(stderr, "config: " "no shared key specified, cannot continue"); exit(1); } } else { exit(1); } carp_demote(CARP_INC, 0); if (carp_init()) return 1; if (pfkey_init(0)) return 1; if (net_init()) return 1; if (!cfgstate.debug) if (daemon(1, 0)) { perror("daemon()"); exit(1); } if (monitor_init()) { /* Parent, with privileges. */ monitor_loop(); exit(0); } /* Child, no privileges left. Run main loop. */ sasyncd_run(getppid()); /* Shutdown. */ log_msg(0, "shutting down..."); net_shutdown(); pfkey_shutdown(); return 0; }