47 #include <ldns/ldns.h>
52 #include <sys/select.h>
53 #include <sys/socket.h>
54 #ifdef HAVE_SYS_TYPES_H
55 # include <sys/types.h>
60 #include <sys/types.h>
62 #define SE_CMDH_CMDLEN 7
65 #define SUN_LEN(su) (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path))
69 static char* cmdh_str =
"cmdhandler";
77 cmdhandler_handle_cmd_help(
int sockfd)
79 char buf[ODS_SE_MAXLINE];
81 (void) snprintf(buf, ODS_SE_MAXLINE,
83 "zones show the currently known zones.\n"
84 "sign <zone> read zone and schedule for immediate (re-)sign.\n"
85 "sign --all read all zones and schedule all for immediate "
87 "clear <zone> delete the internal storage of this zone.\n"
88 " All signatures will be regenerated on the next "
90 "queue show the current task queue.\n"
94 (void) snprintf(buf, ODS_SE_MAXLINE,
95 "flush execute all scheduled tasks immediately.\n"
96 "update <zone> update this zone signer configurations.\n"
97 "update [--all] update zone list and all signer configurations.\n"
98 "start start the engine.\n"
99 "running check if the engine is running.\n"
100 "reload reload the engine.\n"
101 "stop stop the engine.\n"
102 "verbosity <nr> set verbosity.\n"
116 char buf[ODS_SE_MAXLINE];
118 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
124 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have no zones configured\n");
132 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have %i zones configured\n",
138 while (node && node != LDNS_RBTREE_NULL) {
140 for (i=0; i < ODS_SE_MAXLINE; i++) {
143 (void)snprintf(buf, ODS_SE_MAXLINE,
"- %s\n", zone->
name);
145 node = ldns_rbtree_next(node);
161 char buf[ODS_SE_MAXLINE];
180 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has not changed."
181 " Signer configurations updated.\n");
185 ods_log_debug(
"[%s] signer configurations updated", cmdh_str);
187 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list updated: %i "
188 "removed, %i added, %i updated.\n",
201 ods_log_debug(
"[%s] signer configurations updated", cmdh_str);
204 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has errors.\n");
222 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s not found.\n",
226 cmdhandler_handle_cmd_update(sockfd, cmdc,
"--all");
250 "signconf as soon as possible", cmdh_str, zone->
name);
261 ods_log_crit(
"[%s] cannot schedule task for zone %s: %s",
269 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s config being updated.\n",
282 cmdhandler_handle_cmd_sign(
int sockfd,
cmdhandler_type* cmdc,
const char* tbd)
287 char buf[ODS_SE_MAXLINE];
301 (void)snprintf(buf, ODS_SE_MAXLINE,
"All zones scheduled for "
302 "immediate re-sign.\n");
320 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s not found.\n",
345 "zone input as soon as possible", cmdh_str, zone->
name);
357 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Cannot schedule task for "
360 ods_log_crit(
"[%s] cannot schedule task for zone %s: %s",
365 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s scheduled for immediate "
382 unlink_backup_file(
const char* filename,
const char* extension)
387 free((
void*)tmpname);
396 cmdhandler_handle_cmd_clear(
int sockfd,
cmdhandler_type* cmdc,
const char* tbd)
398 char buf[ODS_SE_MAXLINE];
401 uint32_t inbound_serial = 0;
402 uint32_t internal_serial = 0;
403 uint32_t outbound_serial = 0;
410 unlink_backup_file(tbd,
".inbound");
411 unlink_backup_file(tbd,
".backup");
443 " reloading signconf", cmdh_str, zone->
name);
449 " zone %s, reloading signconf", cmdh_str, zone->
name);
456 " for zone %s, reloading signconf", cmdh_str, zone->
name);
462 (void)snprintf(buf, ODS_SE_MAXLINE,
"Internal zone information about "
463 "%s cleared", tbd?tbd:
"(null)");
464 ods_log_info(
"[%s] internal zone information about %s cleared",
465 cmdh_str, tbd?tbd:
"(null)");
467 (void)snprintf(buf, ODS_SE_MAXLINE,
"Cannot clear zone %s, zone not "
468 "found", tbd?tbd:
"(null)");
470 cmdh_str, tbd?tbd:
"(null)");
485 char* strtime = NULL;
486 char buf[ODS_SE_MAXLINE];
489 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
495 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have no tasks scheduled.\n");
505 strtime = ctime(&now);
506 (void)snprintf(buf, ODS_SE_MAXLINE,
"It is now %s",
507 strtime?strtime:
"(null)");
514 (void)snprintf(buf, ODS_SE_MAXLINE,
"Working with task %s on "
523 (void)snprintf(buf, ODS_SE_MAXLINE,
"\nI have %i tasks scheduled.\n",
529 while (node && node != LDNS_RBTREE_NULL) {
531 for (i=0; i < ODS_SE_MAXLINE; i++) {
534 (void)
task2str(task, (
char*) &buf[0]);
536 node = ldns_rbtree_next(node);
552 char buf[ODS_SE_MAXLINE];
566 (void)snprintf(buf, ODS_SE_MAXLINE,
"All tasks scheduled immediately.\n");
580 char buf[ODS_SE_MAXLINE];
593 (void)snprintf(buf, ODS_SE_MAXLINE,
"Reloading engine.\n");
606 char buf[ODS_SE_MAXLINE];
619 (void)snprintf(buf, ODS_SE_MAXLINE, ODS_SE_STOP_RESPONSE);
630 cmdhandler_handle_cmd_start(
int sockfd)
632 char buf[ODS_SE_MAXLINE];
634 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine already running.\n");
645 cmdhandler_handle_cmd_running(
int sockfd)
647 char buf[ODS_SE_MAXLINE];
649 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine running.\n");
660 cmdhandler_handle_cmd_verbosity(
int sockfd,
cmdhandler_type* cmdc,
int val)
662 char buf[ODS_SE_MAXLINE];
671 (void)snprintf(buf, ODS_SE_MAXLINE,
"Verbosity level set to %i.\n", val);
681 cmdhandler_handle_cmd_error(
int sockfd,
const char* str)
683 char buf[ODS_SE_MAXLINE];
684 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: %s.\n", str?str:
"(null)");
695 cmdhandler_handle_cmd_unknown(
int sockfd,
const char* str)
697 char buf[ODS_SE_MAXLINE];
698 (void)snprintf(buf, ODS_SE_MAXLINE,
"Unknown command %s.\n",
728 char buf[ODS_SE_MAXLINE];
734 while ((n = read(sockfd, buf, ODS_SE_MAXLINE)) > 0) {
742 if (n == 4 && strncmp(buf,
"help", n) == 0) {
744 cmdhandler_handle_cmd_help(sockfd);
745 }
else if (n == 5 && strncmp(buf,
"zones", n) == 0) {
747 cmdhandler_handle_cmd_zones(sockfd, cmdc);
748 }
else if (n >= 4 && strncmp(buf,
"sign", 4) == 0) {
750 if (buf[4] ==
'\0') {
752 cmdhandler_handle_cmd_error(sockfd,
"sign command needs "
753 "an argument (either '--all' or a zone name)");
754 }
else if (buf[4] !=
' ') {
755 cmdhandler_handle_cmd_unknown(sockfd, buf);
757 cmdhandler_handle_cmd_sign(sockfd, cmdc, &buf[5]);
759 }
else if (n >= 5 && strncmp(buf,
"clear", 5) == 0) {
761 if (buf[5] ==
'\0') {
762 cmdhandler_handle_cmd_error(sockfd,
"clear command needs "
764 }
else if (buf[5] !=
' ') {
765 cmdhandler_handle_cmd_unknown(sockfd, buf);
767 cmdhandler_handle_cmd_clear(sockfd, cmdc, &buf[6]);
769 }
else if (n == 5 && strncmp(buf,
"queue", n) == 0) {
771 cmdhandler_handle_cmd_queue(sockfd, cmdc);
772 }
else if (n == 5 && strncmp(buf,
"flush", n) == 0) {
774 cmdhandler_handle_cmd_flush(sockfd, cmdc);
775 }
else if (n >= 6 && strncmp(buf,
"update", 6) == 0) {
777 if (buf[6] ==
'\0') {
778 cmdhandler_handle_cmd_update(sockfd, cmdc,
"--all");
779 }
else if (buf[6] !=
' ') {
780 cmdhandler_handle_cmd_unknown(sockfd, buf);
782 cmdhandler_handle_cmd_update(sockfd, cmdc, &buf[7]);
784 }
else if (n == 4 && strncmp(buf,
"stop", n) == 0) {
786 cmdhandler_handle_cmd_stop(sockfd, cmdc);
788 }
else if (n == 5 && strncmp(buf,
"start", n) == 0) {
790 cmdhandler_handle_cmd_start(sockfd);
791 }
else if (n == 6 && strncmp(buf,
"reload", n) == 0) {
793 cmdhandler_handle_cmd_reload(sockfd, cmdc);
794 }
else if (n == 7 && strncmp(buf,
"running", n) == 0) {
796 cmdhandler_handle_cmd_running(sockfd);
797 }
else if (n >= 9 && strncmp(buf,
"verbosity", 9) == 0) {
799 if (buf[9] ==
'\0') {
800 cmdhandler_handle_cmd_error(sockfd,
"verbosity command "
801 "an argument (verbosity level)");
802 }
else if (buf[9] !=
' ') {
803 cmdhandler_handle_cmd_unknown(sockfd, buf);
805 cmdhandler_handle_cmd_verbosity(sockfd, cmdc, atoi(&buf[10]));
809 cmdhandler_handle_cmd_unknown(sockfd, buf);
812 ods_log_debug(
"[%s] done handling command %s[%i]", cmdh_str, buf, n);
817 if (n < 0 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) ) {
819 }
else if (n < 0 && errno == ECONNRESET) {
823 ods_log_error(
"[%s] read error: %s", cmdh_str, strerror(errno));
834 cmdhandler_accept_client(
void* arg)
842 cmdhandler_handle_cmd(cmdc);
860 struct sockaddr_un servaddr;
866 ods_log_error(
"[%s] unable to create: no allocator", cmdh_str);
872 ods_log_error(
"[%s] unable to create: no socket filename", cmdh_str);
879 listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
881 ods_log_error(
"[%s] unable to create, socket() failed: %s", cmdh_str,
886 flags = fcntl(listenfd, F_GETFL, 0);
888 ods_log_error(
"[%s] unable to create, fcntl(F_GETFL) failed: %s",
889 cmdh_str, strerror(errno));
894 if (fcntl(listenfd, F_SETFL, flags) < 0) {
895 ods_log_error(
"[%s] unable to create, fcntl(F_SETFL) failed: %s",
896 cmdh_str, strerror(errno));
905 bzero(&servaddr,
sizeof(servaddr));
906 servaddr.sun_family = AF_UNIX;
907 strncpy(servaddr.sun_path, filename,
sizeof(servaddr.sun_path) - 1);
910 ret = bind(listenfd, (
const struct sockaddr*) &servaddr,
913 ods_log_error(
"[%s] unable to create, bind() failed: %s", cmdh_str,
920 ods_log_error(
"[%s] unable to create, listen() failed: %s", cmdh_str,
948 struct sockaddr_un cliaddr;
960 engine = cmdhandler->
engine;
964 clilen =
sizeof(cliaddr);
968 if (errno != EINTR && errno != EWOULDBLOCK) {
974 if (FD_ISSET(cmdhandler->
listen_fd, &rset)) {
976 (
struct sockaddr *) &cliaddr, &clilen);
978 if (errno != EINTR && errno != EWOULDBLOCK) {
987 ods_log_crit(
"[%s] unable to create thread for client: "
988 "malloc failed", cmdh_str);
1000 ods_log_debug(
"[%s] %i clients in progress...", cmdh_str, count);
1005 engine = cmdhandler->
engine;