51 #include <libxml/parser.h>
57 #include <sys/socket.h>
58 #include <sys/types.h>
63 static const char* engine_str =
"engine";
95 if (!(engine->
taskq = schedule_create())) {
101 schedule_registertask(engine->
taskq, TASK_CLASS_SIGNER, TASK_READ,
do_readzone);
103 schedule_registertask(engine->
taskq, TASK_CLASS_SIGNER, TASK_SIGN,
do_signzone);
104 schedule_registertask(engine->
taskq, TASK_CLASS_SIGNER, TASK_WRITE,
do_writezone);
111 ods_log_debug(
"[%s] start command handler", engine_str);
112 janitor_thread_create(&engine->
cmdhandler->thread_id, workerthreadclass, (janitor_runfn_t)cmdhandler_start, engine->
cmdhandler);
125 ods_log_debug(
"[%s] start dnshandler", engine_str);
135 ods_log_debug(
"[%s] stop dnshandler", engine_str);
138 ods_log_debug(
"[%s] join dnshandler", engine_str);
150 ods_log_debug(
"[%s] start xfrhandler", engine_str);
165 ods_log_debug(
"[%s] stop xfrhandler", engine_str);
168 ods_log_debug(
"[%s] join xfrhandler", engine_str);
184 ods_status status = ODS_STATUS_OK;
187 ods_log_assert(engine);
188 ods_log_assert(engine->
config);
189 ods_log_debug(
"[%s] drop privileges", engine_str);
191 ods_log_verbose(
"[%s] drop privileges to user %s, group %s",
194 ods_log_verbose(
"[%s] drop privileges to user %s", engine_str,
197 ods_log_verbose(
"[%s] drop privileges to group %s", engine_str,
201 ods_log_verbose(
"[%s] chroot to %s", engine_str,
224 ods_log_assert(engine);
225 ods_log_assert(engine->
config);
227 CHECKALLOC(engine->
workers = (worker_type**) malloc(numTotalWorkers *
sizeof(worker_type*)));
229 asprintf(&name,
"worker[%d]", i+1);
230 engine->
workers[threadCount++] = worker_create(name, engine->
taskq);
233 asprintf(&name,
"drudger[%d]", i+1);
234 engine->
workers[threadCount++] = worker_create(name, engine->
taskq);
246 ods_log_debug(
"[%s] start workers", engine_str);
254 janitor_thread_create(&
engine->
workers[threadCount]->thread_id, workerthreadclass, (janitor_runfn_t)worker_start,
engine->
workers[threadCount]);
269 ods_log_debug(
"[%s] stop workers and drudgers", engine_str);
271 for (i=0; i < numTotalWorkers; i++) {
274 ods_log_debug(
"[%s] notify workers and drudgers", engine_str);
277 for (i=0; i < numTotalWorkers; i++) {
278 ods_log_debug(
"[%s] join worker %d", engine_str, i+1);
295 ods_log_debug(
"[%s] wake up workers", engine_str);
301 signal_handler(sig_atomic_t sig)
333 ods_status status = ODS_STATUS_OK;
334 struct sigaction action;
335 int sockets[2] = {0,0};
340 ods_log_debug(
"[%s] setup signer engine", engine_str);
341 if (!engine || !engine->
config) {
342 return ODS_STATUS_ASSERT_ERR;
350 return ODS_STATUS_CMDHANDLER_ERR;
355 return ODS_STATUS_XFRHANDLER_ERR;
358 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) {
359 return ODS_STATUS_XFRHANDLER_ERR;
364 if (status != ODS_STATUS_OK) {
365 ods_log_error(
"[%s] setup: unable to listen to sockets (%s)",
366 engine_str, ods_status2str(status));
367 return ODS_STATUS_XFRHANDLER_ERR;
383 ods_log_error(
"[%s] setup: unable to chdir to %s (%s)", engine_str,
385 return ODS_STATUS_CHDIR_ERR;
387 if (engine_privdrop(engine) != ODS_STATUS_OK) {
388 return ODS_STATUS_PRIVDROP_ERR;
393 ods_log_error(
"[%s] unable to pipe: %s", engine_str, strerror(errno));
394 return ODS_STATUS_PIPE_ERR;
396 switch ((engine->
pid = fork())) {
398 ods_log_error(
"[%s] setup: unable to fork daemon (%s)",
399 engine_str, strerror(errno));
400 return ODS_STATUS_FORK_ERR;
410 while (read(pipefd[0], &buff, 1) != -1) {
411 if (buff <= 1)
break;
416 ods_log_debug(
"[%s] signerd started successfully", engine_str);
419 ods_log_error(
"[%s] fail to start signerd completely", engine_str);
422 if (setsid() == -1) {
423 ods_log_error(
"[%s] setup: unable to setsid daemon (%s)",
424 engine_str, strerror(errno));
425 const char *err =
"unable to setsid daemon: ";
426 ods_writen(pipefd[1], err, strlen(err));
427 ods_writeln(pipefd[1], strerror(errno));
428 write(pipefd[1],
"\0", 1);
430 return ODS_STATUS_SETSID_ERR;
433 engine->
pid = getpid();
437 ods_writeln(pipefd[1],
"Unable to write pid file");
438 write(pipefd[1],
"\0", 1);
441 return ODS_STATUS_WRITE_PIDFILE_ERR;
444 ods_log_verbose(
"[%s] running as pid %lu", engine_str,
445 (
unsigned long) engine->
pid);
447 action.sa_handler = (void (*)(int))signal_handler;
448 sigfillset(&action.sa_mask);
450 sigaction(SIGTERM, &action, NULL);
451 sigaction(SIGHUP, &action, NULL);
452 sigaction(SIGINT, &action, NULL);
453 sigaction(SIGILL, &action, NULL);
454 sigaction(SIGUSR1, &action, NULL);
455 sigaction(SIGALRM, &action, NULL);
456 sigaction(SIGCHLD, &action, NULL);
457 action.sa_handler = SIG_IGN;
458 sigaction(SIGPIPE, &action, NULL);
460 engine_create_workers(engine);
462 engine_start_cmdhandler(engine);
463 engine_start_dnshandler(engine);
464 engine_start_xfrhandler(engine);
467 write(pipefd[1],
"\1", 1);
470 return ODS_STATUS_OK;
484 engine_start_workers(engine);
496 ods_log_debug(
"[%s] taking a break", engine_str);
501 ods_log_debug(
"[%s] signer halted", engine_str);
502 engine_stop_threads(engine);
511 set_notify_ns(
zone_type* zone,
const char* cmd)
513 const char* str = NULL;
514 const char* str2 = NULL;
517 ods_log_assert(zone);
518 ods_log_assert(zone->
name);
523 ods_log_error(
"[%s] unable to set notify ns: replace zonefile failed",
526 str2 = ods_replace(str,
"%zone", zone->
name);
529 str2 = ods_replace(cmd,
"%zone", zone->
name);
532 ods_str_trim((
char*) str2, 1);
536 while ((token = strtok((
char*) str,
" "))) {
545 ods_log_debug(
"[%s] set notify ns: %s", engine_str, zone->
notify_ns);
547 ods_log_error(
"[%s] unable to set notify ns: replace zone failed",
561 ods_log_assert(engine);
564 ods_log_assert(zone);
567 ods_log_assert(zone->
name);
572 ods_log_debug(
"[%s] add transfer handler for zone %s",
573 engine_str, zone->
name);
576 ods_log_assert(zone->
xfrd);
583 }
else if (zone->
xfrd) {
592 ods_log_debug(
"[%s] add notify handler for zone %s",
593 engine_str, zone->
name);
596 ods_log_assert(zone->
notify);
601 }
else if (zone->
notify) {
618 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
620 ods_status status = ODS_STATUS_OK;
621 unsigned wake_up = 0;
628 ods_log_debug(
"[%s] commit zone list changes", engine_str);
631 while (node && node != LDNS_RBTREE_NULL) {
635 node = ldns_rbtree_next(node);
638 schedule_unscheduletask(engine->
taskq, schedule_WHATEVER, zone->
name);
655 if (status != ODS_STATUS_OK) {
656 ods_log_error(
"[%s] unable to load config for inbound adapter "
657 "for zone %s: %s", engine_str, zone->
name,
658 ods_status2str(status));
661 if (status != ODS_STATUS_OK) {
662 ods_log_error(
"[%s] unable to load config for outbound adapter "
663 "for zone %s: %s", engine_str, zone->
name,
664 ods_status2str(status));
667 warnings += dnsconfig_zone(engine, zone);
670 schedule_scheduletask(engine->
taskq, TASK_SIGNCONF, zone->
name, zone, &zone->
zone_lock, 0);
671 }
else if (zl_changed == ODS_STATUS_OK) {
672 schedule_scheduletask(engine->
taskq, TASK_FORCESIGNCONF, zone->
name, zone, &zone->
zone_lock, 0);
674 if (status != ODS_STATUS_OK) {
675 ods_log_crit(
"[%s] unable to schedule task for zone %s: %s",
676 engine_str, zone->
name, ods_status2str(status));
681 node = ldns_rbtree_next(node);
685 ods_log_debug(
"[%s] forward notify for all zones", engine_str);
688 }
else if (warnings) {
689 ods_log_warning(
"[%s] no dnshandler/listener configured, but zones "
690 "are configured with dns adapters: notify and zone transfer "
691 "requests will not work properly", engine_str);
706 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
708 ods_status status = ODS_STATUS_OK;
709 ods_status result = ODS_STATUS_UNCHANGED;
712 ods_log_error(
"[%s] cannot recover zones: no engine or zonelist",
714 return ODS_STATUS_ERR;
716 ods_log_assert(engine);
723 while (node && node != LDNS_RBTREE_NULL) {
729 if (status == ODS_STATUS_OK) {
730 ods_log_assert(zone->
db);
736 if (status != ODS_STATUS_OK) {
737 ods_log_crit(
"[%s] unable to schedule task for zone %s: %s",
738 engine_str, zone->
name, ods_status2str(status));
739 result = ODS_STATUS_OK;
741 ods_log_debug(
"[%s] recovered zone %s", engine_str,
747 if (status != ODS_STATUS_UNCHANGED) {
748 ods_log_warning(
"[%s] unable to recover zone %s from backup,"
749 " performing full sign", engine_str, zone->
name);
751 result = ODS_STATUS_OK;
754 node = ldns_rbtree_next(node);
767 engine_start(
const char* cfgfile,
int cmdline_verbosity,
int daemonize,
int info)
769 ods_status zl_changed = ODS_STATUS_UNCHANGED;
770 ods_status status = ODS_STATUS_OK;
772 engine = engine_create();
774 ods_fatal_exit(
"[%s] create failed", engine_str);
782 if (status != ODS_STATUS_OK) {
783 ods_log_error(
"[%s] cfgfile %s has errors", engine_str, cfgfile);
795 status = engine_setup();
796 if (status != ODS_STATUS_OK) {
797 ods_log_error(
"[%s] setup failed: %s", engine_str,
798 ods_status2str(status));
814 ods_log_info(
"[%s] signer reloading", engine_str);
817 ods_log_info(
"[%s] signer started (version %s), pid %u",
818 engine_str, PACKAGE_VERSION, engine->
pid);
820 char* error = hsm_get_error(NULL);
822 ods_log_error(
"[%s] %s",
"hsm", error);
825 ods_log_error(
"[%s] opening hsm failed (for engine recover)", engine_str);
828 zl_changed = engine_recover(engine);
831 if (zl_changed == ODS_STATUS_OK ||
832 zl_changed == ODS_STATUS_UNCHANGED) {
836 char* error = hsm_get_error(NULL);
838 ods_log_error(
"[%s] %s",
"hsm", error);
841 ods_log_error(
"[%s] opening hsm failed (for engine run)", engine_str);
849 ods_log_info(
"[%s] signer shutdown", engine_str);
851 engine_stop_xfrhandler(engine);
852 engine_stop_dnshandler(engine);
855 if (engine && engine->
config) {
887 for (i=0; i < (size_t) numTotalWorkers; i++) {
888 worker_cleanup(engine->
workers[i]);
893 schedule_cleanup(engine->
taskq);