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"
91 "debug-locks show locking information (for debugging purposes).\n"
95 (void) snprintf(buf, ODS_SE_MAXLINE,
96 "flush execute all scheduled tasks immediately.\n"
97 "update <zone> update this zone signer configurations.\n"
98 "update [--all] update zone list and all signer configurations.\n"
99 "start start the engine.\n"
100 "running check if the engine is running.\n"
101 "reload reload the engine.\n"
102 "stop stop the engine.\n"
103 "verbosity <nr> set verbosity.\n"
117 char buf[ODS_SE_MAXLINE];
119 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
125 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have no zones configured\n");
133 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have %i zones configured\n",
139 while (node && node != LDNS_RBTREE_NULL) {
141 for (i=0; i < ODS_SE_MAXLINE; i++) {
144 (void)snprintf(buf, ODS_SE_MAXLINE,
"- %s\n", zone->
name);
146 node = ldns_rbtree_next(node);
162 char buf[ODS_SE_MAXLINE];
181 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has not changed."
182 " Signer configurations updated.\n");
186 ods_log_debug(
"[%s] signer configurations updated", cmdh_str);
188 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list updated: %i "
189 "removed, %i added, %i updated.\n",
203 ods_log_debug(
"[%s] signer configurations updated", cmdh_str);
207 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has errors.\n");
225 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s not found.\n",
229 cmdhandler_handle_cmd_update(sockfd, cmdc,
"--all");
254 "signconf as soon as possible", cmdh_str, zone->
name);
266 ods_log_crit(
"[%s] cannot schedule task for zone %s: %s",
274 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s config being updated.\n",
287 cmdhandler_handle_cmd_sign(
int sockfd,
cmdhandler_type* cmdc,
const char* tbd)
292 char buf[ODS_SE_MAXLINE];
306 (void)snprintf(buf, ODS_SE_MAXLINE,
"All zones scheduled for "
307 "immediate re-sign.\n");
325 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s not found.\n",
351 "zone input as soon as possible", cmdh_str, zone->
name);
364 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Cannot schedule task for "
367 ods_log_crit(
"[%s] cannot schedule task for zone %s: %s",
372 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s scheduled for immediate "
389 unlink_backup_file(
const char* filename,
const char* extension)
394 free((
void*)tmpname);
403 cmdhandler_handle_cmd_clear(
int sockfd,
cmdhandler_type* cmdc,
const char* tbd)
405 char buf[ODS_SE_MAXLINE];
408 uint32_t inbound_serial = 0;
409 uint32_t internal_serial = 0;
410 uint32_t outbound_serial = 0;
417 unlink_backup_file(tbd,
".inbound");
418 unlink_backup_file(tbd,
".backup");
450 " reloading signconf", cmdh_str, zone->
name);
456 " zone %s, reloading signconf", cmdh_str, zone->
name);
463 " for zone %s, reloading signconf", cmdh_str, zone->
name);
469 (void)snprintf(buf, ODS_SE_MAXLINE,
"Internal zone information about "
470 "%s cleared", tbd?tbd:
"(null)");
471 ods_log_info(
"[%s] internal zone information about %s cleared",
472 cmdh_str, tbd?tbd:
"(null)");
474 (void)snprintf(buf, ODS_SE_MAXLINE,
"Cannot clear zone %s, zone not "
475 "found", tbd?tbd:
"(null)");
477 cmdh_str, tbd?tbd:
"(null)");
492 char* strtime = NULL;
493 char buf[ODS_SE_MAXLINE];
496 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
502 (void)snprintf(buf, ODS_SE_MAXLINE,
"I have no tasks scheduled.\n");
511 strtime = ctime(&now);
512 (void)snprintf(buf, ODS_SE_MAXLINE,
"It is now %s",
513 strtime?strtime:
"(null)");
520 (void)snprintf(buf, ODS_SE_MAXLINE,
"Working with task %s on "
529 (void)snprintf(buf, ODS_SE_MAXLINE,
"\nI have %i tasks scheduled.\n",
535 while (node && node != LDNS_RBTREE_NULL) {
537 for (i=0; i < ODS_SE_MAXLINE; i++) {
540 (void)
task2str(task, (
char*) &buf[0]);
542 node = ldns_rbtree_next(node);
557 char* strtime = NULL;
558 char buf[ODS_SE_MAXLINE];
561 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
569 strtime = ctime(&now);
570 (void)snprintf(buf, ODS_SE_MAXLINE,
"It is now %s",
571 strtime?strtime:
"(null)");
574 (void)snprintf(buf, ODS_SE_MAXLINE,
"- signal is %s[%i]\n",
578 (void)snprintf(buf, ODS_SE_MAXLINE,
"- zone list is %s[%i]\n",
582 (void)snprintf(buf, ODS_SE_MAXLINE,
"- task schedule is %s[%i]\n",
586 (void)snprintf(buf, ODS_SE_MAXLINE,
"- rrset queue is %s[%i]\n",
592 (void)snprintf(buf, ODS_SE_MAXLINE,
"- worker[%i] is %s[%i]\n",
600 (void)snprintf(buf, ODS_SE_MAXLINE,
"- drudger[%i] is %s[%i]\n",
609 while (node && node != LDNS_RBTREE_NULL) {
611 memset(buf, 0, ODS_SE_MAXLINE);
612 (void)snprintf(buf, ODS_SE_MAXLINE,
"- %s is %s[%i], stats is %s[%i]\n",
619 node = ldns_rbtree_next(node);
633 char buf[ODS_SE_MAXLINE];
647 (void)snprintf(buf, ODS_SE_MAXLINE,
"All tasks scheduled immediately.\n");
661 char buf[ODS_SE_MAXLINE];
674 (void)snprintf(buf, ODS_SE_MAXLINE,
"Reloading engine.\n");
687 char buf[ODS_SE_MAXLINE];
700 (void)snprintf(buf, ODS_SE_MAXLINE, ODS_SE_STOP_RESPONSE);
711 cmdhandler_handle_cmd_start(
int sockfd)
713 char buf[ODS_SE_MAXLINE];
715 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine already running.\n");
726 cmdhandler_handle_cmd_running(
int sockfd)
728 char buf[ODS_SE_MAXLINE];
730 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine running.\n");
741 cmdhandler_handle_cmd_verbosity(
int sockfd,
cmdhandler_type* cmdc,
int val)
743 char buf[ODS_SE_MAXLINE];
752 (void)snprintf(buf, ODS_SE_MAXLINE,
"Verbosity level set to %i.\n", val);
762 cmdhandler_handle_cmd_error(
int sockfd,
const char* str)
764 char buf[ODS_SE_MAXLINE];
765 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: %s.\n", str?str:
"(null)");
776 cmdhandler_handle_cmd_unknown(
int sockfd,
const char* str)
778 char buf[ODS_SE_MAXLINE];
779 (void)snprintf(buf, ODS_SE_MAXLINE,
"Unknown command %s.\n",
809 char buf[ODS_SE_MAXLINE];
815 while ((n = read(sockfd, buf, ODS_SE_MAXLINE)) > 0) {
823 if (n == 4 && strncmp(buf,
"help", n) == 0) {
825 cmdhandler_handle_cmd_help(sockfd);
826 }
else if (n == 5 && strncmp(buf,
"zones", n) == 0) {
828 cmdhandler_handle_cmd_zones(sockfd, cmdc);
829 }
else if (n >= 4 && strncmp(buf,
"sign", 4) == 0) {
831 if (buf[4] ==
'\0') {
833 cmdhandler_handle_cmd_error(sockfd,
"sign command needs "
834 "an argument (either '--all' or a zone name)");
835 }
else if (buf[4] !=
' ') {
836 cmdhandler_handle_cmd_unknown(sockfd, buf);
838 cmdhandler_handle_cmd_sign(sockfd, cmdc, &buf[5]);
840 }
else if (n >= 5 && strncmp(buf,
"clear", 5) == 0) {
842 if (buf[5] ==
'\0') {
843 cmdhandler_handle_cmd_error(sockfd,
"clear command needs "
845 }
else if (buf[5] !=
' ') {
846 cmdhandler_handle_cmd_unknown(sockfd, buf);
848 cmdhandler_handle_cmd_clear(sockfd, cmdc, &buf[6]);
850 }
else if (n == 5 && strncmp(buf,
"queue", n) == 0) {
852 cmdhandler_handle_cmd_queue(sockfd, cmdc);
853 }
else if (n == 11 && strncmp(buf,
"debug-locks", n) == 0) {
855 cmdhandler_handle_cmd_debuglocks(sockfd, cmdc);
856 }
else if (n == 5 && strncmp(buf,
"flush", n) == 0) {
858 cmdhandler_handle_cmd_flush(sockfd, cmdc);
859 }
else if (n >= 6 && strncmp(buf,
"update", 6) == 0) {
861 if (buf[6] ==
'\0') {
862 cmdhandler_handle_cmd_update(sockfd, cmdc,
"--all");
863 }
else if (buf[6] !=
' ') {
864 cmdhandler_handle_cmd_unknown(sockfd, buf);
866 cmdhandler_handle_cmd_update(sockfd, cmdc, &buf[7]);
868 }
else if (n == 4 && strncmp(buf,
"stop", n) == 0) {
870 cmdhandler_handle_cmd_stop(sockfd, cmdc);
872 }
else if (n == 5 && strncmp(buf,
"start", n) == 0) {
874 cmdhandler_handle_cmd_start(sockfd);
875 }
else if (n == 6 && strncmp(buf,
"reload", n) == 0) {
877 cmdhandler_handle_cmd_reload(sockfd, cmdc);
878 }
else if (n == 7 && strncmp(buf,
"running", n) == 0) {
880 cmdhandler_handle_cmd_running(sockfd);
881 }
else if (n >= 9 && strncmp(buf,
"verbosity", 9) == 0) {
883 if (buf[9] ==
'\0') {
884 cmdhandler_handle_cmd_error(sockfd,
"verbosity command "
885 "an argument (verbosity level)");
886 }
else if (buf[9] !=
' ') {
887 cmdhandler_handle_cmd_unknown(sockfd, buf);
889 cmdhandler_handle_cmd_verbosity(sockfd, cmdc, atoi(&buf[10]));
893 cmdhandler_handle_cmd_unknown(sockfd, buf);
896 ods_log_debug(
"[%s] done handling command %s[%i]", cmdh_str, buf, n);
901 if (n < 0 && (errno == EINTR || errno == EWOULDBLOCK || errno == EAGAIN) ) {
903 }
else if (n < 0 && errno == ECONNRESET) {
907 ods_log_error(
"[%s] read error: %s", cmdh_str, strerror(errno));
918 cmdhandler_accept_client(
void* arg)
926 cmdhandler_handle_cmd(cmdc);
945 struct sockaddr_un servaddr;
951 ods_log_error(
"[%s] unable to create: no allocator", cmdh_str);
957 ods_log_error(
"[%s] unable to create: no socket filename", cmdh_str);
964 listenfd = socket(AF_UNIX, SOCK_STREAM, 0);
966 ods_log_error(
"[%s] unable to create, socket() failed: %s", cmdh_str,
971 flags = fcntl(listenfd, F_GETFL, 0);
973 ods_log_error(
"[%s] unable to create, fcntl(F_GETFL) failed: %s",
974 cmdh_str, strerror(errno));
979 if (fcntl(listenfd, F_SETFL, flags) < 0) {
980 ods_log_error(
"[%s] unable to create, fcntl(F_SETFL) failed: %s",
981 cmdh_str, strerror(errno));
990 bzero(&servaddr,
sizeof(servaddr));
991 servaddr.sun_family = AF_UNIX;
992 strncpy(servaddr.sun_path, filename,
sizeof(servaddr.sun_path) - 1);
995 ret = bind(listenfd, (
const struct sockaddr*) &servaddr,
998 ods_log_error(
"[%s] unable to create, bind() failed: %s", cmdh_str,
1005 ods_log_error(
"[%s] unable to create, listen() failed: %s", cmdh_str,
1033 struct sockaddr_un cliaddr;
1045 engine = cmdhandler->
engine;
1049 clilen =
sizeof(cliaddr);
1051 ret = select(cmdhandler->
listen_fd+1, &rset, NULL, NULL, NULL);
1053 if (errno != EINTR && errno != EWOULDBLOCK) {
1059 if (FD_ISSET(cmdhandler->
listen_fd, &rset)) {
1061 (
struct sockaddr *) &cliaddr, &clilen);
1063 if (errno != EINTR && errno != EWOULDBLOCK) {
1072 ods_log_crit(
"[%s] unable to create thread for client: "
1073 "malloc failed", cmdh_str);
1085 ods_log_debug(
"[%s] %i clients in progress...", cmdh_str, count);
1090 engine = cmdhandler->
engine;