50 #include <libxml/parser.h> 56 #include <sys/socket.h> 57 #include <sys/types.h> 62 static const char* engine_str =
"engine";
100 if (!engine->
taskq) {
105 if (!engine->
signq) {
119 cmdhandler_thread_start(
void* arg)
122 ods_thread_blocksigs();
130 ods_log_assert(engine);
131 ods_log_debug(
"[%s] start command handler", engine_str);
145 struct sockaddr_un servaddr;
146 const char* servsock_filename = ODS_SE_SOCKFILE;
147 ods_log_assert(engine);
149 sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
151 ods_log_error(
"[%s] unable to connect to command handler: " 152 "socket() failed (%s)", engine_str, strerror(errno));
155 bzero(&servaddr,
sizeof(servaddr));
156 servaddr.sun_family = AF_UNIX;
157 strncpy(servaddr.sun_path, servsock_filename,
sizeof(servaddr.sun_path)-1);
158 ret = connect(sockfd, (
const struct sockaddr*) &servaddr,
161 ods_log_error(
"[%s] unable to connect to command handler: " 162 "connect() failed (%s)", engine_str, strerror(errno));
167 ods_writen(sockfd,
"", 1);
180 ods_log_assert(engine);
184 ods_log_debug(
"[%s] stop command handler", engine_str);
186 if (self_pipe_trick(engine) == 0) {
188 ods_log_debug(
"[%s] waiting for command handler to exit...",
193 ods_log_error(
"[%s] command handler self pipe trick failed, " 194 "unclean shutdown", engine_str);
204 dnshandler_thread_start(
void* arg)
216 ods_log_debug(
"[%s] start dnshandler", engine_str);
227 ods_log_debug(
"[%s] stop dnshandler", engine_str);
230 ods_log_debug(
"[%s] join dnshandler", engine_str);
241 xfrhandler_thread_start(
void* arg)
253 ods_log_debug(
"[%s] start xfrhandler", engine_str);
269 ods_log_debug(
"[%s] stop xfrhandler", engine_str);
272 ods_log_debug(
"[%s] join xfrhandler", engine_str);
288 ods_status status = ODS_STATUS_OK;
291 ods_log_assert(engine);
292 ods_log_assert(engine->
config);
293 ods_log_debug(
"[%s] drop privileges", engine_str);
295 ods_log_verbose(
"[%s] drop privileges to user %s, group %s",
298 ods_log_verbose(
"[%s] drop privileges to user %s", engine_str,
301 ods_log_verbose(
"[%s] drop privileges to group %s", engine_str,
305 ods_log_verbose(
"[%s] chroot to %s", engine_str,
325 ods_log_assert(engine);
326 ods_log_assert(engine->
config);
336 ods_log_assert(engine);
337 ods_log_assert(engine->
config);
344 worker_thread_start(
void* arg)
347 ods_thread_blocksigs();
355 ods_log_assert(engine);
356 ods_log_assert(engine->
config);
357 ods_log_debug(
"[%s] start workers", engine_str);
369 ods_log_assert(engine);
370 ods_log_assert(engine->
config);
371 ods_log_debug(
"[%s] start drudgers", engine_str);
383 ods_log_assert(engine);
384 ods_log_assert(engine->
config);
385 ods_log_debug(
"[%s] stop workers", engine_str);
391 ods_log_debug(
"[%s] notify workers", engine_str);
395 ods_log_debug(
"[%s] join worker %d", engine_str, i+1);
404 ods_log_assert(engine);
405 ods_log_assert(engine->
config);
406 ods_log_debug(
"[%s] stop drudgers", engine_str);
411 ods_log_debug(
"[%s] notify drudgers", engine_str);
415 ods_log_debug(
"[%s] join drudger %d", engine_str, i+1);
430 ods_log_assert(engine);
431 ods_log_assert(engine->
config);
432 ods_log_debug(
"[%s] wake up workers", engine_str);
447 ods_status status = ODS_STATUS_OK;
448 struct sigaction action;
449 int sockets[2] = {0,0};
451 ods_log_debug(
"[%s] setup signer engine", engine_str);
452 if (!engine || !engine->
config) {
453 return ODS_STATUS_ASSERT_ERR;
461 return ODS_STATUS_CMDHANDLER_ERR;
466 return ODS_STATUS_XFRHANDLER_ERR;
469 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sockets) == -1) {
470 return ODS_STATUS_XFRHANDLER_ERR;
475 if (status != ODS_STATUS_OK) {
476 ods_log_error(
"[%s] setup: unable to listen to sockets (%s)",
477 engine_str, ods_status2str(status));
478 return ODS_STATUS_XFRHANDLER_ERR;
494 ods_log_error(
"[%s] setup: unable to chdir to %s (%s)", engine_str,
496 return ODS_STATUS_CHDIR_ERR;
498 if (engine_privdrop(engine) != ODS_STATUS_OK) {
499 return ODS_STATUS_PRIVDROP_ERR;
503 switch ((engine->
pid = fork())) {
505 ods_log_error(
"[%s] setup: unable to fork daemon (%s)",
506 engine_str, strerror(errno));
507 return ODS_STATUS_FORK_ERR;
518 if (setsid() == -1) {
519 ods_log_error(
"[%s] setup: unable to setsid daemon (%s)",
520 engine_str, strerror(errno));
521 return ODS_STATUS_SETSID_ERR;
524 engine->
pid = getpid();
527 return ODS_STATUS_WRITE_PIDFILE_ERR;
530 ods_log_verbose(
"[%s] running as pid %lu", engine_str,
531 (
unsigned long) engine->
pid);
535 sigfillset(&action.sa_mask);
537 sigaction(SIGTERM, &action, NULL);
538 sigaction(SIGHUP, &action, NULL);
539 sigaction(SIGINT, &action, NULL);
540 sigaction(SIGILL, &action, NULL);
541 sigaction(SIGUSR1, &action, NULL);
542 sigaction(SIGALRM, &action, NULL);
543 sigaction(SIGCHLD, &action, NULL);
544 action.sa_handler = SIG_IGN;
545 sigaction(SIGPIPE, &action, NULL);
547 engine_create_workers(engine);
548 engine_create_drudgers(engine);
550 engine_start_cmdhandler(engine);
551 engine_start_dnshandler(engine);
552 engine_start_xfrhandler(engine);
554 return ODS_STATUS_OK;
565 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
568 ods_log_assert(engine);
573 while (node && node != LDNS_RBTREE_NULL) {
575 ods_log_assert(zone);
576 ods_log_assert(zone->
db);
580 node = ldns_rbtree_next(node);
596 engine_start_workers(engine);
611 ods_log_error(
"signer instructed to reload due to explicit signal");
618 ods_log_warning(
"[%s] invalid signal %d captured, " 619 "keep running", engine_str, (
int)engine->
signal);
626 engine->
need_to_exit = engine_all_zones_processed(engine);
630 ods_log_debug(
"[%s] taking a break", engine_str);
635 ods_log_debug(
"[%s] signer halted", engine_str);
637 engine_stop_workers(engine);
646 set_notify_ns(
zone_type* zone,
const char* cmd)
648 const char* str = NULL;
649 const char* str2 = NULL;
652 ods_log_assert(zone);
653 ods_log_assert(zone->
name);
658 ods_log_error(
"[%s] unable to set notify ns: replace zonefile failed",
661 str2 = ods_replace(str,
"%zone", zone->
name);
664 str2 = ods_replace(cmd,
"%zone", zone->
name);
667 ods_str_trim((
char*) str2, 1);
671 while ((token = strtok((
char*) str,
" "))) {
680 ods_log_debug(
"[%s] set notify ns: %s", engine_str, zone->
notify_ns);
682 ods_log_error(
"[%s] unable to set notify ns: replace zone failed",
696 ods_log_assert(engine);
699 ods_log_assert(zone);
702 ods_log_assert(zone->
name);
707 ods_log_debug(
"[%s] add transfer handler for zone %s",
708 engine_str, zone->
name);
711 ods_log_assert(zone->xfrd);
713 &zone->xfrd->handler);
718 }
else if (zone->
xfrd) {
727 ods_log_debug(
"[%s] add notify handler for zone %s",
728 engine_str, zone->
name);
731 ods_log_assert(zone->notify);
733 &zone->notify->handler);
736 }
else if (zone->
notify) {
753 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
757 ods_status status = ODS_STATUS_OK;
758 unsigned wake_up = 0;
767 ods_log_debug(
"[%s] commit zone list changes", engine_str);
770 while (node && node != LDNS_RBTREE_NULL) {
775 node = ldns_rbtree_next(node);
794 ods_log_assert(!zone->
task);
803 ods_log_crit(
"[%s] unable to create task for zone %s: " 804 "task_create() failed", engine_str, zone->
name);
805 node = ldns_rbtree_next(node);
811 if (status != ODS_STATUS_OK) {
812 ods_log_error(
"[%s] unable to load config for inbound adapter " 813 "for zone %s: %s", engine_str, zone->
name,
814 ods_status2str(status));
817 if (status != ODS_STATUS_OK) {
818 ods_log_error(
"[%s] unable to load config for outbound adapter " 819 "for zone %s: %s", engine_str, zone->
name,
820 ods_status2str(status));
823 warnings += dnsconfig_zone(engine, zone);
826 ods_log_assert(task);
836 }
else if (zl_changed == ODS_STATUS_OK) {
842 if (status != ODS_STATUS_OK) {
843 ods_log_crit(
"[%s] unable to schedule task for zone %s: %s",
844 engine_str, zone->
name, ods_status2str(status));
849 node = ldns_rbtree_next(node);
853 ods_log_debug(
"[%s] forward notify for all zones", engine_str);
856 }
else if (warnings) {
857 ods_log_warning(
"[%s] no dnshandler/listener configured, but zones " 858 "are configured with dns adapters: notify and zone transfer " 859 "requests will not work properly", engine_str);
874 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
876 ods_status status = ODS_STATUS_OK;
877 ods_status result = ODS_STATUS_UNCHANGED;
880 ods_log_error(
"[%s] cannot recover zones: no engine or zonelist",
882 return ODS_STATUS_ERR;
884 ods_log_assert(engine);
891 while (node && node != LDNS_RBTREE_NULL) {
897 if (status == ODS_STATUS_OK) {
898 ods_log_assert(zone->
task);
899 ods_log_assert(zone->
db);
912 if (status != ODS_STATUS_OK) {
913 ods_log_crit(
"[%s] unable to schedule task for zone %s: %s",
914 engine_str, zone->
name, ods_status2str(status));
917 result = ODS_STATUS_OK;
919 ods_log_debug(
"[%s] recovered zone %s", engine_str,
925 if (status != ODS_STATUS_UNCHANGED) {
926 ods_log_warning(
"[%s] unable to recover zone %s from backup," 927 " performing full sign", engine_str, zone->
name);
929 result = ODS_STATUS_OK;
932 node = ldns_rbtree_next(node);
945 engine_start(
const char* cfgfile,
int cmdline_verbosity,
int daemonize,
946 int info,
int single_run)
949 ods_status zl_changed = ODS_STATUS_UNCHANGED;
950 ods_status status = ODS_STATUS_OK;
952 engine = engine_create();
954 ods_fatal_exit(
"[%s] create failed", engine_str);
962 if (status != ODS_STATUS_OK) {
963 ods_log_error(
"[%s] cfgfile %s has errors", engine_str, cfgfile);
978 status = engine_setup(engine);
979 if (status != ODS_STATUS_OK) {
980 ods_log_error(
"[%s] setup failed: %s", engine_str,
981 ods_status2str(status));
982 if (status != ODS_STATUS_WRITE_PIDFILE_ERR) {
1001 ods_log_info(
"[%s] signer reloading", engine_str);
1005 ods_log_info(
"[%s] signer started (version %s), pid %u",
1006 engine_str, PACKAGE_VERSION, engine->
pid);
1008 char* error = hsm_get_error(NULL);
1009 if (error != NULL) {
1010 ods_log_error(
"[%s] %s",
"hsm", error);
1013 ods_log_error(
"[%s] opening hsm failed (for engine recover)", engine_str);
1016 zl_changed = engine_recover(engine);
1019 if (zl_changed == ODS_STATUS_OK ||
1020 zl_changed == ODS_STATUS_UNCHANGED) {
1024 char* error = hsm_get_error(NULL);
1025 if (error != NULL) {
1026 ods_log_error(
"[%s] %s",
"hsm", error);
1029 ods_log_error(
"[%s] opening hsm failed (for engine run)", engine_str);
1032 engine_run(engine, single_run);
1037 ods_log_info(
"[%s] signer shutdown", engine_str);
1038 engine_stop_cmdhandler(engine);
1039 engine_stop_xfrhandler(engine);
1040 engine_stop_dnshandler(engine);
1043 if (engine && engine->
config) {
void engine_config_cleanup(engineconfig_type *config)
void engine_config_print(FILE *out, engineconfig_type *config)
void tsig_handler_cleanup(void)
void zone_cleanup(zone_type *zone)
#define ODS_SE_NOTIFY_CMD
void engine_wakeup_workers(engine_type *engine)
schedule_type * schedule_create()
void engine_stop_drudgers(engine_type *engine)
worker_type * worker_create(int num, worker_id type)
ods_status dnshandler_listen(dnshandler_type *dnshandler)
cond_basic_type signal_cond
cond_basic_type q_threshold
ods_status tsig_handler_init()
const char * zonelist_filename
void xfrhandler_cleanup(xfrhandler_type *xfrhandler)
void engine_update_zones(engine_type *engine, ods_status zl_changed)
ods_status adapter_load_config(adapter_type *adapter)
int engine_start(const char *cfgfile, int cmdline_verbosity, int daemonize, int info, int single_run)
ods_status zone_recover2(zone_type *zone)
ods_status schedule_task(schedule_type *schedule, task_type *task, int log)
void signal_set_engine(void *engine)
void worker_start(worker_type *worker)
lock_basic_type zone_lock
ods_thread_type thread_id
void cmdhandler_start(cmdhandler_type *cmdhandler)
void worker_cleanup(worker_type *worker)
xfrd_type * xfrd_create(xfrhandler_type *xfrhandler, zone_type *zone)
netio_handler_type dnshandler
void engine_start_drudgers(engine_type *engine)
void notify_cleanup(notify_type *notify)
adapter_type * adoutbound
void netio_add_handler(netio_type *netio, netio_handler_type *handler)
void fifoq_cleanup(fifoq_type *q)
const char * log_filename
lock_basic_type signal_lock
const char * clisock_filename
sig_atomic_t signal_capture(sig_atomic_t dflsig)
zone_type * zonelist_del_zone(zonelist_type *zlist, zone_type *zone)
engineconfig_type * config
void dnshandler_signal(dnshandler_type *dnshandler)
xfrhandler_type * xfrhandler_create()
hsm_repository_t * repositories
void xfrhandler_start(xfrhandler_type *xfrhandler)
engineconfig_type * engine_config(const char *cfgfile, int cmdline_verbosity)
void worker_notify_all(lock_basic_type *lock, cond_basic_type *condition)
const char * notify_command
notify_type * notify_create(xfrhandler_type *xfrhandler, zone_type *zone)
void task_cleanup(task_type *task)
void xfrd_cleanup(xfrd_type *xfrd, int backup)
void worker_wakeup(worker_type *worker)
void xfrhandler_signal(xfrhandler_type *xfrhandler)
task_type * unschedule_task(schedule_type *schedule, task_type *task)
#define EDNS_MAX_MESSAGE_LEN
cmdhandler_type * cmdhandler
void netio_remove_handler(netio_type *netio, netio_handler_type *handler)
void fifoq_wipe(fifoq_type *q)
ods_status zone_reschedule_task(zone_type *zone, schedule_type *taskq, task_id what)
netio_handler_type xfrhandler
ods_status engine_config_check(engineconfig_type *config)
fifoq_type * fifoq_create()
void xfrd_set_timer_now(xfrd_type *xfrd)
void edns_init(edns_data_type *data, uint16_t max_length)
listener_type * interfaces
void zonelist_cleanup(zonelist_type *zl)
cmdhandler_type * cmdhandler_create(const char *filename)
void * signal_handler(sig_atomic_t sig)
void engine_cleanup(engine_type *engine)
void schedule_cleanup(schedule_type *schedule)
ods_status zonelist_update(zonelist_type *zl, const char *zlfile)
dnshandler_type * dnshandler_create(listener_type *interfaces)
lock_basic_type schedule_lock
ods_thread_type thread_id
cond_basic_type q_nonfull
void dnshandler_start(dnshandler_type *dnshandler)
netio_handler_type handler
netio_handler_type handler
ods_thread_type thread_id
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
zonelist_type * zonelist_create()
const char * pid_filename
void cmdhandler_cleanup(cmdhandler_type *cmdhandler)
time_t serial_disk_acquired
ods_thread_type thread_id
task_type * task_create(task_id what, time_t when, void *zone)
dnshandler_type * dnshandler
xfrhandler_type * xfrhandler
void dnshandler_cleanup(dnshandler_type *dnshandler)