#define MAXNAME (DNS_NAME_MAXTEXT + 1)
+/*
+ * Default maximum number of chained queries before we give up
+ * to prevent CNAME loops.
+ */
+#define MAX_RESTARTS 11
+
/* Variables used internally by delv. */
char *progname = NULL;
static isc_mem_t *mctx = NULL;
/* Create client */
CHECK(dns_client_create(mctx, loopmgr, netmgr, 0, tlsctx_client_cache,
&client, srcaddr4, srcaddr6));
+ dns_client_setmaxrestarts(client, MAX_RESTARTS);
/* Set the nameserver */
if (server != NULL) {
dns_view_setcache(view, cache, false);
dns_cache_detach(&cache);
dns_view_setdstport(view, destport);
+ dns_view_setmaxrestarts(view, MAX_RESTARTS);
CHECK(dns_rootns_create(mctx, dns_rdataclass_in, hintfile, &roothints));
dns_view_sethints(view, roothints);
#define UCTX_MAGIC ISC_MAGIC('U', 'c', 't', 'x')
#define UCTX_VALID(c) ISC_MAGIC_VALID(c, UCTX_MAGIC)
-#define MAX_RESTARTS 11
-
#define CHECK(r) \
do { \
result = (r); \
unsigned int find_timeout;
unsigned int find_udpretries;
+ uint8_t max_restarts;
isc_refcount_t references;
#define DEF_FIND_TIMEOUT 5
#define DEF_FIND_UDPRETRIES 3
+#define DEF_MAX_RESTARTS 11
/*%
* Internal state for a single name resolution procedure
*client = (dns_client_t){
.loop = isc_loop_get(loopmgr, 0),
.nm = nm,
+ .max_restarts = DEF_MAX_RESTARTS,
};
result = dns_dispatchmgr_create(mctx, loopmgr, nm,
return (result);
}
+void
+dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts) {
+ REQUIRE(DNS_CLIENT_VALID(client));
+ REQUIRE(max_restarts > 0);
+
+ client->max_restarts = max_restarts;
+}
+
static isc_result_t
getrdataset(isc_mem_t *mctx, dns_rdataset_t **rdatasetp) {
dns_rdataset_t *rdataset;
/*
* Limit the number of restarts.
*/
- if (want_restart && rctx->restarts == MAX_RESTARTS) {
+ if (want_restart &&
+ rctx->restarts == rctx->client->max_restarts)
+ {
want_restart = false;
result = ISC_R_QUOTA;
send_event = true;
*\li Anything else Failure.
*/
+void
+dns_client_setmaxrestarts(dns_client_t *client, uint8_t max_restarts);
+/*%<
+ * Set the number of permissible chained queries before we give up,
+ * to prevent CNAME loops. This defaults to 11.
+ *
+ * Requires:
+ *
+ *\li 'client' is a valid client.
+
+ *\li 'max_restarts' is greater than 0.
+ */
+
typedef void (*dns_client_resolve_cb)(dns_client_t *client,
const dns_name_t *name,
dns_namelist_t *namelist,
unsigned int udpsize;
uint32_t maxrrperset;
uint32_t maxtypepername;
+ uint8_t max_restarts;
/*
* Configurable data for server use only,
*\li 'adbp' is non-NULL and '*adbp' is NULL.
*/
+void
+dns_view_setmaxrestarts(dns_view_t *view, uint8_t max_restarts);
+/*%<
+ * Set the number of permissible chained queries before we give up,
+ * to prevent CNAME loops. This defaults to 11.
+ *
+ * Requires:
+ *
+ *\li 'view' is valid;
+ *\li 'max_restarts' is greater than 0.
+ */
+
ISC_LANG_ENDDECLS
#define DNS_VIEW_DELONLYHASH 111
+/*%
+ * Default maximum number of chained queries before we give up
+ * to prevent CNAME loops.
+ */
+#define DEFAULT_MAX_RESTARTS 11
+
/*%
* Default EDNS0 buffer size
*/
.trust_anchor_telemetry = true,
.root_key_sentinel = true,
.udpsize = DEFAULT_EDNS_BUFSIZE,
+ .max_restarts = DEFAULT_MAX_RESTARTS,
};
isc_refcount_init(&view->references, 1);
}
rcu_read_unlock();
}
+
+void
+dns_view_setmaxrestarts(dns_view_t *view, uint8_t max_restarts) {
+ REQUIRE(DNS_VIEW_VALID(view));
+ REQUIRE(max_restarts > 0);
+
+ view->max_restarts = max_restarts;
+}
uint16_t transfer_tcp_message_size;
bool interface_auto;
dns_tkeyctx_t *tkeyctx;
+ uint8_t max_restarts;
/*% Server id for NSID */
char *server_id;
#define dns64_bis_return_excluded_addresses 1
#endif /* if 0 */
-/*%
- * Maximum number of chained queries before we give up
- * to prevent CNAME loops.
- */
-#define MAX_RESTARTS 11
-
#define QUERY_ERROR(qctx, r) \
do { \
(qctx)->result = r; \
/*
* In some cases, a record that has been added as additional
* data may *also* trigger the addition of additional data.
- * This cannot go more than MAX_RESTARTS levels deep.
+ * This cannot go more than 'max-restarts' levels deep.
*/
if (trdataset != NULL && dns_rdatatype_followadditional(type)) {
- if (client->additionaldepth++ < MAX_RESTARTS) {
+ if (client->additionaldepth++ < client->view->max_restarts) {
eresult = dns_rdataset_additionaldata(
trdataset, fname, query_additional_cb, qctx);
}
* Do we need to restart the query (e.g. for CNAME chaining)?
*/
if (qctx->want_restart) {
- if (qctx->client->query.restarts < MAX_RESTARTS) {
+ if (qctx->client->query.restarts <
+ qctx->client->view->max_restarts)
+ {
query_ctx_t *saved_qctx = NULL;
qctx->client->query.restarts++;
saved_qctx = isc_mem_get(qctx->client->manager->mctx,
void
ns_server_create(isc_mem_t *mctx, ns_matchview_t matchingview,
ns_server_t **sctxp) {
- ns_server_t *sctx;
+ ns_server_t *sctx = NULL;
REQUIRE(sctxp != NULL && *sctxp == NULL);