isc_result_t (*addglue)(dns_rdataset_t *rdataset,
dns_dbversion_t *version, dns_message_t *msg);
dns_slabheader_t *(*getheader)(const dns_rdataset_t *rdataset);
+ bool (*equals)(const dns_rdataset_t *rdataset1,
+ const dns_rdataset_t *rdataset2);
};
#define DNS_RDATASET_MAGIC ISC_MAGIC('D', 'N', 'S', 'R')
* Requires:
* \li 'rdataset' is a valid rdataset.
*/
+
+bool
+dns_rdataset_equals(const dns_rdataset_t *rdataset1,
+ const dns_rdataset_t *rdataset2);
+/*%<
+ * Returns true if the rdata in the rdataset is equal.
+ *
+ * Requires:
+ * \li 'rdataset1' is a valid rdataset.
+ * \li 'rdataset2' is a valid rdataset.
+ */
return NULL;
}
+
+bool
+dns_rdataset_equals(const dns_rdataset_t *rdataset1,
+ const dns_rdataset_t *rdataset2) {
+ REQUIRE(DNS_RDATASET_VALID(rdataset1));
+ REQUIRE(DNS_RDATASET_VALID(rdataset2));
+
+ if (rdataset1->methods->equals != NULL &&
+ rdataset1->methods->equals == rdataset2->methods->equals)
+ {
+ return (rdataset1->methods->equals)(rdataset1, rdataset2);
+ }
+
+ return false;
+}
rdataset_getownercase(const dns_rdataset_t *rdataset, dns_name_t *name);
static dns_slabheader_t *
rdataset_getheader(const dns_rdataset_t *rdataset);
+static bool
+rdataset_equals(const dns_rdataset_t *rdataset1,
+ const dns_rdataset_t *rdataset2);
/*% Note: the "const void *" are just to make qsort happy. */
static int
.setownercase = rdataset_setownercase,
.getownercase = rdataset_getownercase,
.getheader = rdataset_getheader,
+ .equals = rdataset_equals,
};
/* Fixed RRSet helper macros */
dns_slabheader_t *header = (dns_slabheader_t *)rdataset->slab.raw;
return header - 1;
}
+
+static bool
+rdataset_equals(const dns_rdataset_t *rdataset1,
+ const dns_rdataset_t *rdataset2) {
+ if (rdataset1->rdclass != rdataset2->rdclass ||
+ rdataset1->type != rdataset2->type)
+ {
+ return false;
+ }
+
+ dns_slabheader_t *header1 = (dns_slabheader_t *)rdataset1->slab.raw - 1;
+ dns_slabheader_t *header2 = (dns_slabheader_t *)rdataset2->slab.raw - 1;
+
+ return dns_rdataslab_equalx(header1, header2, rdataset1->rdclass,
+ rdataset2->type);
+}
if (result == DNS_R_UNCHANGED) {
result = ISC_R_SUCCESS;
if (!need_validation &&
- ardataset != NULL &&
- NEGATIVE(ardataset))
+ ardataset != NULL)
{
/*
* The answer in the
* cache is better than
- * the answer we found,
- * and is a negative
- * cache entry, so we
+ * the answer we found.
+ * If it's a negative
+ * cache entry, we
* must set eresult
* appropriately.
*/
if (NXDOMAIN(ardataset)) {
eresult =
DNS_R_NCACHENXDOMAIN;
- } else {
+ } else if (NEGATIVE(ardataset))
+ {
eresult =
DNS_R_NCACHENXRRSET;
}
+
/*
- * We have a negative
- * response from the
- * cache so don't
- * attempt to add the
- * RRSIG rrset.
+ * The cache wasn't updated
+ * because something was
+ * already there. If the
+ * data was the same as what
+ * we were trying to add,
+ * then sigrdataset might
+ * still be useful. If
+ * not, move on.
*/
- continue;
+ if (sigrdataset != NULL &&
+ !dns_rdataset_equals(
+ rdataset,
+ addedrdataset))
+ {
+ continue;
+ }
}
}
if (result != ISC_R_SUCCESS) {