return (result);
}
+#define IS_REQUIRED_GLUE(r) (((r)->attributes & DNS_RDATASETATTR_REQUIRED) != 0)
+
static isc_result_t
rdataset_addglue(dns_rdataset_t *rdataset, dns_dbversion_t *version,
dns_message_t *msg) {
dns_rdataset_t *rdataset_aaaa = NULL;
dns_rdataset_t *sigrdataset_aaaa = NULL;
dns_name_t *gluename = dns_fixedname_name(&ge->fixedname);
+ bool prepend_name = false;
dns_message_gettempname(msg, &name);
if (rdataset_a != NULL) {
dns_rdataset_clone(&ge->rdataset_a, rdataset_a);
ISC_LIST_APPEND(name->list, rdataset_a, link);
+ if (IS_REQUIRED_GLUE(rdataset_a)) {
+ prepend_name = true;
+ }
}
if (sigrdataset_a != NULL) {
if (rdataset_aaaa != NULL) {
dns_rdataset_clone(&ge->rdataset_aaaa, rdataset_aaaa);
ISC_LIST_APPEND(name->list, rdataset_aaaa, link);
+ if (IS_REQUIRED_GLUE(rdataset_aaaa)) {
+ prepend_name = true;
+ }
}
if (sigrdataset_aaaa != NULL) {
dns_rdataset_clone(&ge->sigrdataset_aaaa,
}
dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
+
+ /*
+ * When looking for required glue, dns_message_rendersection()
+ * only processes the first rdataset associated with the first
+ * name added to the ADDITIONAL section. dns_message_addname()
+ * performs an append on the list of names in a given section,
+ * so if any glue record was marked as required, we need to
+ * move the name it is associated with to the beginning of the
+ * list for the ADDITIONAL section or else required glue might
+ * not be rendered.
+ */
+ if (prepend_name) {
+ ISC_LIST_UNLINK(msg->sections[DNS_SECTION_ADDITIONAL],
+ name, link);
+ ISC_LIST_PREPEND(msg->sections[DNS_SECTION_ADDITIONAL],
+ name, link);
+ }
}
no_glue: