ixfr-from-differences false;\n\
max-journal-size default;\n\
max-records 0;\n\
+ max-records-per-type 100;\n\
max-refresh-time 2419200; /* 4 weeks */\n\
max-retry-time 1209600; /* 2 weeks */\n\
max-transfer-idle-in 60;\n\
dns_resolver_setclientsperquery(view->resolver, cfg_obj_asuint32(obj),
max_clients_per_query);
+ /*
+ * This is used for the cache and also as a default value
+ * for zone databases.
+ */
+ obj = NULL;
+ result = named_config_get(maps, "max-records-per-type", &obj);
+ INSIST(result == ISC_R_SUCCESS);
+ dns_view_setmaxrrperset(view, cfg_obj_asuint32(obj));
+
obj = NULL;
result = named_config_get(maps, "max-recursion-depth", &obj);
INSIST(result == ISC_R_SUCCESS);
dns_zone_setmaxrecords(zone, 0);
}
+ obj = NULL;
+ result = named_config_get(maps, "max-records-per-type", &obj);
+ INSIST(result == ISC_R_SUCCESS && obj != NULL);
+ dns_zone_setmaxrrperset(mayberaw, cfg_obj_asuint32(obj));
+ if (zone != mayberaw) {
+ dns_zone_setmaxrrperset(zone, 0);
+ }
+
if (raw != NULL && filename != NULL) {
#define SIGNED ".signed"
size_t signedlen = strlen(filename) + sizeof(SIGNED);
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
- NULL /* adjusthashsize */
+ NULL, /* adjusthashsize */
+ NULL /* setmaxrrperset */
};
/* Auxiliary driver functions. */
This sets the maximum number of records permitted in a zone. The default is
zero, which means the maximum is unlimited.
+``max-records-per-type``
+ This sets the maximum number of resource records that can be stored
+ in an RRset in a database. When configured in ``options``
+ or ``view``, it controls the cache database; it also sets
+ the default value for zone databases, which can be overridden by setting
+ it at the ``zone`` level.
+
+ If set to a positive value, any attempt to cache or to add to a zone
+ an RRset with more than the specified number of records will result in
+ a failure. If set to 0, there is no cap on RRset size. The default is
+ 100.
+
``recursive-clients``
This sets the maximum number (a "hard quota") of simultaneous recursive lookups
the server performs on behalf of clients. The default is
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
notify ( explicit | master-only | primary-only | <boolean> );
notify-delay <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
- dnstap { ( all | auth | client | forwarder | resolver | update ) [
- ( query | response ) ]; ... };
- dnstap-identity ( <quoted_string> | none | hostname );
- dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited |
- <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
- increment | timestamp ) ];
- dnstap-version ( <quoted_string> | none );
+ dnstap { ( all | auth | client | forwarder |
+ resolver | update ) [ ( query | response ) ];
+ ... }; // not configured
+ dnstap-identity ( <quoted_string> | none |
+ hostname ); // not configured
+ dnstap-output ( file | unix ) <quoted_string> [
+ size ( unlimited | <size> ) ] [ versions (
+ unlimited | <integer> ) ] [ suffix ( increment
+ | timestamp ) ]; // not configured
+ dnstap-version ( <quoted_string> | none ); // not configured
dscp <integer>; // deprecated
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
forward ( first | only );
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
- fstrm-set-buffer-hint <integer>;
- fstrm-set-flush-timeout <integer>;
- fstrm-set-input-queue-size <integer>;
- fstrm-set-output-notify-threshold <integer>;
- fstrm-set-output-queue-model ( mpsc | spsc );
- fstrm-set-output-queue-size <integer>;
- fstrm-set-reopen-interval <duration>;
+ fstrm-set-buffer-hint <integer>; // not configured
+ fstrm-set-flush-timeout <integer>; // not configured
+ fstrm-set-input-queue-size <integer>; // not configured
+ fstrm-set-output-notify-threshold <integer>; // not configured
+ fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
+ fstrm-set-output-queue-size <integer>; // not configured
+ fstrm-set-reopen-interval <duration>; // not configured
geoip-directory ( <quoted_string> | none );
geoip-use-ecs <boolean>; // obsolete
glue-cache <boolean>;
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
+ max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
memstatistics <boolean>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
- dnstap { ( all | auth | client | forwarder | resolver | update ) [
- ( query | response ) ]; ... };
+ dnstap { ( all | auth | client | forwarder |
+ resolver | update ) [ ( query | response ) ];
+ ... }; // not configured
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
+ max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
message-compression <boolean>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
min-refresh-time <integer>;
min-retry-time <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
min-refresh-time <integer>;
min-retry-time <integer>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
- dnstap { ( all | auth | client | forwarder | resolver | update ) [
- ( query | response ) ]; ... };
- dnstap-identity ( <quoted_string> | none | hostname );
- dnstap-output ( file | unix ) <quoted_string> [ size ( unlimited |
- <size> ) ] [ versions ( unlimited | <integer> ) ] [ suffix (
- increment | timestamp ) ];
- dnstap-version ( <quoted_string> | none );
+ dnstap { ( all | auth | client | forwarder |
+ resolver | update ) [ ( query | response ) ];
+ ... }; // not configured
+ dnstap-identity ( <quoted_string> | none |
+ hostname ); // not configured
+ dnstap-output ( file | unix ) <quoted_string> [
+ size ( unlimited | <size> ) ] [ versions (
+ unlimited | <integer> ) ] [ suffix ( increment
+ | timestamp ) ]; // not configured
+ dnstap-version ( <quoted_string> | none ); // not configured
dscp <integer>; // deprecated
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
forward ( first | only );
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address>
| <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
- fstrm-set-buffer-hint <integer>;
- fstrm-set-flush-timeout <integer>;
- fstrm-set-input-queue-size <integer>;
- fstrm-set-output-notify-threshold <integer>;
- fstrm-set-output-queue-model ( mpsc | spsc );
- fstrm-set-output-queue-size <integer>;
- fstrm-set-reopen-interval <duration>;
+ fstrm-set-buffer-hint <integer>; // not configured
+ fstrm-set-flush-timeout <integer>; // not configured
+ fstrm-set-input-queue-size <integer>; // not configured
+ fstrm-set-output-notify-threshold <integer>; // not configured
+ fstrm-set-output-queue-model ( mpsc | spsc ); // not configured
+ fstrm-set-output-queue-size <integer>; // not configured
+ fstrm-set-reopen-interval <duration>; // not configured
geoip-directory ( <quoted_string> | none );
glue-cache <boolean>;
heartbeat-interval <integer>;
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
+ max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
memstatistics <boolean>;
dnssec-secure-to-insecure <boolean>;
dnssec-update-mode ( maintain | no-resign );
dnssec-validation ( yes | no | auto );
- dnstap { ( all | auth | client | forwarder | resolver | update ) [
- ( query | response ) ]; ... };
+ dnstap { ( all | auth | client | forwarder |
+ resolver | update ) [ ( query | response ) ];
+ ... }; // not configured
dual-stack-servers [ port <integer> ] { ( <quoted_string> [ port
<integer> ] [ dscp <integer> ] | <ipv4_address> [ port
<integer> ] [ dscp <integer> ] | <ipv6_address> [ port
max-journal-size ( default | unlimited | <sizeval> );
max-ncache-ttl <duration>;
max-records <integer>;
+ max-records-per-type <integer>;
max-recursion-depth <integer>;
max-recursion-queries <integer>;
max-refresh-time <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-udp-size <integer>;
max-zone-ttl ( unlimited | <duration> );
message-compression <boolean>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
min-refresh-time <integer>;
min-retry-time <integer>;
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
min-refresh-time <integer>;
min-retry-time <integer>;
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
max-records <integer>;
+ max-records-per-type <integer>;
+ max-types-per-name <integer>;
max-zone-ttl ( unlimited | <duration> );
primaries [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
zone-statistics ( full | terse | none | <boolean> );
max-ixfr-ratio ( unlimited | <percentage> );
max-journal-size ( default | unlimited | <sizeval> );
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-idle-out <integer>;
max-transfer-time-in <integer>;
max-transfer-time-out <integer>;
+ max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
forward ( first | only );
forwarders [ port <integer> ] [ dscp <integer> ] { ( <ipv4_address> | <ipv6_address> ) [ port <integer> ] [ dscp <integer> ]; ... };
max-records <integer>;
+ max-records-per-type <integer>;
+ max-types-per-name <integer>;
server-addresses { ( <ipv4_address> | <ipv6_address> ); ... };
server-names { <string>; ... };
zone-statistics ( full | terse | none | <boolean> );
masterfile-style ( full | relative );
masters [ port <integer> ] [ dscp <integer> ] { ( <remote-servers> | <ipv4_address> [ port <integer> ] | <ipv6_address> [ port <integer> ] ) [ key <string> ]; ... };
max-records <integer>;
+ max-records-per-type <integer>;
max-refresh-time <integer>;
max-retry-time <integer>;
max-transfer-idle-in <integer>;
max-transfer-time-in <integer>;
+ max-types-per-name <integer>;
min-refresh-time <integer>;
min-retry-time <integer>;
multi-master <boolean>;
/* Locked by 'filelock'. */
char *filename;
/* Access to the on-disk cache file is also locked by 'filelock'. */
+
+ uint32_t maxrrperset;
};
/***
}
dns_db_setservestalettl(*db, cache->serve_stale_ttl);
+ dns_db_setmaxrrperset(*db, cache->maxrrperset);
if (cache->taskmgr == NULL) {
return (ISC_R_SUCCESS);
}
}
+void
+dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value) {
+ REQUIRE(VALID_CACHE(cache));
+
+ cache->maxrrperset = value;
+ if (cache->db != NULL) {
+ dns_db_setmaxrrperset(cache->db, value);
+ }
+}
+
/*
* XXX: Much of the following code has been copied in from statschannel.c.
* We should refactor this into a generic function in stats.c that can be
return (ISC_R_NOTIMPLEMENTED);
}
+
+void
+dns_db_setmaxrrperset(dns_db_t *db, uint32_t value) {
+ REQUIRE(DNS_DB_VALID(db));
+
+ if (db->methods->setmaxrrperset != NULL) {
+ (db->methods->setmaxrrperset)(db, value);
+ }
+}
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
- NULL /* adjusthashsize */
+ NULL, /* adjusthashsize */
+ NULL /* setmaxrrperset */
};
static dns_rdatasetmethods_t rpsdb_rdataset_methods = {
}
result = dns_rdataslab_fromrdataset(rdataset, mctx, &r,
- sizeof(rdatasetheader_t));
+ sizeof(rdatasetheader_t), 0);
if (result != ISC_R_SUCCESS) {
goto unlock;
}
NULL, /* getsize */
NULL, /* setservestalettl */
NULL, /* getservestalettl */
- NULL /* setgluecachestats */
+ NULL, /* setservestalerefresh */
+ NULL, /* getservestalerefresh */
+ NULL, /* setgluecachestats */
+ NULL, /* adjusthashsize */
+ NULL /* setmaxrrperset */
};
static isc_result_t
* Update cache statistics based on result code in 'result'
*/
+void
+dns_cache_setmaxrrperset(dns_cache_t *cache, uint32_t value);
+/*%<
+ * Set the maximum resource records per RRSet that can be cached.
+ */
+
#ifdef HAVE_LIBXML2
int
dns_cache_renderxml(dns_cache_t *cache, void *writer0);
isc_result_t (*getservestalerefresh)(dns_db_t *db, uint32_t *interval);
isc_result_t (*setgluecachestats)(dns_db_t *db, isc_stats_t *stats);
isc_result_t (*adjusthashsize)(dns_db_t *db, size_t size);
+ void (*setmaxrrperset)(dns_db_t *db, uint32_t value);
} dns_dbmethods_t;
typedef isc_result_t (*dns_dbcreatefunc_t)(isc_mem_t *mctx,
* dns_rdatasetstats_create(); otherwise NULL.
*/
+void
+dns_db_setmaxrrperset(dns_db_t *db, uint32_t value);
+/*%<
+ * Set the maximum permissible number of RRs per RRset. If 'value'
+ * is nonzero, then any subsequent attempt to add an rdataset with
+ * more than 'value' RRs will return ISC_R_NOSPACE.
+ */
ISC_LANG_ENDDECLS
#endif /* DNS_DB_H */
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
- isc_region_t *region, unsigned int reservelen);
+ isc_region_t *region, unsigned int reservelen,
+ uint32_t limit);
/*%<
* Slabify a rdataset. The slab area will be allocated and returned
* in 'region'.
dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
unsigned int reservelen, isc_mem_t *mctx,
dns_rdataclass_t rdclass, dns_rdatatype_t type,
- unsigned int flags, unsigned char **tslabp);
+ unsigned int flags, uint32_t maxrrperset,
+ unsigned char **tslabp);
/*%<
* Merge 'oslab' and 'nslab'.
*/
dns_dlzdblist_t dlz_unsearched;
uint32_t fail_ttl;
dns_badcache_t *failcache;
+ uint32_t maxrrperset;
/*
* Configurable data for server use only,
*\li 'view' to be valid.
*/
+void
+dns_view_setmaxrrperset(dns_view_t *view, uint32_t value);
+/*%<
+ * Set the maximum resource records per RRSet that can be cached.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_VIEW_H */
*\li #ISC_R_UNEXPECTED
*/
+isc_result_t
+dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp);
+/*%<
+ * Creates a new empty database for the 'zone'.
+ *
+ * Requires:
+ *\li 'zone' to be a valid zone.
+ *\li 'dbp' to point to NULL pointer.
+ *
+ * Returns:
+ *\li dns_db_create() error codes.
+ */
+
void
dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass);
/*%<
*\li uint32_t maxrecords.
*/
+void
+dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t maxrrperset);
+/*%<
+ * Sets the maximum number of records per rrset permitted in a zone.
+ * 0 implies unlimited.
+ *
+ * Requires:
+ *\li 'zone' to be valid initialised zone.
+ *
+ * Returns:
+ *\li void
+ */
+
void
dns_zone_setmaxttl(dns_zone_t *zone, uint32_t maxttl);
/*%<
rbtdb_serial_t current_serial;
rbtdb_serial_t least_serial;
rbtdb_serial_t next_serial;
+ uint32_t maxrrperset;
rbtdb_version_t *current_version;
rbtdb_version_t *future_version;
rbtdb_versionlist_t open_versions;
rbtdb->common.mctx,
rbtdb->common.rdclass,
(dns_rdatatype_t)header->type, flags,
- &merged);
+ rbtdb->maxrrperset, &merged);
}
if (result == ISC_R_SUCCESS) {
/*
static isc_result_t
addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
- dns_rdataset_t *rdataset) {
+ uint32_t maxrrperset, dns_rdataset_t *rdataset) {
struct noqname *noqname;
isc_mem_t *mctx = rbtdb->common.mctx;
dns_name_t name;
noqname->negsig = NULL;
noqname->type = neg.type;
dns_name_dup(&name, mctx, &noqname->name);
- result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0);
+ result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0, maxrrperset);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
noqname->neg = r.base;
- result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0);
+ result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0, maxrrperset);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
static isc_result_t
addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
- dns_rdataset_t *rdataset) {
+ uint32_t maxrrperset, dns_rdataset_t *rdataset) {
struct noqname *closest;
isc_mem_t *mctx = rbtdb->common.mctx;
dns_name_t name;
closest->negsig = NULL;
closest->type = neg.type;
dns_name_dup(&name, mctx, &closest->name);
- result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0);
+ result = dns_rdataslab_fromrdataset(&neg, mctx, &r, 0, maxrrperset);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
closest->neg = r.base;
- result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0);
+ result = dns_rdataslab_fromrdataset(&negsig, mctx, &r, 0, maxrrperset);
if (result != ISC_R_SUCCESS) {
goto cleanup;
}
}
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- ®ion, sizeof(rdatasetheader_t));
+ ®ion, sizeof(rdatasetheader_t),
+ rbtdb->maxrrperset);
if (result != ISC_R_SUCCESS) {
return (result);
}
RDATASET_ATTR_SET(newheader, RDATASET_ATTR_OPTOUT);
}
if ((rdataset->attributes & DNS_RDATASETATTR_NOQNAME) != 0) {
- result = addnoqname(rbtdb, newheader, rdataset);
+ result = addnoqname(rbtdb, newheader,
+ rbtdb->maxrrperset, rdataset);
if (result != ISC_R_SUCCESS) {
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
}
}
if ((rdataset->attributes & DNS_RDATASETATTR_CLOSEST) != 0) {
- result = addclosest(rbtdb, newheader, rdataset);
+ result = addclosest(rbtdb, newheader,
+ rbtdb->maxrrperset, rdataset);
if (result != ISC_R_SUCCESS) {
free_rdataset(rbtdb, rbtdb->common.mctx,
newheader);
nodefullname(db, node, nodename);
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- ®ion, sizeof(rdatasetheader_t));
+ ®ion, sizeof(rdatasetheader_t),
+ 0);
if (result != ISC_R_SUCCESS) {
return (result);
}
}
result = dns_rdataslab_fromrdataset(rdataset, rbtdb->common.mctx,
- ®ion, sizeof(rdatasetheader_t));
+ ®ion, sizeof(rdatasetheader_t),
+ rbtdb->maxrrperset);
if (result != ISC_R_SUCCESS) {
return (result);
}
return (ISC_R_SUCCESS);
}
+static void
+setmaxrrperset(dns_db_t *db, uint32_t maxrrperset) {
+ dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
+
+ REQUIRE(VALID_RBTDB(rbtdb));
+
+ rbtdb->maxrrperset = maxrrperset;
+}
+
static dns_stats_t *
getrrsetstats(dns_db_t *db) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
setgluecachestats,
- adjusthashsize };
+ adjusthashsize,
+ setmaxrrperset };
static dns_dbmethods_t cache_methods = { attach,
detach,
setservestalerefresh,
getservestalerefresh,
NULL,
- adjusthashsize };
+ adjusthashsize,
+ setmaxrrperset };
isc_result_t
dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type,
isc_result_t
dns_rdataslab_fromrdataset(dns_rdataset_t *rdataset, isc_mem_t *mctx,
- isc_region_t *region, unsigned int reservelen) {
+ isc_region_t *region, unsigned int reservelen,
+ uint32_t maxrrperset) {
/*
* Use &removed as a sentinel pointer for duplicate
* rdata as rdata.data == NULL is valid.
return (ISC_R_SUCCESS);
}
- if (nitems > DNS_RDATASET_MAX_RECORDS) {
+ if (maxrrperset > 0 && nitems > maxrrperset) {
return (DNS_R_TOOMANYRECORDS);
}
dns_rdataslab_merge(unsigned char *oslab, unsigned char *nslab,
unsigned int reservelen, isc_mem_t *mctx,
dns_rdataclass_t rdclass, dns_rdatatype_t type,
- unsigned int flags, unsigned char **tslabp) {
+ unsigned int flags, uint32_t maxrrperset,
+ unsigned char **tslabp) {
unsigned char *ocurrent, *ostart, *ncurrent, *tstart, *tcurrent, *data;
unsigned int ocount, ncount, count, olength, tlength, tcount, length;
dns_rdata_t ordata = DNS_RDATA_INIT;
#endif /* if DNS_RDATASET_FIXED */
INSIST(ocount > 0 && ncount > 0);
- if (ocount + ncount > DNS_RDATASET_MAX_RECORDS) {
+ if (maxrrperset > 0 && ocount + ncount > maxrrperset) {
return (DNS_R_TOOMANYRECORDS);
}
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
- NULL /* adjusthashsize */
+ NULL, /* adjusthashsize */
+ NULL /* setmaxrrperset */
};
static isc_result_t
NULL, /* setservestalerefresh */
NULL, /* getservestalerefresh */
NULL, /* setgluecachestats */
- NULL /* adjusthashsize */
+ NULL, /* adjusthashsize */
+ NULL /* setmaxrrperset */
};
/*
dns_cache_attach(cache, &view->cache);
dns_cache_attachdb(cache, &view->cachedb);
INSIST(DNS_DB_VALID(view->cachedb));
+
+ dns_cache_setmaxrrperset(view->cache, view->maxrrperset);
}
bool
return (result);
}
+
+void
+dns_view_setmaxrrperset(dns_view_t *view, uint32_t value) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ view->maxrrperset = value;
+ if (view->cache != NULL) {
+ dns_cache_setmaxrrperset(view->cache, value);
+ }
+}
static isc_result_t
axfr_init(dns_xfrin_ctx_t *xfr);
static isc_result_t
-axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp);
-static isc_result_t
axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
dns_ttl_t ttl, dns_rdata_t *rdata);
static isc_result_t
dns_db_detach(&xfr->db);
}
- CHECK(axfr_makedb(xfr, &xfr->db));
+ CHECK(dns_zone_makedb(xfr->zone, &xfr->db));
+
+ dns_zone_rpz_enable_db(xfr->zone, xfr->db);
+ dns_zone_catz_enable_db(xfr->zone, xfr->db);
+
dns_rdatacallbacks_init(&xfr->axfr);
CHECK(dns_db_beginload(xfr->db, &xfr->axfr));
result = ISC_R_SUCCESS;
return (result);
}
-static isc_result_t
-axfr_makedb(dns_xfrin_ctx_t *xfr, dns_db_t **dbp) {
- isc_result_t result;
-
- result = dns_db_create(xfr->mctx, /* XXX */
- "rbt", /* XXX guess */
- &xfr->name, dns_dbtype_zone, xfr->rdclass, 0,
- NULL, /* XXX guess */
- dbp);
- if (result == ISC_R_SUCCESS) {
- dns_zone_rpz_enable_db(xfr->zone, *dbp);
- dns_zone_catz_enable_db(xfr->zone, *dbp);
- }
- return (result);
-}
-
static isc_result_t
axfr_putdata(dns_xfrin_ctx_t *xfr, dns_diffop_t op, dns_name_t *name,
dns_ttl_t ttl, dns_rdata_t *rdata) {
uint32_t minretry;
uint32_t maxrecords;
+ uint32_t maxrrperset;
isc_sockaddr_t *masters;
isc_dscp_t *masterdscps;
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
"starting load");
- result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
- (zone->type == dns_zone_stub) ? dns_dbtype_stub
- : dns_dbtype_zone,
- zone->rdclass, zone->db_argc - 1,
- zone->db_argv + 1, &db);
-
+ result = dns_zone_makedb(zone, &db);
if (result != ISC_R_SUCCESS) {
dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
"loading zone: creating database: %s",
isc_result_totext(result));
goto cleanup;
}
- dns_db_settask(db, zone->task, zone->task);
-
- if (zone->type == dns_zone_primary ||
- zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
- {
- result = dns_db_setgluecachestats(db, zone->gluecachestats);
- if (result == ISC_R_NOTIMPLEMENTED) {
- result = ISC_R_SUCCESS;
- }
- if (result != ISC_R_SUCCESS) {
- goto cleanup;
- }
- }
if (!dns_db_ispersistent(db)) {
if (zone->masterfile != NULL) {
zone->maxrecords = val;
}
+void
+dns_zone_setmaxrrperset(dns_zone_t *zone, uint32_t val) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+
+ zone->maxrrperset = val;
+ if (zone->db != NULL) {
+ dns_db_setmaxrrperset(zone->db, val);
+ }
+}
+
static bool
notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
isc_sockaddr_t *addr, dns_tsigkey_t *key) {
goto cleanup;
}
dns_db_settask(stub->db, zone->task, zone->task);
+ dns_db_setmaxrrperset(stub->db, zone->maxrrperset);
}
result = dns_db_newversion(stub->db, &stub->version);
}
zone_attachdb(zone, db);
dns_db_settask(zone->db, zone->task, zone->task);
+ dns_db_setmaxrrperset(zone->db, zone->maxrrperset);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
return (ISC_R_SUCCESS);
return (ISC_MIN(zone->minimum, zone->soattl));
}
+
+isc_result_t
+dns_zone_makedb(dns_zone_t *zone, dns_db_t **dbp) {
+ REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(dbp != NULL && *dbp == NULL);
+
+ dns_db_t *db = NULL;
+
+ isc_result_t result = dns_db_create(
+ zone->mctx, zone->db_argv[0], &zone->origin,
+ (zone->type == dns_zone_stub) ? dns_dbtype_stub
+ : dns_dbtype_zone,
+ zone->rdclass, zone->db_argc - 1, zone->db_argv + 1, &db);
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+
+ switch (zone->type) {
+ case dns_zone_primary:
+ case dns_zone_secondary:
+ case dns_zone_mirror:
+ result = dns_db_setgluecachestats(db, zone->gluecachestats);
+ if (result == ISC_R_NOTIMPLEMENTED) {
+ result = ISC_R_SUCCESS;
+ }
+ if (result != ISC_R_SUCCESS) {
+ dns_db_detach(&db);
+ return (result);
+ }
+ break;
+ default:
+ break;
+ }
+
+ dns_db_settask(db, zone->task, zone->task);
+ dns_db_setmaxrrperset(db, zone->maxrrperset);
+
+ *dbp = db;
+
+ return (ISC_R_SUCCESS);
+}
{ "max-records", &cfg_type_uint32,
CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
+ { "max-records-per-type", &cfg_type_uint32,
+ CFG_ZONE_PRIMARY | CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR |
+ CFG_ZONE_STUB | CFG_ZONE_STATICSTUB | CFG_ZONE_REDIRECT },
{ "max-refresh-time", &cfg_type_uint32,
CFG_ZONE_SECONDARY | CFG_ZONE_MIRROR | CFG_ZONE_STUB },
{ "max-retry-time", &cfg_type_uint32,