11#include "cmdhandler.h"
13#include "clientpipe.h"
15static char const * cmdh_str =
"cmdhandler";
18cmdargument(
const char* cmd,
const char* matchValue,
const char* defaultValue)
23 while(*s && !isspace(*s))
25 while(*s && isspace(*s))
28 if (!strcmp(s,matchValue))
44cmdhandler_handle_cmd_help(cmdhandler_ctx_type* context,
char *cmd)
46 int sockfd = context->sockfd;
47 char buf[ODS_SE_MAXLINE];
49 (void) snprintf(buf, ODS_SE_MAXLINE,
51 "zones Show the currently known zones.\n"
52 "sign <zone> [--serial <nr>] Read zone and schedule for immediate "
54 " If a serial is given, that serial is used "
55 "in the output zone.\n"
56 "sign --all Read all zones and schedule all for "
57 "immediate (re-)sign.\n"
59 client_printf(sockfd,
"%s", buf);
61 (void) snprintf(buf, ODS_SE_MAXLINE,
62 "clear <zone> Delete the internal storage of this "
64 " All signatures will be regenerated "
65 "on the next re-sign.\n"
66 "queue Show the current task queue.\n"
67 "flush Execute all scheduled tasks "
70 client_printf(sockfd,
"%s", buf);
72 (void) snprintf(buf, ODS_SE_MAXLINE,
73 "update <zone> Update this zone signer "
75 "update [--all] Update zone list and all signer "
77 "retransfer <zone> Retransfer the zone from the master.\n"
78 "start Start the engine.\n"
79 "running Check if the engine is running.\n"
80 "reload Reload the engine.\n"
81 "stop Stop the engine.\n"
82 "verbosity <nr> Set verbosity.\n"
84 client_printf(sockfd,
"%s", buf);
94cmdhandler_handle_cmd_zones(cmdhandler_ctx_type* context,
char *cmd)
96 int sockfd = context->sockfd;
98 char buf[ODS_SE_MAXLINE];
100 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
104 (void)snprintf(buf, ODS_SE_MAXLINE,
"There are no zones configured\n");
105 client_printf(sockfd,
"%s", buf);
110 (void)snprintf(buf, ODS_SE_MAXLINE,
"There are %i zones configured\n",
112 client_printf(sockfd,
"%s", buf);
115 while (node && node != LDNS_RBTREE_NULL) {
117 for (i=0; i < ODS_SE_MAXLINE; i++) {
120 (void)snprintf(buf, ODS_SE_MAXLINE,
"- %s\n", zone->
name);
121 client_printf(sockfd,
"%s", buf);
122 node = ldns_rbtree_next(node);
134cmdhandler_handle_cmd_update(cmdhandler_ctx_type* context,
char *cmd)
136 int sockfd = context->sockfd;
138 char buf[ODS_SE_MAXLINE];
140 ods_status zl_changed = ODS_STATUS_OK;
142 ods_log_assert(engine);
143 ods_log_assert(engine->
taskq);
144 if (cmdargument(cmd,
"--all", NULL)) {
148 if (zl_changed == ODS_STATUS_UNCHANGED) {
149 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has not changed."
150 " Signer configurations updated.\n");
151 client_printf(sockfd,
"%s", buf);
152 }
else if (zl_changed == ODS_STATUS_OK) {
153 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list updated: %i "
154 "removed, %i added, %i updated.\n",
158 client_printf(sockfd,
"%s", buf);
161 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has errors.\n");
162 client_printf(sockfd,
"%s", buf);
164 if (zl_changed == ODS_STATUS_OK ||
165 zl_changed == ODS_STATUS_UNCHANGED) {
189 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
190 cmdargument(cmd, NULL,
""));
191 client_printf(sockfd,
"%s", buf);
193 cmdhandler_handle_cmd_update(context,
"update --all");
198 schedule_scheduletask(engine->
taskq, TASK_FORCESIGNCONF, zone->
name, zone, &zone->
zone_lock, schedule_PROMPTLY);
201 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s config being updated.\n",
202 cmdargument(cmd, NULL,
""));
203 client_printf(sockfd,
"%s", buf);
204 ods_log_verbose(
"[%s] zone %s scheduled for immediate update signconf",
205 cmdh_str, cmdargument(cmd, NULL,
""));
217cmdhandler_handle_cmd_retransfer(cmdhandler_ctx_type* context,
char *cmd)
219 int sockfd = context->sockfd;
221 char buf[ODS_SE_MAXLINE];
224 ods_log_assert(engine->
taskq);
237 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
238 cmdargument(cmd, NULL,
""));
239 client_printf(sockfd,
"%s", buf);
241 (void)snprintf(buf, ODS_SE_MAXLINE,
242 "Error: Zone %s not configured to use DNS input adapter.\n",
243 cmdargument(cmd, NULL,
""));
244 client_printf(sockfd,
"%s", buf);
248 ods_log_debug(
"[%s] forward a notify", cmdh_str);
251 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s being re-transfered.\n", cmdargument(cmd, NULL,
""));
252 client_printf(sockfd,
"%s", buf);
253 ods_log_verbose(
"[%s] zone %s being re-transfered", cmdh_str, cmdargument(cmd, NULL,
""));
260max(uint32_t a, uint32_t b)
270 ods_log_assert(zone->
db);
271 if (!util_serial_gt(serial, max(zone->
db->
outserial,
274 client_printf(sockfd,
"Error: Unable to enforce serial %u for zone %s.\n", serial, zone->
name);
280 schedule_scheduletask(engine->
taskq, TASK_FORCEREAD, zone->
name, zone, &zone->
zone_lock, schedule_IMMEDIATELY);
285static struct option signoptions[] = {
286 {
"all", 0, NULL,
'a' },
287 {
"zone", 1, NULL,
'z' },
288 {
"serial", 1, NULL,
's' },
289 {
"time", 1, NULL,
't' },
300 *result = strtol(s, &end, 0);
301 if(errno == ERANGE) {
327cmdhandler_handle_cmd_sign(cmdhandler_ctx_type* context,
int argc,
char* argv[])
330 struct longgetopt optctx;
333 char* zonename = NULL;
335 int force_serial = 0;
337 char* signtime = NULL;
344 for(opt = longgetopt(argc, argv,
"az:s:t:", signoptions, &longindex, &optctx); opt != -1;
345 opt = longgetopt(argc, argv, NULL, signoptions, &longindex, &optctx)) {
351 zonename = optctx.optarg;
354 getlong(optctx.optarg, NULL, &serial);
358 signtime = optctx.optarg;
361 client_printf_err(context->sockfd,
"unknown arguments\n");
365 if(optctx.optind < argc)
366 zonename = argv[optctx.optind];
367 if(!allzones && (zonename == NULL || *zonename ==
'\0')) {
368 client_printf_err(context->sockfd,
"No zone name provided to zone sign command.\n");
374 for (node = ldns_rbtree_first(engine->
zonelist->
zones); node != LDNS_RBTREE_NULL && node != NULL; node = ldns_rbtree_next(node)) {
376 forceread(engine, zone, 0, 0, context->sockfd);
380 client_printf(context->sockfd,
"All zones scheduled for immediate re-sign.\n");
393 client_printf(context->sockfd,
"Error: Zone %s not found.\n", zonename);
397 forceread(engine, zone, force_serial, serial, context->sockfd);
399 client_printf(context->sockfd,
"Zone %s scheduled for immediate re-sign.\n", zonename);
400 ods_log_verbose(
"zone %s scheduled for immediate re-sign", zonename);
410unlink_backup_file(
const char* filename,
const char* extension)
412 char* tmpname = ods_build_path(filename, extension, 0, 1);
414 ods_log_debug(
"[%s] unlink file %s", cmdh_str, tmpname);
416 free((
void*)tmpname);
425cmdhandler_handle_cmd_clear(cmdhandler_ctx_type* context,
char *cmd)
427 int sockfd = context->sockfd;
429 char buf[ODS_SE_MAXLINE];
431 uint32_t inbserial = 0;
432 uint32_t intserial = 0;
433 uint32_t outserial = 0;
435 unlink_backup_file(cmdargument(cmd, NULL,
""),
".inbound");
436 unlink_backup_file(cmdargument(cmd, NULL,
""),
".backup");
437 unlink_backup_file(cmdargument(cmd, NULL,
""),
".axfr");
438 unlink_backup_file(cmdargument(cmd, NULL,
""),
".ixfr");
457 ods_fatal_exit(
"[%s] unable to clear zone %s: failed to recreate"
458 "signconf, ixfr of db structure (out of memory?)", cmdh_str, cmdargument(cmd, NULL,
""));
469 schedule_scheduletask(engine->
taskq, TASK_FORCESIGNCONF, zone->
name, zone, &zone->
zone_lock, schedule_IMMEDIATELY);
472 (void)snprintf(buf, ODS_SE_MAXLINE,
"Internal zone information about "
473 "%s cleared", cmdargument(cmd, NULL,
""));
474 ods_log_info(
"[%s] internal zone information about %s cleared",
475 cmdh_str, cmdargument(cmd, NULL,
""));
477 (void)snprintf(buf, ODS_SE_MAXLINE,
"Cannot clear zone %s, zone not "
478 "found", cmdargument(cmd, NULL,
""));
479 ods_log_warning(
"[%s] cannot clear zone %s, zone not found",
480 cmdh_str, cmdargument(cmd, NULL,
""));
482 client_printf(sockfd,
"%s", buf);
492cmdhandler_handle_cmd_queue(cmdhandler_ctx_type* context,
char *cmd)
494 int sockfd = context->sockfd;
496 char* strtime = NULL;
497 char buf[ODS_SE_MAXLINE];
501 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
502 task_type* task = NULL;
504 if (!engine->
taskq || !engine->
taskq->tasks) {
505 (void)snprintf(buf, ODS_SE_MAXLINE,
"There are no tasks scheduled.\n");
506 client_printf(sockfd,
"%s", buf);
511 strtime = ctime(&now);
512 (void)snprintf(buf, ODS_SE_MAXLINE,
"It is now %s",
513 strtime?strtime:
"(null)");
514 client_printf(sockfd,
"%s", buf);
516 pthread_mutex_lock(&engine->
taskq->schedule_lock);
518 (void)snprintf(buf, ODS_SE_MAXLINE,
"\nThere are %i tasks scheduled.\n",
519 (
int) engine->
taskq->tasks->count);
520 client_printf(sockfd,
"%s", buf);
522 node = ldns_rbtree_first(engine->
taskq->tasks);
523 while (node && node != LDNS_RBTREE_NULL) {
524 task = (task_type*) node->data;
525 for (i=0; i < ODS_SE_MAXLINE; i++) {
528 taskdesc = schedule_describetask(task);
529 client_printf(sockfd,
"%s", taskdesc);
531 node = ldns_rbtree_next(node);
533 pthread_mutex_unlock(&engine->
taskq->schedule_lock);
543cmdhandler_handle_cmd_flush(cmdhandler_ctx_type* context,
char *cmd)
545 int sockfd = context->sockfd;
547 char buf[ODS_SE_MAXLINE];
549 ods_log_assert(engine->
taskq);
550 schedule_flush(engine->
taskq);
552 (void)snprintf(buf, ODS_SE_MAXLINE,
"All tasks scheduled immediately.\n");
553 client_printf(sockfd,
"%s", buf);
554 ods_log_verbose(
"[%s] all tasks scheduled immediately", cmdh_str);
564cmdhandler_handle_cmd_reload(cmdhandler_ctx_type* context,
char *cmd)
566 int sockfd = context->sockfd;
568 char buf[ODS_SE_MAXLINE];
570 ods_log_error(
"signer instructed to reload due to explicit command");
575 (void)snprintf(buf, ODS_SE_MAXLINE,
"Reloading engine.\n");
576 client_printf(sockfd,
"%s", buf);
586cmdhandler_handle_cmd_stop(cmdhandler_ctx_type* context,
char *cmd)
588 int sockfd = context->sockfd;
590 char buf[ODS_SE_MAXLINE];
596 (void)snprintf(buf, ODS_SE_MAXLINE, ODS_SE_STOP_RESPONSE);
597 client_printf(sockfd,
"%s", buf);
607cmdhandler_handle_cmd_start(cmdhandler_ctx_type* context,
char *cmd)
609 int sockfd = context->sockfd;
610 char buf[ODS_SE_MAXLINE];
611 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine already running.\n");
612 client_printf(sockfd,
"%s", buf);
622cmdhandler_handle_cmd_running(cmdhandler_ctx_type* context,
char *cmd)
624 int sockfd = context->sockfd;
625 char buf[ODS_SE_MAXLINE];
626 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine running.\n");
627 client_printf(sockfd,
"%s", buf);
637cmdhandler_handle_cmd_verbosity(cmdhandler_ctx_type* context,
char *cmd)
639 int sockfd = context->sockfd;
640 char buf[ODS_SE_MAXLINE];
642 val = atoi(cmdargument(cmd, NULL,
"1"));
643 ods_log_setverbosity(val);
644 (void)snprintf(buf, ODS_SE_MAXLINE,
"Verbosity level set to %i.\n", val);
645 client_printf(sockfd,
"%s", buf);
655cmdhandler_handle_cmd_error(
int sockfd, cmdhandler_ctx_type* context,
char* str)
657 char buf[ODS_SE_MAXLINE];
658 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: %s.\n", str?str:
"(null)");
659 client_printf(sockfd,
"%s", buf);
668cmdhandler_handle_cmd_timeleap(cmdhandler_ctx_type* context,
char *cmd)
670 int sockfd = context->sockfd;
671 struct tm strtime_struct;
673 time_t now = time_now();
674 time_t time_leap = 0;
675 time_t next_leap = 0;
681 while(isspace(*cmd)) ++cmd;
683 while(isspace(*cmd)) ++cmd;
685 while(isspace(*cmd)) ++cmd;
687 if (strptime(cmd,
"%Y-%m-%d-%H:%M:%S", &tm)) {
689 time_leap = mktime(&tm);
690 client_printf(sockfd,
"Using %s parameter value as time to leap to\n", cmd);
692 client_printf_err(sockfd,
"Time leap: Error - could not convert '%s' to a time. Format is YYYY-MM-DD-HH:MM:SS \n", cmd);
695 if (!engine->
taskq || !engine->
taskq->tasks) {
696 client_printf(sockfd,
"There are no tasks scheduled.\n");
699 schedule_info(engine->
taskq, &next_leap, NULL, &taskcount);
701 strftime(strtime,
sizeof (strtime),
"%c", localtime_r(&now, &strtime_struct));
702 client_printf(sockfd,
"There are %i tasks scheduled.\nIt is now %s (%ld seconds since epoch)\n", taskcount, strtime, (
long) now);
703 set_time_now(time_leap);
704 strftime(strtime,
sizeof (strtime),
"%c", localtime_r(&time_leap, &strtime_struct));
705 client_printf(sockfd,
"Leaping to time %s (%ld seconds since epoch)\n", (strtime[0] ? strtime :
"(null)"), (long) time_leap);
706 ods_log_info(
"Time leap: Leaping to time %s\n", strtime);
707 client_printf(sockfd,
"Waking up workers\n");
712struct cmd_func_block
helpCmdDef = {
"help", NULL, NULL, NULL, &cmdhandler_handle_cmd_help, NULL };
713struct cmd_func_block
zonesCmdDef = {
"zones", NULL, NULL, NULL, &cmdhandler_handle_cmd_zones, NULL };
714struct cmd_func_block
signCmdDef = {
"sign", NULL, NULL, NULL, NULL, &cmdhandler_handle_cmd_sign };
715struct cmd_func_block
clearCmdDef = {
"clear", NULL, NULL, NULL, &cmdhandler_handle_cmd_clear, NULL };
716struct cmd_func_block
queueCmdDef = {
"queue", NULL, NULL, NULL, &cmdhandler_handle_cmd_queue, NULL };
717struct cmd_func_block
flushCmdDef = {
"flush", NULL, NULL, NULL, &cmdhandler_handle_cmd_flush, NULL };
718struct cmd_func_block
updateCmdDef = {
"update", NULL, NULL, NULL, &cmdhandler_handle_cmd_update, NULL };
719struct cmd_func_block
stopCmdDef = {
"stop", NULL, NULL, NULL, &cmdhandler_handle_cmd_stop, NULL };
720struct cmd_func_block
startCmdDef = {
"start", NULL, NULL, NULL, &cmdhandler_handle_cmd_start, NULL };
721struct cmd_func_block
reloadCmdDef = {
"reload", NULL, NULL, NULL, &cmdhandler_handle_cmd_reload, NULL };
722struct cmd_func_block
retransferCmdDef = {
"retransfer", NULL, NULL, NULL, &cmdhandler_handle_cmd_retransfer, NULL };
723struct cmd_func_block
runningCmdDef = {
"running", NULL, NULL, NULL, &cmdhandler_handle_cmd_running, NULL };
724struct cmd_func_block
verbosityCmdDef = {
"verbosity", NULL, NULL, NULL, &cmdhandler_handle_cmd_verbosity, NULL };
725struct cmd_func_block
timeleapCmdDef = {
"time leap", NULL, NULL, NULL, &cmdhandler_handle_cmd_timeleap, NULL };
void dnshandler_fwd_notify(dnshandler_type *dnshandler, uint8_t *pkt, size_t len)
#define ODS_SE_NOTIFY_CMD
void engine_wakeup_workers(engine_type *engine)
void engine_update_zones(engine_type *engine, ods_status zl_changed)
void ixfr_cleanup(ixfr_type *ixfr)
ixfr_type * ixfr_create()
namedb_type * namedb_create(void *zone)
void namedb_cleanup(namedb_type *db)
void signconf_cleanup(signconf_type *sc)
signconf_type * signconf_create(void)
struct cmd_func_block zonesCmdDef
struct cmd_func_block verbosityCmdDef
struct cmd_func_block startCmdDef
struct cmd_func_block signCmdDef
struct cmd_func_block retransferCmdDef
struct cmd_func_block * signcommands[]
struct cmd_func_block flushCmdDef
int getlong(char *s, char **endptr, long *result)
struct cmd_func_block timeleapCmdDef
struct cmd_func_block clearCmdDef
struct cmd_func_block reloadCmdDef
struct cmd_func_block queueCmdDef
engine_type * getglobalcontext(cmdhandler_ctx_type *context)
struct cmd_func_block helpCmdDef
struct cmd_func_block ** signercommands
struct cmd_func_block stopCmdDef
struct cmd_func_block runningCmdDef
struct cmd_func_block updateCmdDef
pthread_mutex_t signal_lock
pthread_cond_t signal_cond
dnshandler_type * dnshandler
engineconfig_type * config
const char * zonelist_filename
uint8_t serial_retransfer
pthread_mutex_t zone_lock
void xfrd_set_timer_now(xfrd_type *xfrd)
ods_status zonelist_update(zonelist_type *zl, const char *zlfile)
zone_type * zonelist_lookup_zone_by_name(zonelist_type *zonelist, const char *name, ldns_rr_class klass)