43 #include <ldns/ldns.h> 48 #include <sys/select.h> 49 #include <sys/socket.h> 50 #ifdef HAVE_SYS_TYPES_H 51 # include <sys/types.h> 56 #include <sys/types.h> 58 #define SE_CMDH_CMDLEN 7 61 #define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) 65 static char* cmdh_str =
"cmdhandler";
73 cmdhandler_handle_cmd_help(
int sockfd)
75 char buf[ODS_SE_MAXLINE];
77 (void) snprintf(buf, ODS_SE_MAXLINE,
79 "zones Show the currently known zones.\n" 80 "sign <zone> [--serial <nr>] Read zone and schedule for immediate " 82 " If a serial is given, that serial is used " 83 "in the output zone.\n" 84 "sign --all Read all zones and schedule all for " 85 "immediate (re-)sign.\n" 89 (void) snprintf(buf, ODS_SE_MAXLINE,
90 "clear <zone> Delete the internal storage of this " 92 " All signatures will be regenerated " 93 "on the next re-sign.\n" 94 "queue Show the current task queue.\n" 95 "flush Execute all scheduled tasks " 100 (void) snprintf(buf, ODS_SE_MAXLINE,
101 "update <zone> Update this zone signer " 103 "update [--all] Update zone list and all signer " 105 "retransfer <zone> Retransfer the zone from the master.\n" 106 "start Start the engine.\n" 107 "running Check if the engine is running.\n" 108 "reload Reload the engine.\n" 109 "stop Stop the engine.\n" 110 "verbosity <nr> Set verbosity.\n" 125 char buf[ODS_SE_MAXLINE];
127 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
133 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have no zones configured\n");
139 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have %i zones configured\n",
144 while (node && node != LDNS_RBTREE_NULL) {
146 for (i=0; i < ODS_SE_MAXLINE; i++) {
149 (void)snprintf(buf, ODS_SE_MAXLINE,
"- %s\n", zone->
name);
151 node = ldns_rbtree_next(node);
167 char buf[ODS_SE_MAXLINE];
181 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has not changed." 182 " Signer configurations updated.\n");
185 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list updated: %i " 186 "removed, %i added, %i updated.\n",
193 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has errors.\n");
222 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
226 cmdhandler_handle_cmd_update(sockfd, cmdc,
"--all");
235 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Unable to reschedule " 236 "task for zone %s.\n", tbd);
238 ods_log_crit(
"[%s] unable to reschedule task for zone %s: %s",
241 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s config being updated.\n",
244 ods_log_verbose(
"[%s] zone %s scheduled for immediate update signconf",
258 cmdhandler_handle_cmd_retransfer(
int sockfd,
cmdhandler_type* cmdc,
char* tbd)
261 char buf[ODS_SE_MAXLINE];
280 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
285 (void)snprintf(buf, ODS_SE_MAXLINE,
286 "Error: Zone %s not configured to use DNS input adapter.\n",
296 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s being retransferred.\n", tbd);
304 max(uint32_t a, uint32_t b)
315 cmdhandler_handle_cmd_sign(
int sockfd,
cmdhandler_type* cmdc,
const char* tbd)
320 char buf[ODS_SE_MAXLINE];
332 (void)snprintf(buf, ODS_SE_MAXLINE,
"All zones scheduled for " 333 "immediate re-sign.\n");
339 char* delim1 = strchr(tbd,
' ');
341 int force_serial = 0;
346 if (strncmp(delim1+1,
"--serial ", 9) != 0) {
347 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Expecting <zone> " 348 "--serial <nr>, got %s.\n", tbd);
352 delim2 = strchr(delim1+1,
' ');
354 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Expecting serial.\n");
358 serial = (uint32_t) strtol(delim2+1, &end, 10);
360 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Expecting serial, " 361 "got %s.\n", delim2+1);
380 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
392 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Unable to enforce " 393 "serial %u for zone %s.\n", serial, tbd);
404 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Unable to reschedule " 405 "task for zone %s.\n", tbd);
407 ods_log_crit(
"[%s] unable to reschedule task for zone %s: %s",
410 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s scheduled for " 411 "immediate re-sign.\n", tbd);
427 unlink_backup_file(
const char* filename,
const char* extension)
433 free((
void*)tmpname);
443 cmdhandler_handle_cmd_clear(
int sockfd,
cmdhandler_type* cmdc,
const char* tbd)
447 char buf[ODS_SE_MAXLINE];
449 uint32_t inbserial = 0;
450 uint32_t intserial = 0;
451 uint32_t outserial = 0;
456 unlink_backup_file(tbd,
".inbound");
457 unlink_backup_file(tbd,
".backup");
458 unlink_backup_file(tbd,
".axfr");
459 unlink_backup_file(tbd,
".ixfr");
479 "signconf, ixfr of db structure (out of memory?)", cmdh_str, tbd);
492 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Unable to reschedule " 493 "task for zone %s.\n", tbd);
494 ods_log_crit(
"[%s] unable to reschedule task for zone %s: %s",
497 (void)snprintf(buf, ODS_SE_MAXLINE,
"Internal zone information about " 498 "%s cleared", tbd?tbd:
"(null)");
499 ods_log_info(
"[%s] internal zone information about %s cleared",
500 cmdh_str, tbd?tbd:
"(null)");
503 (void)snprintf(buf, ODS_SE_MAXLINE,
"Cannot clear zone %s, zone not " 504 "found", tbd?tbd:
"(null)");
506 cmdh_str, tbd?tbd:
"(null)");
521 char* strtime = NULL;
522 char buf[ODS_SE_MAXLINE];
525 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
531 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have no tasks scheduled.\n");
537 strtime = ctime(&now);
538 (void)snprintf(buf, ODS_SE_MAXLINE,
"It is now %s",
539 strtime?strtime:
"(null)");
546 (void)snprintf(buf, ODS_SE_MAXLINE,
"Working with task %s on " 554 (void)snprintf(buf, ODS_SE_MAXLINE,
"\nI have %i tasks scheduled.\n",
558 node = ldns_rbtree_first(engine->
taskq->
tasks);
559 while (node && node != LDNS_RBTREE_NULL) {
561 for (i=0; i < ODS_SE_MAXLINE; i++) {
564 (void)
task2str(task, (
char*) &buf[0]);
566 node = ldns_rbtree_next(node);
581 char buf[ODS_SE_MAXLINE];
590 (void)snprintf(buf, ODS_SE_MAXLINE,
"All tasks scheduled immediately.\n");
605 char buf[ODS_SE_MAXLINE];
613 (void)snprintf(buf, ODS_SE_MAXLINE,
"Reloading engine.\n");
627 char buf[ODS_SE_MAXLINE];
635 (void)snprintf(buf, ODS_SE_MAXLINE, ODS_SE_STOP_RESPONSE);
646 cmdhandler_handle_cmd_start(
int sockfd)
648 char buf[ODS_SE_MAXLINE];
649 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine already running.\n");
660 cmdhandler_handle_cmd_running(
int sockfd)
662 char buf[ODS_SE_MAXLINE];
663 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine running.\n");
674 cmdhandler_handle_cmd_verbosity(
int sockfd,
cmdhandler_type* cmdc,
int val)
677 char buf[ODS_SE_MAXLINE];
684 (void)snprintf(buf, ODS_SE_MAXLINE,
"Verbosity level set to %i.\n", val);
695 cmdhandler_handle_cmd_error(
int sockfd,
const char* str)
697 char buf[ODS_SE_MAXLINE];
698 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: %s.\n", str?str:
"(null)");
709 cmdhandler_handle_cmd_unknown(
int sockfd,
const char* str)
711 char buf[ODS_SE_MAXLINE];
712 (void)snprintf(buf, ODS_SE_MAXLINE,
"Unknown command %s.\n",
742 char buf[ODS_SE_MAXLINE];
748 while ((n = read(sockfd, buf, ODS_SE_MAXLINE)) > 0) {
756 if (n == 4 && strncmp(buf,
"help", n) == 0) {
758 cmdhandler_handle_cmd_help(sockfd);
759 }
else if (n == 5 && strncmp(buf,
"zones", n) == 0) {
761 cmdhandler_handle_cmd_zones(sockfd, cmdc);
762 }
else if (n >= 4 && strncmp(buf,
"sign", 4) == 0) {
764 if (n == 4 || buf[4] ==
'\0') {
766 cmdhandler_handle_cmd_error(sockfd,
"sign command needs " 767 "an argument (either '--all' or a zone name)");
768 }
else if (buf[4] !=
' ') {
769 cmdhandler_handle_cmd_unknown(sockfd, buf);
771 cmdhandler_handle_cmd_sign(sockfd, cmdc, &buf[5]);
773 }
else if (n >= 5 && strncmp(buf,
"clear", 5) == 0) {
775 if (n == 5 || buf[5] ==
'\0') {
776 cmdhandler_handle_cmd_error(sockfd,
"clear command needs " 778 }
else if (buf[5] !=
' ') {
779 cmdhandler_handle_cmd_unknown(sockfd, buf);
781 cmdhandler_handle_cmd_clear(sockfd, cmdc, &buf[6]);
783 }
else if (n == 5 && strncmp(buf,
"queue", n) == 0) {
785 cmdhandler_handle_cmd_queue(sockfd, cmdc);
786 }
else if (n == 5 && strncmp(buf,
"flush", n) == 0) {
788 cmdhandler_handle_cmd_flush(sockfd, cmdc);
789 }
else if (n >= 6 && strncmp(buf,
"update", 6) == 0) {
791 if (n == 6 || buf[6] ==
'\0') {
792 cmdhandler_handle_cmd_update(sockfd, cmdc,
"--all");
793 }
else if (buf[6] !=
' ') {
794 cmdhandler_handle_cmd_unknown(sockfd, buf);
796 cmdhandler_handle_cmd_update(sockfd, cmdc, &buf[7]);
798 }
else if (n == 4 && strncmp(buf,
"stop", n) == 0) {
800 cmdhandler_handle_cmd_stop(sockfd, cmdc);
802 }
else if (n == 5 && strncmp(buf,
"start", n) == 0) {
804 cmdhandler_handle_cmd_start(sockfd);
805 }
else if (n == 6 && strncmp(buf,
"reload", n) == 0) {
807 cmdhandler_handle_cmd_reload(sockfd, cmdc);
808 }
else if (n == 7 && strncmp(buf,
"running", n) == 0) {
810 cmdhandler_handle_cmd_running(sockfd);
811 }
else if (n >= 9 && strncmp(buf,
"verbosity", 9) == 0) {
813 if (n == 9 || buf[9] ==
'\0') {
814 cmdhandler_handle_cmd_error(sockfd,
"verbosity command " 815 "an argument (verbosity level)");
816 }
else if (buf[9] !=
' ') {
817 cmdhandler_handle_cmd_unknown(sockfd, buf);
819 cmdhandler_handle_cmd_verbosity(sockfd, cmdc, atoi(&buf[10]));
821 }
else if (n >= 10 && strncmp(buf,
"retransfer", 10) == 0) {
823 if (n == 10 || buf[10] ==
'\0') {
824 cmdhandler_handle_cmd_error(sockfd,
"retransfer command needs " 825 "an argument (a zone name)");
826 }
else if (buf[10] !=
' ') {
827 cmdhandler_handle_cmd_unknown(sockfd, buf);
829 cmdhandler_handle_cmd_retransfer(sockfd, cmdc, &buf[11]);
833 cmdhandler_handle_cmd_unknown(sockfd, buf);
835 ods_log_debug(
"[%s] done handling command %s[%i]", cmdh_str, buf, n);
840 if (n < 0 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) ) {
842 }
else if (n < 0 && errno == ECONNRESET) {
846 ods_log_error(
"[%s] read error: %s", cmdh_str, strerror(errno));
857 cmdhandler_accept_client(
void* arg)
865 cmdhandler_handle_cmd(cmdc);
884 struct sockaddr_un servaddr;
889 if (!allocator || !filename) {
894 listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
897 "socket() failed (%s)", cmdh_str, strerror(errno));
901 flags = fcntl(listenfd, F_GETFL, 0);
904 "fcntl(F_GETFL) failed (%s)", cmdh_str, strerror(errno));
909 if (fcntl(listenfd, F_SETFL, flags) < 0) {
911 "fcntl(F_SETFL) failed (%s)", cmdh_str, strerror(errno));
917 (void)unlink(filename);
919 bzero(&servaddr,
sizeof(servaddr));
920 servaddr.sun_family = AF_UNIX;
921 strncpy(servaddr.sun_path, filename,
sizeof(servaddr.sun_path) - 1);
922 #ifdef HAVE_SOCKADDR_SUN_LEN 923 servaddr.sun_len = strlen(servaddr.sun_path);
926 ret = bind(listenfd, (
const struct sockaddr*) &servaddr,
930 "bind() failed (%s)", cmdh_str, strerror(errno));
937 "listen() failed (%s)", cmdh_str, strerror(errno));
946 "allocator_alloc() failed", cmdh_str);
965 struct sockaddr_un cliaddr;
979 clilen =
sizeof(cliaddr);
981 ret = select(cmdhandler->
listen_fd+1, &rset, NULL, NULL, NULL);
983 if (errno != EINTR && errno != EWOULDBLOCK) {
989 if (FD_ISSET(cmdhandler->
listen_fd, &rset)) {
991 (
struct sockaddr *) &cliaddr, &clilen);
993 if (errno != EINTR && errno != EWOULDBLOCK) {
1002 ods_log_crit(
"[%s] unable to create thread for client: " 1003 "malloc() failed", cmdh_str);
1015 ods_log_debug(
"[%s] %i clients in progress...", cmdh_str, count);
1019 engine = cmdhandler->
engine;
signconf_type * signconf_create(void)
void ixfr_cleanup(ixfr_type *ixfr)
#define ODS_SE_NOTIFY_CMD
void ods_thread_blocksigs(void)
void engine_wakeup_workers(engine_type *engine)
void ods_log_debug(const char *format,...)
cond_basic_type signal_cond
void * allocator_alloc(allocator_type *allocator, size_t size)
const char * zonelist_filename
void engine_update_zones(engine_type *engine, ods_status zl_changed)
void signconf_cleanup(signconf_type *sc)
void namedb_cleanup(namedb_type *db)
cmdhandler_type * cmdhandler_create(allocator_type *allocator, const char *filename)
void ods_fatal_exit(const char *format,...)
void ods_log_info(const char *format,...)
const char * task_who2str(task_type *task)
enum ods_enum_status ods_status
lock_basic_type zone_lock
void schedule_flush(schedule_type *schedule, task_id override)
ods_thread_type thread_id
void ods_log_error(const char *format,...)
const char * ods_status2str(ods_status status)
int ods_strcmp(const char *s1, const char *s2)
void cmdhandler_start(cmdhandler_type *cmdhandler)
struct sockaddr_un listen_addr
int util_serial_gt(uint32_t serial_new, uint32_t serial_old)
#define ODS_SE_MAX_HANDLERS
void ods_log_crit(const char *format,...)
const char * log_filename
lock_basic_type signal_lock
#define lock_basic_lock(lock)
void ods_str_trim(char *str)
engineconfig_type * config
ssize_t ods_writen(int fd, const void *vptr, size_t n)
allocator_type * allocator
ods_status zone_reschedule_task(zone_type *zone, schedule_type *taskq, task_id what)
namedb_type * namedb_create(void *zone)
char * ods_build_path(const char *file, const char *suffix, int dir, int no_slash)
#define ods_thread_detach(thr)
void ods_log_verbose(const char *format,...)
zone_type * zonelist_lookup_zone_by_name(zonelist_type *zonelist, const char *name, ldns_rr_class klass)
void xfrd_set_timer_now(xfrd_type *xfrd)
uint8_t serial_retransfer
void allocator_deallocate(allocator_type *allocator, void *data)
ods_status zonelist_update(zonelist_type *zl, const char *zlfile)
char * task2str(task_type *task, char *buftask)
lock_basic_type schedule_lock
#define ods_log_assert(x)
#define ods_thread_create(thr, func, arg)
void ods_log_init(const char *filename, int use_syslog, int verbosity)
ixfr_type * ixfr_create(void *zone)
#define lock_basic_alarm(cond)
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
#define lock_basic_unlock(lock)
void ods_log_warning(const char *format,...)
void cmdhandler_cleanup(cmdhandler_type *cmdhandler)
const char * task_what2str(task_id what)
dnshandler_type * dnshandler