📄 rndc.c
字号:
static voidrndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { isc_result_t result; char socktext[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, socktext, sizeof(socktext)); notify("using server %s (%s)", servername, socktext); DO("create socket", isc_socket_create(socketmgr, isc_sockaddr_pf(addr), isc_sockettype_tcp, &sock)); DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, NULL)); connects++;}static voidrndc_start(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); get_addresses(servername, (in_port_t) remoteport); currentaddr = 0; rndc_startconnect(&serveraddrs[currentaddr++], task);}static voidparse_config(isc_mem_t *mctx, isc_log_t *log, const char *keyname, cfg_parser_t **pctxp, cfg_obj_t **configp){ isc_result_t result; const char *conffile = admin_conffile; cfg_obj_t *defkey = NULL; cfg_obj_t *options = NULL; cfg_obj_t *servers = NULL; cfg_obj_t *server = NULL; cfg_obj_t *keys = NULL; cfg_obj_t *key = NULL; cfg_obj_t *defport = NULL; cfg_obj_t *secretobj = NULL; cfg_obj_t *algorithmobj = NULL; cfg_obj_t *config = NULL; cfg_listelt_t *elt; const char *secretstr; const char *algorithm; static char secretarray[1024]; const cfg_type_t *conftype = &cfg_type_rndcconf; isc_boolean_t key_only = ISC_FALSE; if (! isc_file_exists(conffile)) { conffile = admin_keyfile; conftype = &cfg_type_rndckey; if (! isc_file_exists(conffile)) fatal("neither %s nor %s was found", admin_conffile, admin_keyfile); key_only = ISC_TRUE; } DO("create parser", cfg_parser_create(mctx, log, pctxp)); /* * The parser will output its own errors, so DO() is not used. */ result = cfg_parse_file(*pctxp, conffile, conftype, &config); if (result != ISC_R_SUCCESS) fatal("could not load rndc configuration"); if (!key_only) (void)cfg_map_get(config, "options", &options); if (key_only && servername == NULL) servername = "127.0.0.1"; else if (servername == NULL && options != NULL) { cfg_obj_t *defserverobj = NULL; (void)cfg_map_get(options, "default-server", &defserverobj); if (defserverobj != NULL) servername = cfg_obj_asstring(defserverobj); } if (servername == NULL) fatal("no server specified and no default"); if (!key_only) { (void)cfg_map_get(config, "server", &servers); if (servers != NULL) { for (elt = cfg_list_first(servers); elt != NULL; elt = cfg_list_next(elt)) { const char *name; server = cfg_listelt_value(elt); name = cfg_obj_asstring(cfg_map_getname(server)); if (strcasecmp(name, servername) == 0) break; server = NULL; } } } /* * Look for the name of the key to use. */ if (keyname != NULL) ; /* Was set on command line, do nothing. */ else if (server != NULL) { DO("get key for server", cfg_map_get(server, "key", &defkey)); keyname = cfg_obj_asstring(defkey); } else if (options != NULL) { DO("get default key", cfg_map_get(options, "default-key", &defkey)); keyname = cfg_obj_asstring(defkey); } else if (!key_only) fatal("no key for server and no default"); /* * Get the key's definition. */ if (key_only) DO("get key", cfg_map_get(config, "key", &key)); else { DO("get config key list", cfg_map_get(config, "key", &keys)); for (elt = cfg_list_first(keys); elt != NULL; elt = cfg_list_next(elt)) { key = cfg_listelt_value(elt); if (strcasecmp(cfg_obj_asstring(cfg_map_getname(key)), keyname) == 0) break; } if (elt == NULL) fatal("no key definition for name %s", keyname); } (void)cfg_map_get(key, "secret", &secretobj); (void)cfg_map_get(key, "algorithm", &algorithmobj); if (secretobj == NULL || algorithmobj == NULL) fatal("key must have algorithm and secret"); secretstr = cfg_obj_asstring(secretobj); algorithm = cfg_obj_asstring(algorithmobj); if (strcasecmp(algorithm, "hmac-md5") != 0) fatal("unsupported algorithm: %s", algorithm); secret.rstart = (unsigned char *)secretarray; secret.rend = (unsigned char *)secretarray + sizeof(secretarray); DO("decode base64 secret", isccc_base64_decode(secretstr, &secret)); secret.rend = secret.rstart; secret.rstart = (unsigned char *)secretarray; /* * Find the port to connect to. */ if (remoteport != 0) ; /* Was set on command line, do nothing. */ else { if (server != NULL) (void)cfg_map_get(server, "port", &defport); if (defport == NULL && options != NULL) (void)cfg_map_get(options, "default-port", &defport); } if (defport != NULL) { remoteport = cfg_obj_asuint32(defport); if (remoteport > 65535 || remoteport == 0) fatal("port %d out of range", remoteport); } else if (remoteport == 0) remoteport = NS_CONTROL_PORT; *configp = config;}intmain(int argc, char **argv) { isc_boolean_t show_final_mem = ISC_FALSE; isc_result_t result = ISC_R_SUCCESS; isc_taskmgr_t *taskmgr = NULL; isc_task_t *task = NULL; isc_log_t *log = NULL; isc_logconfig_t *logconfig = NULL; isc_logdestination_t logdest; cfg_parser_t *pctx = NULL; cfg_obj_t *config = NULL; const char *keyname = NULL; char *p; size_t argslen; int ch; int i; result = isc_file_progname(*argv, program, sizeof(program)); if (result != ISC_R_SUCCESS) memcpy(program, "rndc", 5); progname = program; admin_conffile = RNDC_CONFFILE; admin_keyfile = RNDC_KEYFILE; result = isc_app_start(); if (result != ISC_R_SUCCESS) fatal("isc_app_start() failed: %s", isc_result_totext(result)); while ((ch = isc_commandline_parse(argc, argv, "c:k:Mmp:s:Vy:")) != -1) { switch (ch) { case 'c': admin_conffile = isc_commandline_argument; break; case 'k': admin_keyfile = isc_commandline_argument; break; case 'M': isc_mem_debugging = ISC_MEM_DEBUGTRACE; break; case 'm': show_final_mem = ISC_TRUE; break; case 'p': remoteport = atoi(isc_commandline_argument); if (remoteport > 65535 || remoteport == 0) fatal("port '%s' out of range", isc_commandline_argument); break; case 's': servername = isc_commandline_argument; break; case 'V': verbose = ISC_TRUE; break; case 'y': keyname = isc_commandline_argument; break; case '?': usage(0); break; default: fatal("unexpected error parsing command arguments: " "got %c\n", ch); break; } } argc -= isc_commandline_index; argv += isc_commandline_index; if (argc < 1) usage(1); isc_random_get(&serial); DO("create memory context", isc_mem_create(0, 0, &mctx)); DO("create socket manager", isc_socketmgr_create(mctx, &socketmgr)); DO("create task manager", isc_taskmgr_create(mctx, 1, 0, &taskmgr)); DO("create task", isc_task_create(taskmgr, 0, &task)); DO("create logging context", isc_log_create(mctx, &log, &logconfig)); isc_log_setcontext(log); DO("setting log tag", isc_log_settag(logconfig, progname)); logdest.file.stream = stderr; logdest.file.name = NULL; logdest.file.versions = ISC_LOG_ROLLNEVER; logdest.file.maximum_size = 0; DO("creating log channel", isc_log_createchannel(logconfig, "stderr", ISC_LOG_TOFILEDESC, ISC_LOG_INFO, &logdest, ISC_LOG_PRINTTAG|ISC_LOG_PRINTLEVEL)); DO("enabling log channel", isc_log_usechannel(logconfig, "stderr", NULL, NULL)); parse_config(mctx, log, keyname, &pctx, &config); isccc_result_register(); command = *argv; /* * Convert argc/argv into a space-delimited command string * similar to what the user might enter in interactive mode * (if that were implemented). */ argslen = 0; for (i = 0; i < argc; i++) argslen += strlen(argv[i]) + 1; args = isc_mem_get(mctx, argslen); if (args == NULL) DO("isc_mem_get", ISC_R_NOMEMORY); p = args; for (i = 0; i < argc; i++) { size_t len = strlen(argv[i]); memcpy(p, argv[i], len); p += len; *p++ = ' '; } p--; *p++ = '\0'; INSIST(p == args + argslen); notify("%s", command); if (strcmp(command, "restart") == 0) fatal("'%s' is not implemented", command); DO("post event", isc_app_onrun(mctx, task, rndc_start, NULL)); result = isc_app_run(); if (result != ISC_R_SUCCESS) fatal("isc_app_run() failed: %s", isc_result_totext(result)); if (connects > 0 || sends > 0 || recvs > 0) isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); isc_task_detach(&task); isc_taskmgr_destroy(&taskmgr); isc_socketmgr_destroy(&socketmgr); isc_log_destroy(&log); isc_log_setcontext(NULL); cfg_obj_destroy(pctx, &config); cfg_parser_destroy(&pctx); isc_mem_put(mctx, args, argslen); isccc_ccmsg_invalidate(&ccmsg); if (show_final_mem) isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx); if (failed) return (1); return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -