📄 query.c
字号:
fname = dns_fixedname_name(&foundname); /* * Get resources and make 'name' be the database origin. */ result = dns_message_gettempname(client->message, &name); if (result != ISC_R_SUCCESS) { CTRACE("query_addns: dns_message_gettempname failed: done"); return (result); } dns_name_init(name, NULL); dns_name_clone(dns_db_origin(db), name); rdataset = query_newrdataset(client); if (rdataset == NULL) { CTRACE("query_addns: query_newrdataset failed"); eresult = DNS_R_SERVFAIL; goto cleanup; } if (WANTDNSSEC(client)) { sigrdataset = query_newrdataset(client); if (sigrdataset == NULL) { CTRACE("query_addns: query_newrdataset failed"); eresult = DNS_R_SERVFAIL; goto cleanup; } } /* * Find the NS rdataset. */ CTRACE("query_addns: calling dns_db_find"); result = dns_db_find(db, name, NULL, dns_rdatatype_ns, client->query.dboptions, 0, &node, fname, rdataset, sigrdataset); CTRACE("query_addns: dns_db_find complete"); if (result != ISC_R_SUCCESS) { CTRACE("query_addns: dns_db_find failed"); /* * This is bad. We tried to get the NS rdataset at the zone * top and it didn't work! */ eresult = DNS_R_SERVFAIL; } else { if (sigrdataset != NULL) sigrdatasetp = &sigrdataset; else sigrdatasetp = NULL; query_addrrset(client, &name, &rdataset, sigrdatasetp, NULL, DNS_SECTION_AUTHORITY); } cleanup: CTRACE("query_addns: cleanup"); query_putrdataset(client, &rdataset); if (sigrdataset != NULL) query_putrdataset(client, &sigrdataset); if (name != NULL) query_releasename(client, &name); if (node != NULL) dns_db_detachnode(db, &node); CTRACE("query_addns: done"); return (eresult);}static inline isc_result_tquery_addcnamelike(ns_client_t *client, dns_name_t *qname, dns_name_t *tname, dns_trust_t trust, dns_name_t **anamep, dns_rdatatype_t type){ dns_rdataset_t *rdataset; dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; isc_result_t result; isc_region_t r; /* * We assume the name data referred to by tname won't go away. */ REQUIRE(anamep != NULL); rdatalist = NULL; result = dns_message_gettemprdatalist(client->message, &rdatalist); if (result != ISC_R_SUCCESS) return (result); rdata = NULL; result = dns_message_gettemprdata(client->message, &rdata); if (result != ISC_R_SUCCESS) return (result); rdataset = NULL; result = dns_message_gettemprdataset(client->message, &rdataset); if (result != ISC_R_SUCCESS) return (result); dns_rdataset_init(rdataset); result = dns_name_dup(qname, client->mctx, *anamep); if (result != ISC_R_SUCCESS) { dns_message_puttemprdataset(client->message, &rdataset); return (result); } rdatalist->type = type; rdatalist->covers = 0; rdatalist->rdclass = client->message->rdclass; rdatalist->ttl = 0; dns_name_toregion(tname, &r); rdata->data = r.base; rdata->length = r.length; rdata->rdclass = client->message->rdclass; rdata->type = type; ISC_LIST_INIT(rdatalist->rdata); ISC_LIST_APPEND(rdatalist->rdata, rdata, link); RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS); rdataset->trust = trust; query_addrrset(client, anamep, &rdataset, NULL, NULL, DNS_SECTION_ANSWER); if (rdataset != NULL) { if (dns_rdataset_isassociated(rdataset)) dns_rdataset_disassociate(rdataset); dns_message_puttemprdataset(client->message, &rdataset); } return (ISC_R_SUCCESS);}static voidquery_addbestns(ns_client_t *client) { dns_db_t *db, *zdb; dns_dbnode_t *node; dns_name_t *fname, *zfname; dns_rdataset_t *rdataset, *sigrdataset, *zrdataset, *zsigrdataset; isc_boolean_t is_zone, use_zone; isc_buffer_t *dbuf; isc_result_t result; dns_dbversion_t *version; dns_zone_t *zone; isc_buffer_t b; CTRACE("query_addbestns"); fname = NULL; zfname = NULL; rdataset = NULL; zrdataset = NULL; sigrdataset = NULL; zsigrdataset = NULL; node = NULL; db = NULL; zdb = NULL; version = NULL; zone = NULL; is_zone = ISC_FALSE; use_zone = ISC_FALSE; /* * Find the right database. */ result = query_getdb(client, client->query.qname, dns_rdatatype_ns, 0, &zone, &db, &version, &is_zone); if (result != ISC_R_SUCCESS) goto cleanup; db_find: /* * We'll need some resources... */ dbuf = query_getnamebuf(client); if (dbuf == NULL) goto cleanup; fname = query_newname(client, dbuf, &b); rdataset = query_newrdataset(client); if (fname == NULL || rdataset == NULL) goto cleanup; if (WANTDNSSEC(client)) { sigrdataset = query_newrdataset(client); if (sigrdataset == NULL) goto cleanup; } /* * Now look for the zonecut. */ if (is_zone) { result = dns_db_find(db, client->query.qname, version, dns_rdatatype_ns, client->query.dboptions, client->now, &node, fname, rdataset, sigrdataset); if (result != DNS_R_DELEGATION) goto cleanup; if (USECACHE(client)) { query_keepname(client, fname, dbuf); zdb = db; zfname = fname; fname = NULL; zrdataset = rdataset; rdataset = NULL; zsigrdataset = sigrdataset; sigrdataset = NULL; dns_db_detachnode(db, &node); version = NULL; db = NULL; dns_db_attach(client->view->cachedb, &db); is_zone = ISC_FALSE; goto db_find; } } else { result = dns_db_findzonecut(db, client->query.qname, client->query.dboptions, client->now, &node, fname, rdataset, sigrdataset); if (result == ISC_R_SUCCESS) { if (zfname != NULL && !dns_name_issubdomain(fname, zfname)) { /* * We found a zonecut in the cache, but our * zone delegation is better. */ use_zone = ISC_TRUE; } } else if (result == ISC_R_NOTFOUND && zfname != NULL) { /* * We didn't find anything in the cache, but we * have a zone delegation, so use it. */ use_zone = ISC_TRUE; } else goto cleanup; } if (use_zone) { query_releasename(client, &fname); fname = zfname; zfname = NULL; /* * We've already done query_keepname() on * zfname, so we must set dbuf to NULL to * prevent query_addrrset() from trying to * call query_keepname() again. */ dbuf = NULL; query_putrdataset(client, &rdataset); if (sigrdataset != NULL) query_putrdataset(client, &sigrdataset); rdataset = zrdataset; zrdataset = NULL; sigrdataset = zsigrdataset; zsigrdataset = NULL; } if ((client->query.dboptions & DNS_DBFIND_PENDINGOK) == 0 && (rdataset->trust == dns_trust_pending || (sigrdataset != NULL && sigrdataset->trust == dns_trust_pending))) goto cleanup; if (WANTDNSSEC(client) && SECURE(client) && (rdataset->trust == dns_trust_glue || (sigrdataset != NULL && sigrdataset->trust == dns_trust_glue))) goto cleanup; query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, DNS_SECTION_AUTHORITY); cleanup: if (rdataset != NULL) query_putrdataset(client, &rdataset); if (sigrdataset != NULL) query_putrdataset(client, &sigrdataset); if (fname != NULL) query_releasename(client, &fname); if (node != NULL) dns_db_detachnode(db, &node); if (db != NULL) dns_db_detach(&db); if (zone != NULL) dns_zone_detach(&zone); if (zdb != NULL) { query_putrdataset(client, &zrdataset); if (zsigrdataset != NULL) query_putrdataset(client, &zsigrdataset); if (zfname != NULL) query_releasename(client, &zfname); dns_db_detach(&zdb); }}static voidquery_addds(ns_client_t *client, dns_db_t *db, dns_dbnode_t *node) { dns_name_t *rname; dns_rdataset_t *rdataset, *sigrdataset; isc_result_t result; CTRACE("query_addds"); rname = NULL; rdataset = NULL; sigrdataset = NULL; /* * We'll need some resources... */ rdataset = query_newrdataset(client); sigrdataset = query_newrdataset(client); if (rdataset == NULL || sigrdataset == NULL) goto cleanup; /* * Look for the DS record, which may or may not be present. */ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ds, 0, client->now, rdataset, sigrdataset); /* * If we didn't find it, look for an NSEC. */ if (result == ISC_R_NOTFOUND) result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_nsec, 0, client->now, rdataset, sigrdataset); if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) goto cleanup; if (!dns_rdataset_isassociated(rdataset) || !dns_rdataset_isassociated(sigrdataset)) goto cleanup; /* * We've already added the NS record, so if the name's not there, * we have other problems. Use this name rather than calling * query_addrrset(). */ result = dns_message_firstname(client->message, DNS_SECTION_AUTHORITY); if (result != ISC_R_SUCCESS) goto cleanup; rname = NULL; dns_message_currentname(client->message, DNS_SECTION_AUTHORITY, &rname); result = dns_message_findtype(rname, dns_rdatatype_ns, 0, NULL); if (result != ISC_R_SUCCESS) goto cleanup; ISC_LIST_APPEND(rname->list, rdataset, link); ISC_LIST_APPEND(rname->list, sigrdataset, link); rdataset = NULL; sigrdataset = NULL; cleanup: if (rdataset != NULL) query_putrdataset(client, &rdataset); if (sigrdataset != NULL) query_putrdataset(client, &sigrdataset);}static voidquery_addwildcardproof(ns_client_t *client, dns_db_t *db, dns_name_t *name, isc_boolean_t ispositive){ isc_buffer_t *dbuf, b; dns_name_t *fname; dns_rdataset_t *rdataset, *sigrdataset; dns_fixedname_t wfixed; dns_name_t *wname; dns_dbnode_t *node; unsigned int options; unsigned int olabels, nlabels; isc_result_t result; dns_rdata_t rdata = DNS_RDATA_INIT; dns_rdata_nsec_t nsec; isc_boolean_t have_wname; int order; CTRACE("query_addwildcardproof"); fname = NULL; rdataset = NULL; sigrdataset = NULL; node = NULL; /* * Get the NOQNAME proof then if !ispositve * get the NOWILDCARD proof. * * DNS_DBFIND_NOWILD finds the NSEC records that covers the * name ignoring any wildcard. From the owner and next names * of this record you can compute which wildcard (if it exists) * will match by finding the longest common suffix of the * owner name and next names with the qname and prefixing that * with the wildcard label. * * e.g. * Given: * example SOA * example NSEC b.example * b.example A * b.example NSEC a.d.example * a.d.example A * a.d.example NSEC g.f.example * g.f.example A * g.f.example NSEC z.i.example * z.i.example A * z.i.example NSEC example * * QNAME: * a.example -> example NSEC b.example * owner common example * next common example * wild *.example * d.b.example -> b.example NSEC a.d.example * owner common b.example * next common example * wild *.b.example * a.f.example -> a.d.example NSEC g.f.example * owner common example * next common f.example * wild *.f.example * j.example -> z.i.example NSEC example * owner common example * next common example * wild *.f.example */ options = client->query.dboptions | DNS_DBFIND_NOWILD; dns_fixedname_init(&wfixed); wname = dns_fixedname_name(&wfixed); again: have_wname = ISC_FALSE; /* * We'll need some resources... */ dbuf = query_getnamebuf(client); if (dbuf == NULL) goto cleanup; fname = query_newname(client, dbuf, &b); rdataset = query_newrdataset(client); sigrdataset = query_newrdataset(client); if (fname == NULL || rdataset == NULL || sigrdataset == NULL) goto cleanup; result = dns_db_find(db, name, NULL, dns_rdatatype_nsec, options, 0, &node, fname, rdataset, sigrdataset); if (node != NULL) dns_db_detachnode(db, &node); if (result == DNS_R_NXDOMAIN) { if (!ispositive) result = dns_rdataset_first(rdataset); if (result == ISC_R_SUCCESS) { dns_rdataset_current(rdataset, &rdata); result = dns_rdata_tostruct(&rdata, &nsec, NULL); } if (result == ISC_R_SUCCESS) { (void)dns_name_fullcompare(name, fname, &order, &olabels); (void)dns_name_fullcompare(name, &nsec.next, &order, &nlabels); if (olabels > nlabels) dns_name_split(name, olabels, NULL, wname); else dns_name_split(name, nlabels, NULL, wname); result = dns_name_concatenate(dns_wildcardname, wname, wname, NULL); if (result == ISC_R_SUCCESS) have_wname = ISC_TRUE; dns_rdata_freestruct(&nsec); } query_addrrset(client, &fname, &rdataset, &sigrdataset, dbuf, DNS_SECTION_AUTHORITY); } if (rdataset != NULL) query_putrdataset(client, &rdataset); if (sigrdataset != NULL) query_putrdataset(client, &sigrdataset); if (fname != NULL) query_releasename(client, &fname); if (have_wname) { ispositive = ISC_TRUE; /* prevent loop */ if (!dns_name_equal(name, wname)) { name = wname; goto again; } } cleanup: if (rdataset != NULL) query_putrdataset(client, &rdataset); if (sigrdataset != NULL) query_putrdataset(client, &sigrdataset); if (fname != NULL) query_releasename(client, &fname);}static voidquery_addnxrrsetnsec(ns_client_t *client, dns_db_t *db, dns_name_t **namep, dns_rdataset_t **rdatasetp, dns_rdataset_t **sigrdatasetp){ dns_name_t *name; dns_rdataset_t *sigrdataset; dns_rdata_t sigrdata; dns_rdata_rrsig_t sig;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -