void rde_shutdown(void) { rt_clear(); msgbuf_clear(&iev_ripe->ibuf.w); free(iev_ripe); msgbuf_clear(&iev_main->ibuf.w); free(iev_main); free(rdeconf); log_info("route decision engine exiting"); _exit(0); }
void lde_shutdown(void) { lde_nbr_clear(); rt_clear(); msgbuf_clear(&iev_ldpe->ibuf.w); free(iev_ldpe); msgbuf_clear(&iev_main->ibuf.w); free(iev_main); free(ldeconf); log_info("label decision engine exiting"); _exit(0); }
/* * Reinitialize a message buffer, retaining its previous contents if * the size and checksum are correct. If the old contents cannot be * recovered, the message buffer is cleared. */ void msgbuf_reinit(struct msgbuf *mbp, void *ptr, int size) { u_int cksum; if (mbp->msg_magic != MSG_MAGIC || mbp->msg_size != size) { msgbuf_init(mbp, ptr, size); return; } mbp->msg_seqmod = SEQMOD(size); mbp->msg_wseq = MSGBUF_SEQNORM(mbp, mbp->msg_wseq); mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq); mbp->msg_ptr = ptr; cksum = msgbuf_cksum(mbp); if (cksum != mbp->msg_cksum) { if (bootverbose) { printf("msgbuf cksum mismatch (read %x, calc %x)\n", mbp->msg_cksum, cksum); printf("Old msgbuf not recovered\n"); } msgbuf_clear(mbp); } mbp->msg_lastpri = -1; /* Assume that the old message buffer didn't end in a newline. */ mbp->msg_flags |= MSGBUF_NEEDNL; bzero(&mbp->msg_lock, sizeof(mbp->msg_lock)); mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN); }
void control_close(int fd, struct control_sock *cs) { struct ctl_conn *c; if ((c = control_connbyfd(fd)) == NULL) { log_warn("control_close: fd %d: not found", fd); return; } msgbuf_clear(&c->iev.ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); event_del(&c->iev.ev); close(c->iev.ibuf.fd); /* Some file descriptors are available again. */ if (evtimer_pending(&cs->cs_evt, NULL)) { evtimer_del(&cs->cs_evt); event_add(&cs->cs_ev, NULL); } npppd_ctl_destroy(c->ctx); free(c); }
void control_close(struct ctl_conn *c, const char *msg, struct imsg *imsg) { struct control_sock *cs = c->cs; if (imsg) { log_debug("%s: fd %d: %s, imsg %d datalen %zu", __func__, c->iev.ibuf.fd, msg, imsg->hdr.type, IMSG_DATA_SIZE(imsg)); imsg_free(imsg); } else log_debug("%s: fd %d: %s", __func__, c->iev.ibuf.fd, msg); msgbuf_clear(&c->iev.ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); event_del(&c->iev.ev); close(c->iev.ibuf.fd); /* Some file descriptors are available again. */ if (evtimer_pending(&cs->cs_evt, NULL)) { evtimer_del(&cs->cs_evt); event_add(&cs->cs_ev, NULL); } free(c); }
void imsgev_clear(struct imsgev *iev) { event_del(&iev->ev); msgbuf_clear(&iev->ibuf.w); close(iev->ibuf.fd); }
void imsg_clear(struct imsgbuf *ibuf) { int fd; msgbuf_clear(&ibuf->w); while ((fd = imsg_get_fd(ibuf)) != -1) close(fd); }
/* * Initialize a message buffer of the specified size at the specified * location. This also zeros the buffer area. */ void msgbuf_init(struct msgbuf *mbp, void *ptr, int size) { mbp->msg_ptr = ptr; mbp->msg_size = size; mbp->msg_seqmod = SEQMOD(size); msgbuf_clear(mbp); mbp->msg_magic = MSG_MAGIC; }
/* * Initialize a message buffer of the specified size at the specified * location. This also zeros the buffer area. */ void msgbuf_init(struct msgbuf *mbp, void *ptr, int size) { mbp->msg_ptr = ptr; mbp->msg_size = size; mbp->msg_seqmod = SEQMOD(size); msgbuf_clear(mbp); mbp->msg_magic = MSG_MAGIC; mbp->msg_lastpri = -1; mbp->msg_flags = 0; bzero(&mbp->msg_lock, sizeof(mbp->msg_lock)); mtx_init(&mbp->msg_lock, "msgbuf", NULL, MTX_SPIN); }
void control_close(int fd) { struct ctl_conn *c; if ((c = control_connbyfd(fd)) == NULL) { log_warn("control_close: fd %d: not found", fd); return; } msgbuf_clear(&c->iev.ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); event_del(&c->iev.ev); close(c->iev.ibuf.fd); free(c); accept_unpause(); }
/* * Reinitialize a message buffer, retaining its previous contents if * the size and checksum are correct. If the old contents cannot be * recovered, the message buffer is cleared. */ void msgbuf_reinit(struct msgbuf *mbp, void *ptr, int size) { u_int cksum; if (mbp->msg_magic != MSG_MAGIC || mbp->msg_size != size) { msgbuf_init(mbp, ptr, size); return; } mbp->msg_seqmod = SEQMOD(size); mbp->msg_wseq = MSGBUF_SEQNORM(mbp, mbp->msg_wseq); mbp->msg_rseq = MSGBUF_SEQNORM(mbp, mbp->msg_rseq); mbp->msg_ptr = ptr; cksum = msgbuf_cksum(mbp); if (cksum != mbp->msg_cksum) { if (bootverbose) { printf("msgbuf cksum mismatch (read %x, calc %x)\n", mbp->msg_cksum, cksum); printf("Old msgbuf not recovered\n"); } msgbuf_clear(mbp); } }
void control_close(int fd) { struct ctl_conn *c; if ((c = control_connbyfd(fd)) == NULL) { log_warnx("%s: fd %d: not found", __func__, fd); return; } msgbuf_clear(&c->iev.ibuf.w); TAILQ_REMOVE(&ctl_conns, c, entry); event_del(&c->iev.ev); close(c->iev.ibuf.fd); /* Some file descriptors are available again. */ if (evtimer_pending(&control_state.evt, NULL)) { evtimer_del(&control_state.evt); event_add(&control_state.ev, NULL); } free(c); }
int main(int argc, char *argv[]) { struct ntpd_conf lconf; struct pollfd pfd[POLL_MAX]; pid_t chld_pid = 0, pid; const char *conffile; int fd_ctl, ch, nfds; int pipe_chld[2]; struct passwd *pw; extern char *__progname; if (strcmp(__progname, "ntpctl") == 0) { ctl_main(argc, argv); /* NOTREACHED */ } conffile = CONFFILE; bzero(&lconf, sizeof(lconf)); log_init(1); /* log to stderr until daemonized */ while ((ch = getopt(argc, argv, "df:nsSv")) != -1) { switch (ch) { case 'd': lconf.debug = 1; log_verbose(1); break; case 'f': conffile = optarg; break; case 'n': lconf.noaction = 1; break; case 's': lconf.settime = 1; break; case 'S': lconf.settime = 0; break; case 'v': log_verbose(1); break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc > 0) usage(); if (parse_config(conffile, &lconf)) exit(1); if (lconf.noaction) { fprintf(stderr, "configuration OK\n"); exit(0); } if (geteuid()) errx(1, "need root privileges"); if ((pw = getpwnam(NTPD_USER)) == NULL) errx(1, "unknown user %s", NTPD_USER); if (setpriority(PRIO_PROCESS, 0, -20) == -1) warn("can't set priority"); reset_adjtime(); if (!lconf.settime) { log_init(lconf.debug); if (!lconf.debug) if (daemon(1, 0)) fatal("daemon"); } else timeout = SETTIME_TIMEOUT * 1000; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_chld) == -1) fatal("socketpair"); if ((fd_ctl = control_init(CTLSOCKET)) == -1) fatalx("control socket init failed"); if (control_listen(fd_ctl) == -1) fatalx("control socket listen failed"); signal(SIGCHLD, sighdlr); /* fork child process */ chld_pid = ntp_main(pipe_chld, fd_ctl, &lconf, pw); setproctitle("[priv]"); readfreq(); signal(SIGTERM, sighdlr); signal(SIGINT, sighdlr); signal(SIGHUP, sighdlr); close(pipe_chld[1]); if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) fatal(NULL); imsg_init(ibuf, pipe_chld[0]); while (quit == 0) { pfd[PFD_PIPE].fd = ibuf->fd; pfd[PFD_PIPE].events = POLLIN; if (ibuf->w.queued) pfd[PFD_PIPE].events |= POLLOUT; if ((nfds = poll(pfd, 1, timeout)) == -1) if (errno != EINTR) { log_warn("poll error"); quit = 1; } if (nfds == 0 && lconf.settime) { lconf.settime = 0; timeout = INFTIM; log_init(lconf.debug); log_warnx("no reply received in time, skipping initial " "time setting"); if (!lconf.debug) if (daemon(1, 0)) fatal("daemon"); } if (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT)) if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) { log_warn("pipe write error (to child)"); quit = 1; } if (nfds > 0 && pfd[PFD_PIPE].revents & POLLIN) { nfds--; if (dispatch_imsg(&lconf) == -1) quit = 1; } if (sigchld) { if (check_child(chld_pid, "child")) { quit = 1; chld_pid = 0; } sigchld = 0; } } signal(SIGCHLD, SIG_DFL); if (chld_pid) kill(chld_pid, SIGTERM); do { if ((pid = wait(NULL)) == -1 && errno != EINTR && errno != ECHILD) fatal("wait"); } while (pid != -1 || (pid == -1 && errno == EINTR)); msgbuf_clear(&ibuf->w); free(ibuf); log_info("Terminating"); return (0); }
int tnt_fork(int imsg_fds[2]) { pid_t pid; struct imsgbuf ibuf; struct imsg_data data; struct passwd *pw; struct event_base *evbase = NULL; struct event *sigterm = NULL; struct event *sigint = NULL; struct event *imsg_event = NULL; struct server server; struct event_config *evcfg; switch ((pid = fork())) { case -1: log_err(TNT_OSERR, "fork"); break; case 0: tnt_setproctitle("[unpriv]"); log_set_prefix("unpriv"); break; default: tnt_setproctitle("[priv]"); log_set_prefix("priv"); return pid; } if ((pw = getpwnam(TNETACLE_USER)) == NULL) { log_errx(1, "unknown user " TNETACLE_USER); return TNT_NOUSER; } /*Allocate the event config*/ evcfg = event_config_new(); /* Initialize the OpenSSL library */ SSL_library_init(); SSL_load_error_strings(); /* We MUST have entropy, or else there's no point to crypto. */ if (!RAND_poll()) { log_errx(TNT_SOFTWARE, "[INIT] failed to find an entropy source"); /* never returns */ } if (serv_opts.encryption) server.server_ctx = evssl_init(); else server.server_ctx = NULL; tnt_priv_drop(pw); #if defined(Darwin) /* It's sad isn't it ?*/ event_config_avoid_method(evcfg, "kqueue"); event_config_avoid_method(evcfg, "poll"); event_config_avoid_method(evcfg, "devpoll"); if ((evbase = event_base_new_with_config(evcfg)) == NULL) { log_err(1, "libevent"); } #else if ((evbase = event_base_new_with_config(evcfg)) == NULL) { log_err(1, "libevent"); } #endif sigterm = event_new(evbase, SIGTERM, EV_SIGNAL, &chld_sighdlr, evbase); sigint = event_new(evbase, SIGINT, EV_SIGNAL, &chld_sighdlr, evbase); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, SIG_IGN); signal(SIGCHLD, SIG_DFL); if (server_init(&server, evbase) == -1) log_errx(1, "failed to init the server socket"); data.ibuf = &ibuf; data.evbase = evbase; data.server = &server; imsg_event = init_pipe_endpoint(imsg_fds, &data); event_add(sigterm, NULL); event_add(sigint, NULL); event_add(imsg_event, NULL); log_info("tnetacle ready"); /* Immediately request the creation of a tun interface */ imsg_compose(&ibuf, IMSG_CREATE_DEV, 0, 0, -1, NULL, 0); log_info("starting event loop"); event_base_dispatch(evbase); /* cleanely exit */ msgbuf_write(&ibuf.w); msgbuf_clear(&ibuf.w); /* Shutdown the server */ server_delete(&server); /* * It may look like we freed this one twice, * once here and once in tnetacled.c but this is not the case. * Please don't erase this ! */ event_free(sigterm); event_free(sigint); close(event_get_fd(imsg_event)); event_free(imsg_event); event_base_free(evbase); event_config_free(evcfg); log_info("tnetacle exiting"); exit(TNT_OK); }
int main(int argc, char *argv[]) { struct ntpd_conf conf; struct pollfd pfd[POLL_MAX]; pid_t chld_pid = 0, pid; const char *conffile; int ch, nfds, timeout = INFTIM; int pipe_chld[2]; extern char *__progname; __progname = _compat_get_progname(argv[0]); conffile = CONFFILE; bzero(&conf, sizeof(conf)); log_init(1); /* log to stderr until daemonized */ res_init(); /* XXX */ while ((ch = getopt(argc, argv, "df:sS")) != -1) { switch (ch) { case 'd': conf.debug = 1; break; case 'f': conffile = optarg; break; case 's': conf.settime = 1; break; case 'S': conf.settime = 0; break; default: usage(); /* NOTREACHED */ } } if (parse_config(conffile, &conf)) exit(1); if (geteuid()) { fprintf(stderr, "ntpd: need root privileges\n"); exit(1); } if (getpwnam(NTPD_USER) == NULL) { fprintf(stderr, "ntpd: unknown user %s\n", NTPD_USER); exit(1); } endpwent(); #ifndef HAVE_ARC4RANDOM seed_rng(); #endif if (!conf.settime) { log_init(conf.debug); if (!conf.debug) if (daemon(1, 0)) fatal("daemon"); } else timeout = SETTIME_TIMEOUT * 1000; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_chld) == -1) fatal("socketpair"); /* fork child process */ chld_pid = ntp_main(pipe_chld, &conf); setproctitle("[priv]"); signal(SIGTERM, sighdlr); signal(SIGINT, sighdlr); signal(SIGCHLD, sighdlr); signal(SIGHUP, sighdlr); close(pipe_chld[1]); if ((ibuf = malloc(sizeof(struct imsgbuf))) == NULL) fatal(NULL); imsg_init(ibuf, pipe_chld[0]); while (quit == 0) { pfd[PFD_PIPE].fd = ibuf->fd; pfd[PFD_PIPE].events = POLLIN; if (ibuf->w.queued) pfd[PFD_PIPE].events |= POLLOUT; if ((nfds = poll(pfd, 1, timeout)) == -1) if (errno != EINTR) { log_warn("poll error"); quit = 1; } if (nfds == 0 && conf.settime) { conf.settime = 0; timeout = INFTIM; // RCP // log_init(conf.debug); // log_debug("no reply received in time, skipping initial " // "time setting"); // if (!conf.debug) // if (daemon(1, 0)) // fatal("daemon"); // RCP system("/opt/rcp/bin/rcplog 5 \"no replay received in time, restarting NTP\""); break; // RCP } if (nfds > 0 && (pfd[PFD_PIPE].revents & POLLOUT)) if (msgbuf_write(&ibuf->w) < 0) { log_warn("pipe write error (to child)"); quit = 1; } if (nfds > 0 && pfd[PFD_PIPE].revents & POLLIN) { nfds--; if (dispatch_imsg(&conf) == -1) quit = 1; } if (sigchld) { if (check_child(chld_pid, "child")) { quit = 1; chld_pid = 0; } sigchld = 0; } } signal(SIGCHLD, SIG_DFL); if (chld_pid) kill(chld_pid, SIGTERM); do { if ((pid = wait(NULL)) == -1 && errno != EINTR && errno != ECHILD) fatal("wait"); } while (pid != -1 || (pid == -1 && errno == EINTR)); msgbuf_clear(&ibuf->w); free(ibuf); // log_info("Terminating"); return (0); }