diff --git a/lib/dns/db.c b/lib/dns/db.c index 834d5ab669..366367d12b 100644 --- a/lib/dns/db.c +++ b/lib/dns/db.c @@ -36,6 +36,8 @@ #include #include #include +#include +#include #include #include @@ -1179,3 +1181,25 @@ dns_db_setmaxtypepername(dns_db_t *db, uint32_t value) { (db->methods->setmaxtypepername)(db, value); } } + +void +dns__db_logtoomanyrecords(dns_db_t *db, const dns_name_t *name, + dns_rdatatype_t type, const char *op, + uint32_t limit) { + char namebuf[DNS_NAME_FORMATSIZE]; + char originbuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + char clsbuf[DNS_RDATACLASS_FORMATSIZE]; + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_name_format(&db->origin, originbuf, sizeof(originbuf)); + dns_rdatatype_format(type, typebuf, sizeof(typebuf)); + dns_rdataclass_format(db->rdclass, clsbuf, sizeof(clsbuf)); + + isc_log_write( + DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_RBTDB, ISC_LOG_ERROR, + "error %s '%s/%s' in '%s/%s' (%s): %s (must not exceed %u)", op, + namebuf, typebuf, originbuf, clsbuf, + (db->attributes & DNS_DBATTR_CACHE) != 0 ? "cache" : "zone", + isc_result_totext(DNS_R_TOOMANYRECORDS), limit); +} diff --git a/lib/dns/db_p.h b/lib/dns/db_p.h index 06c00c7e5a..2e319bbc00 100644 --- a/lib/dns/db_p.h +++ b/lib/dns/db_p.h @@ -186,4 +186,13 @@ prio_type(dns_typepair_t type) { return false; } +void +dns__db_logtoomanyrecords(dns_db_t *db, const dns_name_t *name, + dns_rdatatype_t type, const char *op, uint32_t limit); +/* + * Emit a log message when adding an rdataset of name/type would exceed the + * 'maxrrperset' limit. 'op' is 'adding' or 'updating' depending on whether + * the addition is to create a new rdataset or to merge to an existing one. + */ + ISC_LANG_ENDDECLS diff --git a/lib/dns/qpcache.c b/lib/dns/qpcache.c index 3d890c3133..e2235d4a3b 100644 --- a/lib/dns/qpcache.c +++ b/lib/dns/qpcache.c @@ -3412,6 +3412,11 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, ®ion, sizeof(dns_slabheader_t), qpdb->maxrrperset); if (result != ISC_R_SUCCESS) { + if (result == DNS_R_TOOMANYRECORDS) { + dns__db_logtoomanyrecords((dns_db_t *)qpdb, + &qpnode->name, rdataset->type, + "adding", qpdb->maxrrperset); + } return result; } diff --git a/lib/dns/qpzone.c b/lib/dns/qpzone.c index 9ee1fe3e01..5d59f3fdc3 100644 --- a/lib/dns/qpzone.c +++ b/lib/dns/qpzone.c @@ -1874,6 +1874,12 @@ add(qpzonedb_t *qpdb, qpznode_t *node, const dns_name_t *nodename, header->resign_lsb; } } else { + if (result == DNS_R_TOOMANYRECORDS) { + dns__db_logtoomanyrecords( + (dns_db_t *)qpdb, nodename, + (dns_rdatatype_t)header->type, + "updating", qpdb->maxrrperset); + } dns_slabheader_destroy(&newheader); return result; } @@ -2108,6 +2114,11 @@ loading_addrdataset(void *arg, const dns_name_t *name, ®ion, sizeof(dns_slabheader_t), qpdb->maxrrperset); if (result != ISC_R_SUCCESS) { + if (result == DNS_R_TOOMANYRECORDS) { + dns__db_logtoomanyrecords((dns_db_t *)qpdb, name, + rdataset->type, "adding", + qpdb->maxrrperset); + } return result; } @@ -4604,6 +4615,11 @@ addrdataset(dns_db_t *db, dns_dbnode_t *dbnode, dns_dbversion_t *dbversion, ®ion, sizeof(dns_slabheader_t), qpdb->maxrrperset); if (result != ISC_R_SUCCESS) { + if (result == DNS_R_TOOMANYRECORDS) { + dns__db_logtoomanyrecords((dns_db_t *)qpdb, &node->name, + rdataset->type, "adding", + qpdb->maxrrperset); + } return result; }