📄 nsupdate.c
字号:
isc_buffer_t b; dns_rdataset_t *rds; isc_buffer_init(&b, buf, sizeof(buf) - 1); result = dns_rcode_totext(answer->rcode, &b); check_result(result, "dns_rcode_totext"); rds = dns_message_gettsig(answer, NULL); if (rds != NULL) check_tsig_error(rds, &b); fprintf(stderr, "update failed: %.*s\n", (int)isc_buffer_usedlength(&b), buf); } } if (debugging) { isc_buffer_t *buf = NULL; int bufsz; bufsz = INITTEXT; do { if (bufsz > MAXTEXT) { fprintf(stderr, "could not allocate large " "enough buffer to display message\n"); exit(1); } if (buf != NULL) isc_buffer_free(&buf); result = isc_buffer_allocate(mctx, &buf, bufsz); check_result(result, "isc_buffer_allocate"); result = dns_message_totext(answer, style, 0, buf); bufsz *= 2; } while (result == ISC_R_NOSPACE); check_result(result, "dns_message_totext"); fprintf(stderr, "\nReply from update query:\n%.*s\n", (int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf)); isc_buffer_free(&buf); } done: dns_request_destroy(&request); isc_event_free(&event); done_update();}static voidsend_update(dns_name_t *zonename, isc_sockaddr_t *master, isc_sockaddr_t *srcaddr){ isc_result_t result; dns_request_t *request = NULL; dns_name_t *name = NULL; dns_rdataset_t *rdataset = NULL; unsigned int options = 0; ddebug("send_update()"); result = dns_message_gettempname(updatemsg, &name); check_result(result, "dns_message_gettempname"); dns_name_init(name, NULL); dns_name_clone(zonename, name); result = dns_message_gettemprdataset(updatemsg, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(updatemsg, name, DNS_SECTION_ZONE); if (usevc) options |= DNS_REQUESTOPT_TCP; if (tsigkey == NULL && sig0key != NULL) { result = dns_message_setsig0key(updatemsg, sig0key); check_result(result, "dns_message_setsig0key"); } if (debugging) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(master, addrbuf, sizeof(addrbuf)); fprintf(stderr, "Sending update to %s\n", addrbuf); } result = dns_request_createvia3(requestmgr, updatemsg, srcaddr, master, options, tsigkey, timeout, udp_timeout, udp_retries, global_task, update_completed, NULL, &request); check_result(result, "dns_request_createvia3"); if (debugging) show_message(updatemsg); requests++;}static voidrecvsoa(isc_task_t *task, isc_event_t *event) { dns_requestevent_t *reqev = NULL; dns_request_t *request = NULL; isc_result_t result, eresult; dns_message_t *rcvmsg = NULL; dns_section_t section; dns_name_t *name = NULL; dns_rdataset_t *soaset = NULL; dns_rdata_soa_t soa; dns_rdata_t soarr = DNS_RDATA_INIT; int pass = 0; dns_name_t master; isc_sockaddr_t *serveraddr, tempaddr; dns_name_t *zonename; nsu_requestinfo_t *reqinfo; dns_message_t *soaquery = NULL; isc_sockaddr_t *addr; isc_boolean_t seencname = ISC_FALSE; UNUSED(task); ddebug("recvsoa()"); requests--; REQUIRE(event->ev_type == DNS_EVENT_REQUESTDONE); reqev = (dns_requestevent_t *)event; request = reqev->request; eresult = reqev->result; reqinfo = reqev->ev_arg; soaquery = reqinfo->msg; addr = reqinfo->addr; if (shuttingdown) { dns_request_destroy(&request); dns_message_destroy(&soaquery); isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); isc_event_free(&event); maybeshutdown(); return; } if (eresult != ISC_R_SUCCESS) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(addr, addrbuf, sizeof(addrbuf)); fprintf(stderr, "; Communication with %s failed: %s\n", addrbuf, isc_result_totext(eresult)); if (userserver != NULL) fatal("could not talk to specified name server"); else if (++ns_inuse >= lwconf->nsnext) fatal("could not talk to any default name server"); ddebug("Destroying request [%p]", request); dns_request_destroy(&request); dns_message_renderreset(soaquery); sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); isc_event_free(&event); setzoneclass(dns_rdataclass_none); return; } isc_mem_put(mctx, reqinfo, sizeof(nsu_requestinfo_t)); isc_event_free(&event); reqev = NULL; ddebug("About to create rcvmsg"); result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &rcvmsg); check_result(result, "dns_message_create"); result = dns_request_getresponse(request, rcvmsg, DNS_MESSAGEPARSE_PRESERVEORDER); if (result == DNS_R_TSIGERRORSET && userserver != NULL) { dns_message_destroy(&rcvmsg); ddebug("Destroying request [%p]", request); dns_request_destroy(&request); reqinfo = isc_mem_get(mctx, sizeof(nsu_requestinfo_t)); if (reqinfo == NULL) fatal("out of memory"); reqinfo->msg = soaquery; reqinfo->addr = addr; dns_message_renderreset(soaquery); ddebug("retrying soa request without TSIG"); result = dns_request_createvia3(requestmgr, soaquery, localaddr, addr, 0, NULL, FIND_TIMEOUT * 20, FIND_TIMEOUT * 20, 3, global_task, recvsoa, reqinfo, &request); check_result(result, "dns_request_createvia"); requests++; return; } check_result(result, "dns_request_getresponse"); section = DNS_SECTION_ANSWER; if (debugging) { isc_buffer_t *buf = NULL; int bufsz; bufsz = INITTEXT; do { if (buf != NULL) isc_buffer_free(&buf); if (bufsz > MAXTEXT) { fprintf(stderr, "could not allocate enough " "space for debugging message\n"); exit(1); } result = isc_buffer_allocate(mctx, &buf, bufsz); check_result(result, "isc_buffer_allocate"); result = dns_message_totext(rcvmsg, style, 0, buf); } while (result == ISC_R_NOSPACE); check_result(result, "dns_message_totext"); fprintf(stderr, "Reply from SOA query:\n%.*s\n", (int)isc_buffer_usedlength(buf), (char*)isc_buffer_base(buf)); isc_buffer_free(&buf); } if (rcvmsg->rcode != dns_rcode_noerror && rcvmsg->rcode != dns_rcode_nxdomain) fatal("response to SOA query was unsuccessful"); lookforsoa: if (pass == 0) section = DNS_SECTION_ANSWER; else if (pass == 1) section = DNS_SECTION_AUTHORITY; else fatal("response to SOA query didn't contain an SOA"); result = dns_message_firstname(rcvmsg, section); if (result != ISC_R_SUCCESS) { pass++; goto lookforsoa; } while (result == ISC_R_SUCCESS) { name = NULL; dns_message_currentname(rcvmsg, section, &name); soaset = NULL; result = dns_message_findtype(name, dns_rdatatype_soa, 0, &soaset); if (result == ISC_R_SUCCESS) break; if (section == DNS_SECTION_ANSWER) { dns_rdataset_t *tset = NULL; if (dns_message_findtype(name, dns_rdatatype_cname, 0, &tset) == ISC_R_SUCCESS || dns_message_findtype(name, dns_rdatatype_dname, 0, &tset) == ISC_R_SUCCESS ) { seencname = ISC_TRUE; break; } } result = dns_message_nextname(rcvmsg, section); } if (soaset == NULL && !seencname) { pass++; goto lookforsoa; } if (seencname) { dns_name_t tname; unsigned int nlabels; result = dns_message_firstname(soaquery, DNS_SECTION_QUESTION); INSIST(result == ISC_R_SUCCESS); name = NULL; dns_message_currentname(soaquery, DNS_SECTION_QUESTION, &name); nlabels = dns_name_countlabels(name); if (nlabels == 1) fatal("could not find enclosing zone"); dns_name_init(&tname, NULL); dns_name_getlabelsequence(name, 1, nlabels - 1, &tname); dns_name_clone(&tname, name); dns_request_destroy(&request); dns_message_renderreset(soaquery); if (userserver != NULL) sendrequest(localaddr, userserver, soaquery, &request); else sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); goto out; } if (debugging) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(name, namestr, sizeof(namestr)); fprintf(stderr, "Found zone name: %s\n", namestr); } result = dns_rdataset_first(soaset); check_result(result, "dns_rdataset_first"); dns_rdata_init(&soarr); dns_rdataset_current(soaset, &soarr); result = dns_rdata_tostruct(&soarr, &soa, NULL); check_result(result, "dns_rdata_tostruct"); dns_name_init(&master, NULL); dns_name_clone(&soa.origin, &master); if (userzone != NULL) zonename = userzone; else zonename = name; if (debugging) { char namestr[DNS_NAME_FORMATSIZE]; dns_name_format(&master, namestr, sizeof(namestr)); fprintf(stderr, "The master is: %s\n", namestr); } if (userserver != NULL) serveraddr = userserver; else { char serverstr[DNS_NAME_MAXTEXT+1]; isc_buffer_t buf; isc_buffer_init(&buf, serverstr, sizeof(serverstr)); result = dns_name_totext(&master, ISC_TRUE, &buf); check_result(result, "dns_name_totext"); serverstr[isc_buffer_usedlength(&buf)] = 0; get_address(serverstr, DNSDEFAULTPORT, &tempaddr); serveraddr = &tempaddr; } send_update(zonename, serveraddr, localaddr); dns_message_destroy(&soaquery); dns_request_destroy(&request); out: setzoneclass(dns_rdataclass_none); dns_rdata_freestruct(&soa); dns_message_destroy(&rcvmsg); ddebug("Out of recvsoa");}static voidsendrequest(isc_sockaddr_t *srcaddr, isc_sockaddr_t *destaddr, dns_message_t *msg, dns_request_t **request){ isc_result_t result; nsu_requestinfo_t *reqinfo; reqinfo = isc_mem_get(mctx, sizeof(nsu_requestinfo_t)); if (reqinfo == NULL) fatal("out of memory"); reqinfo->msg = msg; reqinfo->addr = destaddr; result = dns_request_createvia3(requestmgr, msg, srcaddr, destaddr, 0, (userserver != NULL) ? tsigkey : NULL, FIND_TIMEOUT * 20, FIND_TIMEOUT, 3, global_task, recvsoa, reqinfo, request); check_result(result, "dns_request_createvia"); requests++;}static voidstart_update(void) { isc_result_t result; dns_rdataset_t *rdataset = NULL; dns_name_t *name = NULL; dns_request_t *request = NULL; dns_message_t *soaquery = NULL; dns_name_t *firstname; dns_section_t section = DNS_SECTION_UPDATE; ddebug("start_update()"); if (answer != NULL) dns_message_destroy(&answer); result = dns_message_firstname(updatemsg, section); if (result == ISC_R_NOMORE) { section = DNS_SECTION_PREREQUISITE; result = dns_message_firstname(updatemsg, section); } if (result != ISC_R_SUCCESS) { done_update(); return; } if (userzone != NULL && userserver != NULL) { send_update(userzone, userserver, localaddr); setzoneclass(dns_rdataclass_none); return; } result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &soaquery); check_result(result, "dns_message_create"); soaquery->flags |= DNS_MESSAGEFLAG_RD; result = dns_message_gettempname(soaquery, &name); check_result(result, "dns_message_gettempname"); result = dns_message_gettemprdataset(soaquery, &rdataset); check_result(result, "dns_message_gettemprdataset"); dns_rdataset_makequestion(rdataset, getzoneclass(), dns_rdatatype_soa); firstname = NULL; dns_message_currentname(updatemsg, section, &firstname); dns_name_init(name, NULL); dns_name_clone(firstname, name); ISC_LIST_INIT(name->list); ISC_LIST_APPEND(name->list, rdataset, link); dns_message_addname(soaquery, name, DNS_SECTION_QUESTION); if (userserver != NULL) sendrequest(localaddr, userserver, soaquery, &request); else { ns_inuse = 0; sendrequest(localaddr, &servers[ns_inuse], soaquery, &request); }}static voidcleanup(void) { ddebug("cleanup()"); if (answer != NULL) dns_message_destroy(&answer); ddebug("Shutting down task manager"); isc_taskmgr_destroy(&taskmgr); ddebug("Destroying event"); isc_event_free(&global_event); ddebug("Shutting down socket manager"); isc_socketmgr_destroy(&socketmgr); ddebug("Shutting down timer manager"); isc_timermgr_destroy(&timermgr); ddebug("Destroying hash context"); isc_hash_destroy(); ddebug("Destroying memory context"); if (memdebugging) isc_mem_stats(mctx, stderr); isc_mem_destroy(&mctx);}static voidgetinput(isc_task_t *task, isc_event_t *event) { isc_boolean_t more; UNUSED(task); if (shuttingdown) { maybeshutdown(); return; } if (global_event == NULL) global_event = event; reset_system(); more = user_interaction(); if (!more) { isc_app_shutdown(); return; } start_update(); return;}intmain(int argc, char **argv) { isc_result_t result; style = &dns_master_style_debug; input = stdin; interactive = ISC_TF(isatty(0)); isc_app_start(); parse_args(argc, argv); setup_system(); result = isc_app_onrun(mctx, global_task, getinput, NULL); check_result(result, "isc_app_onrun"); (void)isc_app_run(); cleanup(); isc_app_finish(); if (seenerror) return (2); else return (0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -