]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
emit more helpful log for exceeding max-records-per-type
authorJINMEI Tatuya <jtatuya@infoblox.com>
Thu, 29 Aug 2024 07:24:48 +0000 (16:24 +0900)
committerMark Andrews <marka@isc.org>
Tue, 26 Nov 2024 04:06:58 +0000 (04:06 +0000)
The new log message is emitted when adding or updating an RRset
fails due to exceeding the max-records-per-type limit. The log includes
the owner name and type, corresponding zone name, and the limit value.
It will be emitted on loading a zone file, inbound zone transfer
(both AXFR and IXFR), handling a DDNS update, or updating a cache DB.
It's especially helpful in the case of zone transfer, since the
secondary side doesn't have direct access to the offending zone data.

It could also be used for max-types-per-name, but this change
doesn't implement it yet as it's much less likely to happen
in practice.

lib/dns/db.c
lib/dns/db_p.h
lib/dns/qpcache.c
lib/dns/qpzone.c

index 834d5ab669761b8f60a2251cdb32060a48f0b10a..366367d12b3eab25b71054cd189e475b42e10645 100644 (file)
@@ -36,6 +36,8 @@
 #include <dns/clientinfo.h>
 #include <dns/db.h>
 #include <dns/master.h>
+#include <dns/rdata.h>
+#include <dns/rdataclass.h>
 #include <dns/rdataset.h>
 #include <dns/rdatasetiter.h>
 
@@ -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);
+}
index 06c00c7e5a85f88a9e3233a6b83cbbf69e0cf9fe..2e319bbc00fa4892d7f14ce85027f87c4fa96709 100644 (file)
@@ -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
index 3d890c3133be874eebbc4562af4ca034f0e755ed..e2235d4a3bdee01d71f301bb254fda937464683e 100644 (file)
@@ -3412,6 +3412,11 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
                                            &region, 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;
        }
 
index 9ee1fe3e01d31fe1523c17b8b23f1bbbcb54c1ff..5d59f3fdc3090eb610da3c0575ad17dd0daa6973 100644 (file)
@@ -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,
                                            &region, 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,
                                            &region, 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;
        }