dnssec-signzone.c
来自「非常好的dns解析软件」· C语言 代码 · 共 2,334 行 · 第 1/5 页
C
2,334 行
dns_rdataset_init(&rdataset); result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter); check_result(result, "dns_db_allrdatasets()"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { dns_rdatasetiter_current(rdsiter, &rdataset); if (rdataset.type != dns_rdatatype_nsec && rdataset.type != dns_rdatatype_rrsig) active = ISC_TRUE; dns_rdataset_disassociate(&rdataset); if (!active) result = dns_rdatasetiter_next(rdsiter); else result = ISC_R_NOMORE; } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); if (!active) { /*% * The node is empty of everything but NSEC / RRSIG records. */ for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); result = dns_db_deleterdataset(gdb, node, gversion, rdataset.type, rdataset.covers); check_result(result, "dns_db_deleterdataset()"); dns_rdataset_disassociate(&rdataset); } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); } else { /* * Delete RRSIGs for types that no longer exist. */ result = dns_db_allrdatasets(gdb, node, gversion, 0, &rdsiter2); check_result(result, "dns_db_allrdatasets()"); for (result = dns_rdatasetiter_first(rdsiter); result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter)) { dns_rdatasetiter_current(rdsiter, &rdataset); type = rdataset.type; covers = rdataset.covers; dns_rdataset_disassociate(&rdataset); if (type != dns_rdatatype_rrsig) continue; found = ISC_FALSE; for (result = dns_rdatasetiter_first(rdsiter2); !found && result == ISC_R_SUCCESS; result = dns_rdatasetiter_next(rdsiter2)) { dns_rdatasetiter_current(rdsiter2, &rdataset); if (rdataset.type == covers) found = ISC_TRUE; dns_rdataset_disassociate(&rdataset); } if (!found) { if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); result = dns_db_deleterdataset(gdb, node, gversion, type, covers); check_result(result, "dns_db_deleterdataset(rrsig)"); } else if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) fatal("rdataset iteration failed: %s", isc_result_totext(result)); } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter2); } dns_rdatasetiter_destroy(&rdsiter); return (active);}/*% * Extracts the TTL from the SOA. */static dns_ttl_tsoattl(void) { dns_rdataset_t soaset; dns_fixedname_t fname; dns_name_t *name; isc_result_t result; dns_ttl_t ttl; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_soa_t soa; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_rdataset_init(&soaset); result = dns_db_find(gdb, gorigin, gversion, dns_rdatatype_soa, 0, 0, NULL, name, &soaset, NULL); if (result != ISC_R_SUCCESS) fatal("failed to find an SOA at the zone apex: %s", isc_result_totext(result)); result = dns_rdataset_first(&soaset); check_result(result, "dns_rdataset_first"); dns_rdataset_current(&soaset, &rdata); result = dns_rdata_tostruct(&rdata, &soa, NULL); check_result(result, "dns_rdata_tostruct"); ttl = soa.minimum; dns_rdataset_disassociate(&soaset); return (ttl);}/*% * Increment (or set if nonzero) the SOA serial */static isc_result_tsetsoaserial(isc_uint32_t serial) { isc_result_t result; dns_dbnode_t *node = NULL; dns_rdataset_t rdataset; dns_rdata_t rdata = DNS_RDATA_INIT; isc_uint32_t old_serial, new_serial; result = dns_db_getoriginnode(gdb, &node); if (result != ISC_R_SUCCESS) return result; dns_rdataset_init(&rdataset); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_soa, 0, 0, &rdataset, NULL); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_rdataset_first(&rdataset); RUNTIME_CHECK(result == ISC_R_SUCCESS); dns_rdataset_current(&rdataset, &rdata); old_serial = dns_soa_getserial(&rdata); if (serial) { /* Set SOA serial to the value provided. */ new_serial = serial; } else { /* Increment SOA serial using RFC 1982 arithmetics */ new_serial = (old_serial + 1) & 0xFFFFFFFF; if (new_serial == 0) new_serial = 1; } /* If the new serial is not likely to cause a zone transfer * (a/ixfr) from servers having the old serial, warn the user. * * RFC1982 section 7 defines the maximum increment to be * (2^(32-1))-1. Using u_int32_t arithmetic, we can do a single * comparison. (5 - 6 == (2^32)-1, not negative-one) */ if (new_serial == old_serial || (new_serial - old_serial) > 0x7fffffffU) fprintf(stderr, "%s: warning: Serial number not advanced, " "zone may not transfer\n", program); dns_soa_setserial(new_serial, &rdata); result = dns_db_deleterdataset(gdb, node, gversion, dns_rdatatype_soa, 0); check_result(result, "dns_db_deleterdataset"); if (result != ISC_R_SUCCESS) goto cleanup; result = dns_db_addrdataset(gdb, node, gversion, 0, &rdataset, 0, NULL); check_result(result, "dns_db_addrdataset"); if (result != ISC_R_SUCCESS) goto cleanup;cleanup: dns_rdataset_disassociate(&rdataset); if (node != NULL) dns_db_detachnode(gdb, &node); dns_rdata_reset(&rdata); return (result);}/*% * Delete any RRSIG records at a node. */static voidcleannode(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node) { dns_rdatasetiter_t *rdsiter = NULL; dns_rdataset_t set; isc_result_t result, dresult; if (outputformat != dns_masterformat_text) return; dns_rdataset_init(&set); result = dns_db_allrdatasets(db, node, version, 0, &rdsiter); check_result(result, "dns_db_allrdatasets"); result = dns_rdatasetiter_first(rdsiter); while (result == ISC_R_SUCCESS) { isc_boolean_t destroy = ISC_FALSE; dns_rdatatype_t covers = 0; dns_rdatasetiter_current(rdsiter, &set); if (set.type == dns_rdatatype_rrsig) { covers = set.covers; destroy = ISC_TRUE; } dns_rdataset_disassociate(&set); result = dns_rdatasetiter_next(rdsiter); if (destroy) { dresult = dns_db_deleterdataset(db, node, version, dns_rdatatype_rrsig, covers); check_result(dresult, "dns_db_deleterdataset"); } } if (result != ISC_R_NOMORE) fatal("rdataset iteration failed: %s", isc_result_totext(result)); dns_rdatasetiter_destroy(&rdsiter);}/*% * Set up the iterator and global state before starting the tasks. */static voidpresign(void) { isc_result_t result; gdbiter = NULL; result = dns_db_createiterator(gdb, ISC_FALSE, &gdbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(gdbiter); check_result(result, "dns_dbiterator_first()");}/*% * Clean up the iterator and global state after the tasks complete. */static voidpostsign(void) { dns_dbiterator_destroy(&gdbiter);}/*% * Sign the apex of the zone. */static voidsignapex(void) { dns_dbnode_t *node = NULL; dns_fixedname_t fixed; dns_name_t *name; isc_result_t result; dns_fixedname_init(&fixed); name = dns_fixedname_name(&fixed); result = dns_dbiterator_current(gdbiter, &node, name); check_result(result, "dns_dbiterator_current()"); signname(node, name); dumpnode(name, node); cleannode(gdb, gversion, node); dns_db_detachnode(gdb, &node); result = dns_dbiterator_next(gdbiter); if (result == ISC_R_NOMORE) finished = ISC_TRUE; else if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result));}/*% * Assigns a node to a worker thread. This is protected by the master task's * lock. */static voidassignwork(isc_task_t *task, isc_task_t *worker) { dns_fixedname_t *fname; dns_name_t *name; dns_dbnode_t *node; sevent_t *sevent; dns_rdataset_t nsec; isc_boolean_t found; isc_result_t result; if (shuttingdown) return; if (finished) { if (assigned == completed) { isc_task_detach(&task); isc_app_shutdown(); } return; } fname = isc_mem_get(mctx, sizeof(dns_fixedname_t)); if (fname == NULL) fatal("out of memory"); dns_fixedname_init(fname); name = dns_fixedname_name(fname); node = NULL; found = ISC_FALSE; LOCK(&namelock); while (!found) { result = dns_dbiterator_current(gdbiter, &node, name); if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result)); dns_rdataset_init(&nsec); result = dns_db_findrdataset(gdb, node, gversion, dns_rdatatype_nsec, 0, 0, &nsec, NULL); if (result == ISC_R_SUCCESS) found = ISC_TRUE; else dumpnode(name, node); if (dns_rdataset_isassociated(&nsec)) dns_rdataset_disassociate(&nsec); if (!found) dns_db_detachnode(gdb, &node); result = dns_dbiterator_next(gdbiter); if (result == ISC_R_NOMORE) { finished = ISC_TRUE; break; } else if (result != ISC_R_SUCCESS) fatal("failure iterating database: %s", isc_result_totext(result)); } UNLOCK(&namelock); if (!found) { if (assigned == completed) { isc_task_detach(&task); isc_app_shutdown(); } isc_mem_put(mctx, fname, sizeof(dns_fixedname_t)); return; } sevent = (sevent_t *) isc_event_allocate(mctx, task, SIGNER_EVENT_WORK, sign, NULL, sizeof(sevent_t)); if (sevent == NULL) fatal("failed to allocate event\n"); sevent->node = node; sevent->fname = fname; isc_task_send(worker, ISC_EVENT_PTR(&sevent)); assigned++;}/*% * Start a worker task */static voidstartworker(isc_task_t *task, isc_event_t *event) { isc_task_t *worker; worker = (isc_task_t *)event->ev_arg; assignwork(task, worker); isc_event_free(&event);}/*% * Write a node to the output file, and restart the worker task. */static voidwritenode(isc_task_t *task, isc_event_t *event) { isc_task_t *worker; sevent_t *sevent = (sevent_t *)event; completed++; worker = (isc_task_t *)event->ev_sender; dumpnode(dns_fixedname_name(sevent->fname), sevent->node); cleannode(gdb, gversion, sevent->node); dns_db_detachnode(gdb, &sevent->node); isc_mem_put(mctx, sevent->fname, sizeof(dns_fixedname_t)); assignwork(task, worker); isc_event_free(&event);}/*% * Sign a database node. */static voidsign(isc_task_t *task, isc_event_t *event) { dns_fixedname_t *fname; dns_dbnode_t *node; sevent_t *sevent, *wevent; sevent = (sevent_t *)event; node = sevent->node; fname = sevent->fname; isc_event_free(&event); signname(node, dns_fixedname_name(fname)); wevent = (sevent_t *) isc_event_allocate(mctx, task, SIGNER_EVENT_WRITE, writenode, NULL, sizeof(sevent_t)); if (wevent == NULL) fatal("failed to allocate event\n"); wevent->node = node; wevent->fname = fname; isc_task_send(master, ISC_EVENT_PTR(&wevent));}/*% * Generate NSEC records for the zone. */static voidnsecify(void) { dns_dbiterator_t *dbiter = NULL; dns_dbnode_t *node = NULL, *nextnode = NULL; dns_fixedname_t fname, fnextname, fzonecut; dns_name_t *name, *nextname, *zonecut; isc_boolean_t done = ISC_FALSE; isc_result_t result; dns_fixedname_init(&fname); name = dns_fixedname_name(&fname); dns_fixedname_init(&fnextname); nextname = dns_fixedname_name(&fnextname); dns_fixedname_init(&fzonecut); zonecut = NULL; result = dns_db_createiterator(gdb, ISC_FALSE, &dbiter); check_result(result, "dns_db_createiterator()"); result = dns_dbiterator_first(dbiter); check_result(result, "dns_dbiterator_first()"); while (!done) { dns_dbiterator_current(dbiter, &node, name); if (delegation(name, node, NULL)) { zonecut = dns_fixedname_name(&fzonecut); dns_name_copy(name, zonecut, NULL); } result = dns_dbiterator_next(dbiter); nextnode = NULL; while (result == ISC_R_SUCCESS) { isc_boolean_t active = ISC_FALSE; result = dns_dbiterator_current(dbiter, &nextnode, nextname); if (result != ISC_R_SUCCESS) break; active = active_node(nextnode); if (!active) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; } if (!dns_name_issubdomain(nextname, gorigin) || (zonecut != NULL && dns_name_issubdomain(nextname, zonecut))) { dns_db_detachnode(gdb, &nextnode); result = dns_dbiterator_next(dbiter); continue; }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?