result = ISC_R_SUCCESS;
} else if (command_compare(command, NAMED_COMMAND_DUMPSTATS)) {
result = named_server_dumpstats(named_g_server);
+ } else if (command_compare(command, NAMED_COMMAND_FETCHLIMIT)) {
+ result = named_server_fetchlimit(named_g_server, lex, text);
} else if (command_compare(command, NAMED_COMMAND_FLUSH)) {
result = named_server_flushcache(named_g_server, lex);
} else if (command_compare(command, NAMED_COMMAND_FLUSHNAME)) {
#define NAMED_COMMAND_DNSTAP "dnstap"
#define NAMED_COMMAND_TCPTIMEOUTS "tcp-timeouts"
#define NAMED_COMMAND_SERVESTALE "serve-stale"
+#define NAMED_COMMAND_FETCHLIMIT "fetchlimit"
isc_result_t
named_controls_create(named_server_t *server, named_controls_t **ctrlsp);
isc_result_t
named_server_servestale(named_server_t *server, isc_lex_t *lex,
isc_buffer_t **text);
+
+/*%
+ * Report fetch-limited ADB server addresses.
+ */
+isc_result_t
+named_server_fetchlimit(named_server_t *server, isc_lex_t *lex,
+ isc_buffer_t **text);
return (result);
}
+
+isc_result_t
+named_server_fetchlimit(named_server_t *server, isc_lex_t *lex,
+ isc_buffer_t **text) {
+ isc_result_t result = ISC_R_SUCCESS;
+ dns_view_t *view = NULL;
+ char *ptr = NULL, *viewname = NULL;
+ bool first = true;
+
+ REQUIRE(text != NULL);
+
+ /* Skip the command name. */
+ ptr = next_token(lex, text);
+ if (ptr == NULL) {
+ return (ISC_R_UNEXPECTEDEND);
+ }
+
+ /* Look for the view name. */
+ viewname = next_token(lex, text);
+ for (view = ISC_LIST_HEAD(server->viewlist); view != NULL;
+ view = ISC_LIST_NEXT(view, link))
+ {
+ char tbuf[BUFSIZ];
+ unsigned int used;
+ uint32_t val;
+ int s;
+
+ if (view->rdclass != dns_rdataclass_in) {
+ continue;
+ }
+
+ if (viewname != NULL && strcasecmp(view->name, viewname) != 0) {
+ continue;
+ }
+
+ if (view->adb == NULL) {
+ continue;
+ }
+
+ if (!first) {
+ putstr(text, "\n");
+ }
+ putstr(text, "Rate limited servers, view ");
+ putstr(text, view->name);
+
+ dns_adb_getquota(view->adb, &val, NULL, NULL, NULL, NULL);
+ s = snprintf(tbuf, sizeof(tbuf),
+ " (fetches-per-server %u):", val);
+ if (s < 0 || (unsigned)s > sizeof(tbuf)) {
+ return (ISC_R_NOSPACE);
+ }
+ first = false;
+ putstr(text, tbuf);
+ used = isc_buffer_usedlength(*text);
+ CHECK(dns_adb_dumpquota(view->adb, text));
+ if (used == isc_buffer_usedlength(*text)) {
+ putstr(text, "\n None.");
+ }
+ }
+
+cleanup:
+ if (isc_buffer_usedlength(*text) > 0) {
+ (void)putnull(text);
+ }
+
+ return (result);
+}
(See the ``dump-file`` option in the BIND 9 Administrator Reference
Manual.)
+.. option:: fetchlimit [view]
+
+ This command dumps a list of servers which are currently being
+ rate-limited as a result of ``fetches-per-server`` settings.
+
.. option:: flush
This command flushes the server's cache.
status=$((status+ret))
echo_i "dumping ADB data"
-$RNDCCMD dumpdb -adb
-info=`grep '10.53.0.4' ns3/named_dump.db | sed 's/.*\(atr [.0-9]*\).*\(quota [0-9]*\).*/\1 \2/'`
+info=$($RNDCCMD fetchlimit | grep 10.53.0.4 | sed 's/.*quota .*(\([0-9]*\).*atr \([.0-9]*\).*/\2 \1/')
echo_i $info
set -- $info
-quota=$5
-[ ${5:-200} -lt 200 ] || ret=1
+quota=$2
+[ ${quota:-200} -lt 200 ] || ret=1
echo_i "checking servfail statistics"
ret=0
done
echo_i "dumping ADB data"
-$RNDCCMD dumpdb -adb
-info=`grep '10.53.0.4' ns3/named_dump.db | sed 's/.*\(atr [.0-9]*\).*\(quota [0-9]*\).*/\1 \2/'`
+info=$($RNDCCMD fetchlimit | grep 10.53.0.4 | sed 's/.*quota .*(\([0-9]*\).*atr \([.0-9]*\).*/\2 \1/')
echo_i $info
set -- $info
-[ ${5:-${quota}} -lt $quota ] || ret=1
-quota=$5
+[ ${2:-${quota}} -lt $quota ] || ret=1
+quota=$2
for try in 1 2 3 4 5 6 7 8 9 10; do
burst c $try
done
echo_i "dumping ADB data"
-$RNDCCMD dumpdb -adb
-info=`grep '10.53.0.4' ns3/named_dump.db | sed 's/.*\(atr [.0-9]*\).*\(quota [0-9]*\).*/\1 \2/'`
+info=$($RNDCCMD fetchlimit | grep 10.53.0.4 | sed 's/.*quota .*(\([0-9]*\).*atr \([.0-9]*\).*/\2 \1/')
echo_i $info
set -- $info
-[ ${5:-${quota}} -gt $quota ] || ret=1
-quota=$5
+[ ${2:-${quota}} -gt $quota ] || ret=1
+quota=$2
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status+ret))
.UNINDENT
.INDENT 0.0
.TP
+.B fetchlimit [view]
+This command dumps a list of servers which are currently being
+rate\-limited as a result of \fBfetches\-per\-server\fP settings.
+.UNINDENT
+.INDENT 0.0
+.TP
.B flush
This command flushes the server\(aqs cache.
.UNINDENT
}
}
+static isc_result_t
+putstr(isc_buffer_t **b, const char *str) {
+ isc_result_t result;
+
+ result = isc_buffer_reserve(b, strlen(str));
+ if (result != ISC_R_SUCCESS) {
+ return (result);
+ }
+
+ isc_buffer_putstr(*b, str);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf) {
+ isc_result_t result;
+ isc_ht_iter_t *it = NULL;
+
+ REQUIRE(DNS_ADB_VALID(adb));
+
+ RWLOCK(&adb->entries_lock, isc_rwlocktype_read);
+ isc_ht_iter_create(adb->entrybuckets, &it);
+ for (result = isc_ht_iter_first(it); result == ISC_R_SUCCESS;
+ result = isc_ht_iter_next(it))
+ {
+ dns_adbentrybucket_t *ebucket = NULL;
+ dns_adbentry_t *entry = NULL;
+
+ isc_ht_iter_current(it, (void **)&ebucket);
+ LOCK(&ebucket->lock);
+ for (entry = ISC_LIST_HEAD(ebucket->entries); entry != NULL;
+ entry = ISC_LIST_NEXT(entry, plink))
+ {
+ char addrbuf[ISC_NETADDR_FORMATSIZE];
+ char text[BUFSIZ];
+ isc_netaddr_t netaddr;
+
+ if (entry->atr == 0.0 && entry->quota == adb->quota) {
+ continue;
+ }
+
+ isc_netaddr_fromsockaddr(&netaddr, &entry->sockaddr);
+ isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
+
+ snprintf(text, sizeof(text),
+ "\n- quota %s (%" PRIuFAST32 "/%d) atr %0.2f",
+ addrbuf, atomic_load_relaxed(&entry->quota),
+ adb->quota, entry->atr);
+ putstr(buf, text);
+ }
+ UNLOCK(&ebucket->lock);
+ }
+ RWUNLOCK(&adb->entries_lock, isc_rwlocktype_read);
+ isc_ht_iter_destroy(&it);
+
+ if (result == ISC_R_NOMORE) {
+ result = ISC_R_SUCCESS;
+ }
+ return (result);
+}
+
static isc_result_t
dbfind_name(dns_adbname_t *adbname, isc_stdtime_t now, dns_rdatatype_t rdtype) {
isc_result_t result;
adb->atr_discount = discount;
}
+void
+dns_adb_getquota(dns_adb_t *adb, uint32_t *quotap, uint32_t *freqp,
+ double *lowp, double *highp, double *discountp) {
+ REQUIRE(DNS_ADB_VALID(adb));
+
+ if (quotap != NULL) {
+ *quotap = adb->quota;
+ }
+
+ if (freqp != NULL) {
+ *freqp = adb->atr_freq;
+ }
+
+ if (lowp != NULL) {
+ *lowp = adb->atr_low;
+ }
+
+ if (highp != NULL) {
+ *highp = adb->atr_high;
+ }
+
+ if (discountp != NULL) {
+ *discountp = adb->atr_discount;
+ }
+}
+
bool
dns_adbentry_overquota(dns_adbentry_t *entry) {
uint_fast32_t quota, active;
*\li 'adb' is valid.
*/
+void
+dns_adb_getquota(dns_adb_t *adb, uint32_t *quotap, uint32_t *freqp,
+ double *lowp, double *highp, double *discountp);
+/*%<
+ * Get the quota values set by dns_adb_setquota().
+ * If any of the 'quotap', 'freqp', 'lowp', 'highp', and
+ * 'discountp' parameters are non-NULL, then the memory they
+ * point to will be updated to hold the corresponding quota
+ * or parameter value.
+ *
+ * Requires:
+ *\li 'adb' is valid.
+ */
+
bool
dns_adbentry_overquota(dns_adbentry_t *entry);
/*%<
* Requires:
* \li 'adb' is valid.
*/
+
+isc_result_t
+dns_adb_dumpquota(dns_adb_t *adb, isc_buffer_t **buf);
+/*%
+ * Dump the addresses, current quota values, and current ATR values
+ * for all servers that are currently being fetchlimited. Servers
+ * for which the quota is still equal to the default and the ATR
+ * is zero are not printed.
+ *
+ * Requires:
+ * \li 'adb' is valid.
+ */
ISC_LANG_ENDDECLS