10#include "cmdhandler.h"
12#include "clientpipe.h"
14static char const * cmdh_str =
"cmdhandler";
17cmdargument(
const char* cmd,
const char* matchValue,
const char* defaultValue)
22 while(*s && !isspace(*s))
24 while(*s && isspace(*s))
27 if (!strcmp(s,matchValue))
43cmdhandler_handle_cmd_help(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
45 char buf[ODS_SE_MAXLINE];
47 (void) snprintf(buf, ODS_SE_MAXLINE,
49 "zones Show the currently known zones.\n"
50 "sign <zone> [--serial <nr>] Read zone and schedule for immediate "
52 " If a serial is given, that serial is used "
53 "in the output zone.\n"
54 "sign --all Read all zones and schedule all for "
55 "immediate (re-)sign.\n"
57 client_printf(sockfd,
"%s", buf);
59 (void) snprintf(buf, ODS_SE_MAXLINE,
60 "clear <zone> Delete the internal storage of this "
62 " All signatures will be regenerated "
63 "on the next re-sign.\n"
64 "queue Show the current task queue.\n"
65 "flush Execute all scheduled tasks "
68 client_printf(sockfd,
"%s", buf);
70 (void) snprintf(buf, ODS_SE_MAXLINE,
71 "update <zone> Update this zone signer "
73 "update [--all] Update zone list and all signer "
75 "retransfer <zone> Retransfer the zone from the master.\n"
76 "start Start the engine.\n"
77 "running Check if the engine is running.\n"
78 "reload Reload the engine.\n"
79 "stop Stop the engine.\n"
80 "verbosity <nr> Set verbosity.\n"
82 client_printf(sockfd,
"%s", buf);
92cmdhandler_handle_cmd_zones(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
95 char buf[ODS_SE_MAXLINE];
97 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
101 (void)snprintf(buf, ODS_SE_MAXLINE,
"There are no zones configured\n");
102 client_printf(sockfd,
"%s", buf);
107 (void)snprintf(buf, ODS_SE_MAXLINE,
"There are %i zones configured\n",
109 client_printf(sockfd,
"%s", buf);
112 while (node && node != LDNS_RBTREE_NULL) {
114 for (i=0; i < ODS_SE_MAXLINE; i++) {
117 (void)snprintf(buf, ODS_SE_MAXLINE,
"- %s\n", zone->
name);
118 client_printf(sockfd,
"%s", buf);
119 node = ldns_rbtree_next(node);
131cmdhandler_handle_cmd_update(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
134 char buf[ODS_SE_MAXLINE];
135 ods_status status = ODS_STATUS_OK;
137 ods_status zl_changed = ODS_STATUS_OK;
139 ods_log_assert(engine->
taskq);
140 if (cmdargument(cmd,
"--all", NULL)) {
144 if (zl_changed == ODS_STATUS_UNCHANGED) {
145 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has not changed."
146 " Signer configurations updated.\n");
147 client_printf(sockfd,
"%s", buf);
148 }
else if (zl_changed == ODS_STATUS_OK) {
149 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list updated: %i "
150 "removed, %i added, %i updated.\n",
154 client_printf(sockfd,
"%s", buf);
157 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone list has errors.\n");
158 client_printf(sockfd,
"%s", buf);
160 if (zl_changed == ODS_STATUS_OK ||
161 zl_changed == ODS_STATUS_UNCHANGED) {
185 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
186 cmdargument(cmd, NULL,
""));
187 client_printf(sockfd,
"%s", buf);
189 cmdhandler_handle_cmd_update(sockfd, context,
"update --all");
194 schedule_scheduletask(engine->
taskq, TASK_FORCESIGNCONF, zone->
name, zone, &zone->
zone_lock, schedule_PROMPTLY);
197 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s config being updated.\n",
198 cmdargument(cmd, NULL,
""));
199 client_printf(sockfd,
"%s", buf);
200 ods_log_verbose(
"[%s] zone %s scheduled for immediate update signconf",
201 cmdh_str, cmdargument(cmd, NULL,
""));
213cmdhandler_handle_cmd_retransfer(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
216 char buf[ODS_SE_MAXLINE];
219 ods_log_assert(engine->
taskq);
232 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
233 cmdargument(cmd, NULL,
""));
234 client_printf(sockfd,
"%s", buf);
236 (void)snprintf(buf, ODS_SE_MAXLINE,
237 "Error: Zone %s not configured to use DNS input adapter.\n",
238 cmdargument(cmd, NULL,
""));
239 client_printf(sockfd,
"%s", buf);
243 ods_log_debug(
"[%s] forward a notify", cmdh_str);
246 (void)snprintf(buf, ODS_SE_MAXLINE,
"Zone %s being re-transfered.\n", cmdargument(cmd, NULL,
""));
247 client_printf(sockfd,
"%s", buf);
248 ods_log_verbose(
"[%s] zone %s being re-transfered", cmdh_str, cmdargument(cmd, NULL,
""));
255max(uint32_t a, uint32_t b)
265 ods_log_assert(zone->
db);
266 if (!util_serial_gt(serial, max(zone->
db->
outserial,
269 client_printf(sockfd,
"Error: Unable to enforce serial %u for zone %s.\n", serial, zone->
name);
275 schedule_scheduletask(engine->
taskq, TASK_FORCEREAD, zone->
name, zone, &zone->
zone_lock, schedule_IMMEDIATELY);
285cmdhandler_handle_cmd_sign(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
289 ods_status status = ODS_STATUS_OK;
290 char buf[ODS_SE_MAXLINE];
293 ods_log_assert(engine->
taskq);
294 if (cmdargument(cmd,
"--all", NULL)) {
297 for (node = ldns_rbtree_first(engine->
zonelist->
zones); node != LDNS_RBTREE_NULL && node != NULL; node = ldns_rbtree_next(node)) {
299 forceread(engine, zone, 0, 0, sockfd);
303 client_printf(sockfd,
"All zones scheduled for immediate re-sign.\n");
305 char* delim1 = strchr(cmdargument(cmd, NULL,
""),
' ');
307 int force_serial = 0;
312 if (strncmp(delim1+1,
"--serial ", 9) != 0) {
313 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Expecting <zone> "
314 "--serial <nr>, got %s.\n", cmdargument(cmd, NULL,
""));
315 client_printf(sockfd,
"%s", buf);
318 delim2 = strchr(delim1+1,
' ');
320 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Expecting serial.\n");
321 client_printf(sockfd,
"%s", buf);
324 serial = (uint32_t) strtol(delim2+1, &end, 10);
326 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Expecting serial, "
327 "got %s.\n", delim2+1);
328 client_printf(sockfd,
"%s", buf);
346 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: Zone %s not found.\n",
347 cmdargument(cmd, NULL,
""));
348 client_printf(sockfd,
"%s", buf);
352 forceread(engine, zone, force_serial, serial, sockfd);
354 client_printf(sockfd,
"Zone %s scheduled for immediate re-sign.\n", cmdargument(cmd, NULL,
""));
355 ods_log_verbose(
"zone %s scheduled for immediate re-sign", cmdargument(cmd, NULL,
""));
365unlink_backup_file(
const char* filename,
const char* extension)
367 char* tmpname = ods_build_path(filename, extension, 0, 1);
369 ods_log_debug(
"[%s] unlink file %s", cmdh_str, tmpname);
371 free((
void*)tmpname);
380cmdhandler_handle_cmd_clear(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
383 char buf[ODS_SE_MAXLINE];
385 uint32_t inbserial = 0;
386 uint32_t intserial = 0;
387 uint32_t outserial = 0;
389 unlink_backup_file(cmdargument(cmd, NULL,
""),
".inbound");
390 unlink_backup_file(cmdargument(cmd, NULL,
""),
".backup");
391 unlink_backup_file(cmdargument(cmd, NULL,
""),
".axfr");
392 unlink_backup_file(cmdargument(cmd, NULL,
""),
".ixfr");
411 ods_fatal_exit(
"[%s] unable to clear zone %s: failed to recreate"
412 "signconf, ixfr of db structure (out of memory?)", cmdh_str, cmdargument(cmd, NULL,
""));
423 schedule_scheduletask(engine->
taskq, TASK_FORCESIGNCONF, zone->
name, zone, &zone->
zone_lock, schedule_IMMEDIATELY);
426 (void)snprintf(buf, ODS_SE_MAXLINE,
"Internal zone information about "
427 "%s cleared", cmdargument(cmd, NULL,
""));
428 ods_log_info(
"[%s] internal zone information about %s cleared",
429 cmdh_str, cmdargument(cmd, NULL,
""));
431 (void)snprintf(buf, ODS_SE_MAXLINE,
"Cannot clear zone %s, zone not "
432 "found", cmdargument(cmd, NULL,
""));
433 ods_log_warning(
"[%s] cannot clear zone %s, zone not found",
434 cmdh_str, cmdargument(cmd, NULL,
""));
436 client_printf(sockfd,
"%s", buf);
446cmdhandler_handle_cmd_queue(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
449 char* strtime = NULL;
450 char buf[ODS_SE_MAXLINE];
454 ldns_rbnode_t* node = LDNS_RBTREE_NULL;
455 task_type* task = NULL;
457 if (!engine->
taskq || !engine->
taskq->tasks) {
458 (void)snprintf(buf, ODS_SE_MAXLINE,
"There are no tasks scheduled.\n");
459 client_printf(sockfd,
"%s", buf);
464 strtime = ctime(&now);
465 (void)snprintf(buf, ODS_SE_MAXLINE,
"It is now %s",
466 strtime?strtime:
"(null)");
467 client_printf(sockfd,
"%s", buf);
469 pthread_mutex_lock(&engine->
taskq->schedule_lock);
471 (void)snprintf(buf, ODS_SE_MAXLINE,
"\nThere are %i tasks scheduled.\n",
472 (
int) engine->
taskq->tasks->count);
473 client_printf(sockfd,
"%s", buf);
475 node = ldns_rbtree_first(engine->
taskq->tasks);
476 while (node && node != LDNS_RBTREE_NULL) {
477 task = (task_type*) node->data;
478 for (i=0; i < ODS_SE_MAXLINE; i++) {
481 taskdesc = schedule_describetask(task);
482 client_printf(sockfd,
"%s", taskdesc);
484 node = ldns_rbtree_next(node);
486 pthread_mutex_unlock(&engine->
taskq->schedule_lock);
496cmdhandler_handle_cmd_flush(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
499 char buf[ODS_SE_MAXLINE];
501 ods_log_assert(engine->
taskq);
502 schedule_flush(engine->
taskq);
504 (void)snprintf(buf, ODS_SE_MAXLINE,
"All tasks scheduled immediately.\n");
505 client_printf(sockfd,
"%s", buf);
506 ods_log_verbose(
"[%s] all tasks scheduled immediately", cmdh_str);
516cmdhandler_handle_cmd_reload(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
519 char buf[ODS_SE_MAXLINE];
521 ods_log_error(
"signer instructed to reload due to explicit command");
526 (void)snprintf(buf, ODS_SE_MAXLINE,
"Reloading engine.\n");
527 client_printf(sockfd,
"%s", buf);
537cmdhandler_handle_cmd_stop(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
540 char buf[ODS_SE_MAXLINE];
546 (void)snprintf(buf, ODS_SE_MAXLINE, ODS_SE_STOP_RESPONSE);
547 client_printf(sockfd,
"%s", buf);
557cmdhandler_handle_cmd_start(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
559 char buf[ODS_SE_MAXLINE];
560 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine already running.\n");
561 client_printf(sockfd,
"%s", buf);
571cmdhandler_handle_cmd_running(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
573 char buf[ODS_SE_MAXLINE];
574 (void)snprintf(buf, ODS_SE_MAXLINE,
"Engine running.\n");
575 client_printf(sockfd,
"%s", buf);
585cmdhandler_handle_cmd_verbosity(
int sockfd, cmdhandler_ctx_type* context,
const char *cmd)
587 char buf[ODS_SE_MAXLINE];
589 val = atoi(cmdargument(cmd, NULL,
"1"));
590 ods_log_setverbosity(val);
591 (void)snprintf(buf, ODS_SE_MAXLINE,
"Verbosity level set to %i.\n", val);
592 client_printf(sockfd,
"%s", buf);
602cmdhandler_handle_cmd_error(
int sockfd, cmdhandler_ctx_type* context,
const char* str)
604 char buf[ODS_SE_MAXLINE];
605 (void)snprintf(buf, ODS_SE_MAXLINE,
"Error: %s.\n", str?str:
"(null)");
606 client_printf(sockfd,
"%s", buf);
615cmdhandler_handle_cmd_unknown(
int sockfd, cmdhandler_ctx_type* context,
const char* str)
617 char buf[ODS_SE_MAXLINE];
618 (void)snprintf(buf, ODS_SE_MAXLINE,
"Unknown command %s.\n",
620 client_printf(sockfd,
"%s", buf);
629cmdhandler_handle_cmd_timeleap(
int sockfd, cmdhandler_ctx_type* context,
char *cmd)
631 struct tm strtime_struct;
633 time_t now = time_now();
634 time_t time_leap = 0;
635 time_t next_leap = 0;
641 while(isspace(*cmd)) ++cmd;
643 while(isspace(*cmd)) ++cmd;
645 while(isspace(*cmd)) ++cmd;
647 if (strptime(cmd,
"%Y-%m-%d-%H:%M:%S", &tm)) {
649 time_leap = mktime(&tm);
650 client_printf(sockfd,
"Using %s parameter value as time to leap to\n", cmd);
652 client_printf_err(sockfd,
"Time leap: Error - could not convert '%s' to a time. Format is YYYY-MM-DD-HH:MM:SS \n", cmd);
655 if (!engine->
taskq || !engine->
taskq->tasks) {
656 client_printf(sockfd,
"There are no tasks scheduled.\n");
659 schedule_info(engine->
taskq, &next_leap, NULL, &taskcount);
661 strftime(strtime,
sizeof (strtime),
"%c", localtime_r(&now, &strtime_struct));
662 client_printf(sockfd,
"There are %i tasks scheduled.\nIt is now %s (%ld seconds since epoch)\n", taskcount, strtime, (
long) now);
663 set_time_now(time_leap);
664 strftime(strtime,
sizeof (strtime),
"%c", localtime_r(&time_leap, &strtime_struct));
665 client_printf(sockfd,
"Leaping to time %s (%ld seconds since epoch)\n", (strtime[0] ? strtime :
"(null)"), (
long) time_leap);
666 ods_log_info(
"Time leap: Leaping to time %s\n", strtime);
667 client_printf(sockfd,
"Waking up workers\n");
672struct cmd_func_block
helpCmdDef = {
"help", NULL, NULL, NULL, &cmdhandler_handle_cmd_help };
673struct cmd_func_block
zonesCmdDef = {
"zones", NULL, NULL, NULL, &cmdhandler_handle_cmd_zones };
674struct cmd_func_block
signCmdDef = {
"sign", NULL, NULL, NULL, &cmdhandler_handle_cmd_sign };
675struct cmd_func_block
clearCmdDef = {
"clear", NULL, NULL, NULL, &cmdhandler_handle_cmd_clear };
676struct cmd_func_block
queueCmdDef = {
"queue", NULL, NULL, NULL, &cmdhandler_handle_cmd_queue };
677struct cmd_func_block
flushCmdDef = {
"flush", NULL, NULL, NULL, &cmdhandler_handle_cmd_flush };
678struct cmd_func_block
updateCmdDef = {
"update", NULL, NULL, NULL, &cmdhandler_handle_cmd_update };
679struct cmd_func_block
stopCmdDef = {
"stop", NULL, NULL, NULL, &cmdhandler_handle_cmd_stop };
680struct cmd_func_block
startCmdDef = {
"start", NULL, NULL, NULL, &cmdhandler_handle_cmd_start };
681struct cmd_func_block
reloadCmdDef = {
"reload", NULL, NULL, NULL, &cmdhandler_handle_cmd_reload };
682struct cmd_func_block
retransferCmdDef = {
"retransfer", NULL, NULL, NULL, &cmdhandler_handle_cmd_retransfer };
683struct cmd_func_block
runningCmdDef = {
"running", NULL, NULL, NULL, &cmdhandler_handle_cmd_running };
684struct cmd_func_block
verbosityCmdDef = {
"verbosity", NULL, NULL, NULL, &cmdhandler_handle_cmd_verbosity };
685struct cmd_func_block
timeleapCmdDef = {
"time leap", NULL, NULL, NULL, &cmdhandler_handle_cmd_timeleap };
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
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)