xref: /minix/external/bsd/bind/dist/lib/dns/rrl.c (revision fb9c64b2)
1 /*	$NetBSD: rrl.c,v 1.4 2014/12/10 04:37:58 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2012-2014  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
11  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
13  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16  * PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*! \file */
20 
21 /*
22  * Rate limit DNS responses.
23  */
24 
25 /* #define ISC_LIST_CHECKINIT */
26 
27 #include <config.h>
28 #include <isc/mem.h>
29 #include <isc/net.h>
30 #include <isc/netaddr.h>
31 #include <isc/print.h>
32 
33 #include <dns/result.h>
34 #include <dns/rcode.h>
35 #include <dns/rdatatype.h>
36 #include <dns/rdataclass.h>
37 #include <dns/log.h>
38 #include <dns/rrl.h>
39 #include <dns/view.h>
40 
41 static void
42 log_end(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_boolean_t early,
43 	char *log_buf, unsigned int log_buf_len);
44 
45 /*
46  * Get a modulus for a hash function that is tolerably likely to be
47  * relatively prime to most inputs.  Of course, we get a prime for for initial
48  * values not larger than the square of the last prime.  We often get a prime
49  * after that.
50  * This works well in practice for hash tables up to at least 100
51  * times the square of the last prime and better than a multiplicative hash.
52  */
53 static int
54 hash_divisor(unsigned int initial) {
55 	static isc_uint16_t primes[] = {
56 		  3,   5,   7,  11,  13,  17,  19,  23,  29,  31,  37,  41,
57 		 43,  47,  53,  59,  61,  67,  71,  73,  79,  83,  89,  97,
58 #if 0
59 		101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157,
60 		163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
61 		229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
62 		293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367,
63 		373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439,
64 		443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509,
65 		521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599,
66 		601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661,
67 		673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751,
68 		757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
69 		839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919,
70 		929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997,1009,
71 #endif
72 	};
73 	int divisions, tries;
74 	unsigned int result;
75 	isc_uint16_t *pp, p;
76 
77 	result = initial;
78 
79 	if (primes[sizeof(primes)/sizeof(primes[0])-1] >= result) {
80 		pp = primes;
81 		while (*pp < result)
82 			++pp;
83 		return (*pp);
84 	}
85 
86 	if ((result & 1) == 0)
87 		++result;
88 
89 	divisions = 0;
90 	tries = 1;
91 	pp = primes;
92 	do {
93 		p = *pp++;
94 		++divisions;
95 		if ((result % p) == 0) {
96 			++tries;
97 			result += 2;
98 			pp = primes;
99 		}
100 	} while (pp < &primes[sizeof(primes) / sizeof(primes[0])]);
101 
102 	if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3))
103 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
104 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3,
105 			      "%d hash_divisor() divisions in %d tries"
106 			      " to get %d from %d",
107 			      divisions, tries, result, initial);
108 
109 	return (result);
110 }
111 
112 /*
113  * Convert a timestamp to a number of seconds in the past.
114  */
115 static inline int
116 delta_rrl_time(isc_stdtime_t ts, isc_stdtime_t now) {
117 	int delta;
118 
119 	delta = now - ts;
120 	if (delta >= 0)
121 		return (delta);
122 
123 	/*
124 	 * The timestamp is in the future.  That future might result from
125 	 * re-ordered requests, because we use timestamps on requests
126 	 * instead of consulting a clock.  Timestamps in the distant future are
127 	 * assumed to result from clock changes.  When the clock changes to
128 	 * the past, make existing timestamps appear to be in the past.
129 	 */
130 	if (delta < -DNS_RRL_MAX_TIME_TRAVEL)
131 		return (DNS_RRL_FOREVER);
132 	return (0);
133 }
134 
135 static inline int
136 get_age(const dns_rrl_t *rrl, const dns_rrl_entry_t *e, isc_stdtime_t now) {
137 	if (!e->ts_valid)
138 		return (DNS_RRL_FOREVER);
139 	return (delta_rrl_time(e->ts + rrl->ts_bases[e->ts_gen], now));
140 }
141 
142 static inline void
143 set_age(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_stdtime_t now) {
144 	dns_rrl_entry_t *e_old;
145 	unsigned int ts_gen;
146 	int i, ts;
147 
148 	ts_gen = rrl->ts_gen;
149 	ts = now - rrl->ts_bases[ts_gen];
150 	if (ts < 0) {
151 		if (ts < -DNS_RRL_MAX_TIME_TRAVEL)
152 			ts = DNS_RRL_FOREVER;
153 		else
154 			ts = 0;
155 	}
156 
157 	/*
158 	 * Make a new timestamp base if the current base is too old.
159 	 * All entries older than DNS_RRL_MAX_WINDOW seconds are ancient,
160 	 * useless history.  Their timestamps can be treated as if they are
161 	 * all the same.
162 	 * We only do arithmetic on more recent timestamps, so bases for
163 	 * older timestamps can be recycled provided the old timestamps are
164 	 * marked as ancient history.
165 	 * This loop is almost always very short because most entries are
166 	 * recycled after one second and any entries that need to be marked
167 	 * are older than (DNS_RRL_TS_BASES)*DNS_RRL_MAX_TS seconds.
168 	 */
169 	if (ts >= DNS_RRL_MAX_TS) {
170 		ts_gen = (ts_gen + 1) % DNS_RRL_TS_BASES;
171 		for (e_old = ISC_LIST_TAIL(rrl->lru), i = 0;
172 		     e_old != NULL && (e_old->ts_gen == ts_gen ||
173 				       !ISC_LINK_LINKED(e_old, hlink));
174 		     e_old = ISC_LIST_PREV(e_old, lru), ++i)
175 		{
176 			e_old->ts_valid = ISC_FALSE;
177 		}
178 		if (i != 0)
179 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
180 				      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1,
181 				      "rrl new time base scanned %d entries"
182 				      " at %d for %d %d %d %d",
183 				      i, now, rrl->ts_bases[ts_gen],
184 				      rrl->ts_bases[(ts_gen + 1) %
185 					DNS_RRL_TS_BASES],
186 				      rrl->ts_bases[(ts_gen + 2) %
187 					DNS_RRL_TS_BASES],
188 				      rrl->ts_bases[(ts_gen + 3) %
189 					DNS_RRL_TS_BASES]);
190 		rrl->ts_gen = ts_gen;
191 		rrl->ts_bases[ts_gen] = now;
192 		ts = 0;
193 	}
194 
195 	e->ts_gen = ts_gen;
196 	e->ts = ts;
197 	e->ts_valid = ISC_TRUE;
198 }
199 
200 static isc_result_t
201 expand_entries(dns_rrl_t *rrl, int new) {
202 	unsigned int bsize;
203 	dns_rrl_block_t *b;
204 	dns_rrl_entry_t *e;
205 	double rate;
206 	int i;
207 
208 	if (rrl->num_entries + new >= rrl->max_entries &&
209 	    rrl->max_entries != 0)
210 	{
211 		new = rrl->max_entries - rrl->num_entries;
212 		if (new <= 0)
213 			return (ISC_R_SUCCESS);
214 	}
215 
216 	/*
217 	 * Log expansions so that the user can tune max-table-size
218 	 * and min-table-size.
219 	 */
220 	if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP) &&
221 	    rrl->hash != NULL) {
222 		rate = rrl->probes;
223 		if (rrl->searches != 0)
224 			rate /= rrl->searches;
225 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
226 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP,
227 			      "increase from %d to %d RRL entries with"
228 			      " %d bins; average search length %.1f",
229 			      rrl->num_entries, rrl->num_entries+new,
230 			      rrl->hash->length, rate);
231 	}
232 
233 	bsize = sizeof(dns_rrl_block_t) + (new-1)*sizeof(dns_rrl_entry_t);
234 	b = isc_mem_get(rrl->mctx, bsize);
235 	if (b == NULL) {
236 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
237 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL,
238 			      "isc_mem_get(%d) failed for RRL entries",
239 			      bsize);
240 		return (ISC_R_NOMEMORY);
241 	}
242 	memset(b, 0, bsize);
243 	b->size = bsize;
244 
245 	e = b->entries;
246 	for (i = 0; i < new; ++i, ++e) {
247 		ISC_LINK_INIT(e, hlink);
248 		ISC_LIST_INITANDAPPEND(rrl->lru, e, lru);
249 	}
250 	rrl->num_entries += new;
251 	ISC_LIST_INITANDAPPEND(rrl->blocks, b, link);
252 
253 	return (ISC_R_SUCCESS);
254 }
255 
256 static inline dns_rrl_bin_t *
257 get_bin(dns_rrl_hash_t *hash, unsigned int hval) {
258 	INSIST(hash != NULL);
259 	return (&hash->bins[hval % hash->length]);
260 }
261 
262 static void
263 free_old_hash(dns_rrl_t *rrl) {
264 	dns_rrl_hash_t *old_hash;
265 	dns_rrl_bin_t *old_bin;
266 	dns_rrl_entry_t *e, *e_next;
267 
268 	old_hash = rrl->old_hash;
269 	for (old_bin = &old_hash->bins[0];
270 	     old_bin < &old_hash->bins[old_hash->length];
271 	     ++old_bin)
272 	{
273 		for (e = ISC_LIST_HEAD(*old_bin); e != NULL; e = e_next) {
274 			e_next = ISC_LIST_NEXT(e, hlink);
275 			ISC_LINK_INIT(e, hlink);
276 		}
277 	}
278 
279 	isc_mem_put(rrl->mctx, old_hash,
280 		    sizeof(*old_hash)
281 		      + (old_hash->length - 1) * sizeof(old_hash->bins[0]));
282 	rrl->old_hash = NULL;
283 }
284 
285 static isc_result_t
286 expand_rrl_hash(dns_rrl_t *rrl, isc_stdtime_t now) {
287 	dns_rrl_hash_t *hash;
288 	int old_bins, new_bins, hsize;
289 	double rate;
290 
291 	if (rrl->old_hash != NULL)
292 		free_old_hash(rrl);
293 
294 	/*
295 	 * Most searches fail and so go to the end of the chain.
296 	 * Use a small hash table load factor.
297 	 */
298 	old_bins = (rrl->hash == NULL) ? 0 : rrl->hash->length;
299 	new_bins = old_bins/8 + old_bins;
300 	if (new_bins < rrl->num_entries)
301 		new_bins = rrl->num_entries;
302 	new_bins = hash_divisor(new_bins);
303 
304 	hsize = sizeof(dns_rrl_hash_t) + (new_bins-1)*sizeof(hash->bins[0]);
305 	hash = isc_mem_get(rrl->mctx, hsize);
306 	if (hash == NULL) {
307 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
308 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_FAIL,
309 			      "isc_mem_get(%d) failed for"
310 			      " RRL hash table",
311 			      hsize);
312 		return (ISC_R_NOMEMORY);
313 	}
314 	memset(hash, 0, hsize);
315 	hash->length = new_bins;
316 	rrl->hash_gen ^= 1;
317 	hash->gen = rrl->hash_gen;
318 
319 	if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP) && old_bins != 0) {
320 		rate = rrl->probes;
321 		if (rrl->searches != 0)
322 			rate /= rrl->searches;
323 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
324 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP,
325 			      "increase from %d to %d RRL bins for"
326 			      " %d entries; average search length %.1f",
327 			      old_bins, new_bins, rrl->num_entries, rate);
328 	}
329 
330 	rrl->old_hash = rrl->hash;
331 	if (rrl->old_hash != NULL)
332 		rrl->old_hash->check_time = now;
333 	rrl->hash = hash;
334 
335 	return (ISC_R_SUCCESS);
336 }
337 
338 static void
339 ref_entry(dns_rrl_t *rrl, dns_rrl_entry_t *e, int probes, isc_stdtime_t now) {
340 	/*
341 	 * Make the entry most recently used.
342 	 */
343 	if (ISC_LIST_HEAD(rrl->lru) != e) {
344 		if (e == rrl->last_logged)
345 			rrl->last_logged = ISC_LIST_PREV(e, lru);
346 		ISC_LIST_UNLINK(rrl->lru, e, lru);
347 		ISC_LIST_PREPEND(rrl->lru, e, lru);
348 	}
349 
350 	/*
351 	 * Expand the hash table if it is time and necessary.
352 	 * This will leave the newly referenced entry in a chain in the
353 	 * old hash table.  It will migrate to the new hash table the next
354 	 * time it is used or be cut loose when the old hash table is destroyed.
355 	 */
356 	rrl->probes += probes;
357 	++rrl->searches;
358 	if (rrl->searches > 100 &&
359 	    delta_rrl_time(rrl->hash->check_time, now) > 1) {
360 		if (rrl->probes/rrl->searches > 2)
361 			expand_rrl_hash(rrl, now);
362 		rrl->hash->check_time = now;
363 		rrl->probes = 0;
364 		rrl->searches = 0;
365 	}
366 }
367 
368 static inline isc_boolean_t
369 key_cmp(const dns_rrl_key_t *a, const dns_rrl_key_t *b) {
370 	if (memcmp(a, b, sizeof(dns_rrl_key_t)) == 0)
371 		return (ISC_TRUE);
372 	return (ISC_FALSE);
373 }
374 
375 static inline isc_uint32_t
376 hash_key(const dns_rrl_key_t *key) {
377 	isc_uint32_t hval;
378 	int i;
379 
380 	hval = key->w[0];
381 	for (i = sizeof(*key) / sizeof(key->w[0]) - 1; i >= 0; --i) {
382 		hval = key->w[i] + (hval<<1);
383 	}
384 	return (hval);
385 }
386 
387 /*
388  * Construct the hash table key.
389  * Use a hash of the DNS query name to save space in the database.
390  * Collisions result in legitimate rate limiting responses for one
391  * query name also limiting responses for other names to the
392  * same client.  This is rare and benign enough given the large
393  * space costs compared to keeping the entire name in the database
394  * entry or the time costs of dynamic allocation.
395  */
396 static void
397 make_key(const dns_rrl_t *rrl, dns_rrl_key_t *key,
398 	 const isc_sockaddr_t *client_addr,
399 	 dns_rdatatype_t qtype, dns_name_t *qname, dns_rdataclass_t qclass,
400 	 dns_rrl_rtype_t rtype)
401 {
402 	dns_name_t base;
403 	dns_offsets_t base_offsets;
404 	int labels, i;
405 
406 	memset(key, 0, sizeof(*key));
407 
408 	key->s.rtype = rtype;
409 	if (rtype == DNS_RRL_RTYPE_QUERY) {
410 		key->s.qtype = qtype;
411 		key->s.qclass = qclass & 0xff;
412 	} else if (rtype == DNS_RRL_RTYPE_REFERRAL ||
413 		   rtype == DNS_RRL_RTYPE_NODATA) {
414 		/*
415 		 * Because there is no qtype in the empty answer sections of
416 		 * referral and NODATA responses, count them as the same.
417 		 */
418 		key->s.qclass = qclass & 0xff;
419 	}
420 
421 	if (qname != NULL && qname->labels != 0) {
422 		/*
423 		 * Ignore the first label of wildcards.
424 		 */
425 		if ((qname->attributes & DNS_NAMEATTR_WILDCARD) != 0 &&
426 		    (labels = dns_name_countlabels(qname)) > 1)
427 		{
428 			dns_name_init(&base, base_offsets);
429 			dns_name_getlabelsequence(qname, 1, labels-1, &base);
430 			key->s.qname_hash = dns_name_hashbylabel(&base,
431 							ISC_FALSE);
432 		} else {
433 			key->s.qname_hash = dns_name_hashbylabel(qname,
434 							ISC_FALSE);
435 		}
436 	}
437 
438 	switch (client_addr->type.sa.sa_family) {
439 	case AF_INET:
440 		key->s.ip[0] = (client_addr->type.sin.sin_addr.s_addr &
441 			      rrl->ipv4_mask);
442 		break;
443 	case AF_INET6:
444 		key->s.ipv6 = ISC_TRUE;
445 		memmove(key->s.ip, &client_addr->type.sin6.sin6_addr,
446 			sizeof(key->s.ip));
447 		for (i = 0; i < DNS_RRL_MAX_PREFIX/32; ++i)
448 			key->s.ip[i] &= rrl->ipv6_mask[i];
449 		break;
450 	}
451 }
452 
453 static inline dns_rrl_rate_t *
454 get_rate(dns_rrl_t *rrl, dns_rrl_rtype_t rtype) {
455 	switch (rtype) {
456 	case DNS_RRL_RTYPE_QUERY:
457 		return (&rrl->responses_per_second);
458 	case DNS_RRL_RTYPE_REFERRAL:
459 		return (&rrl->referrals_per_second);
460 	case DNS_RRL_RTYPE_NODATA:
461 		return (&rrl->nodata_per_second);
462 	case DNS_RRL_RTYPE_NXDOMAIN:
463 		return (&rrl->nxdomains_per_second);
464 	case DNS_RRL_RTYPE_ERROR:
465 		return (&rrl->errors_per_second);
466 	case DNS_RRL_RTYPE_ALL:
467 		return (&rrl->all_per_second);
468 	default:
469 		INSIST(0);
470 	}
471 	return (NULL);
472 }
473 
474 static int
475 response_balance(dns_rrl_t *rrl, const dns_rrl_entry_t *e, int age) {
476 	dns_rrl_rate_t *ratep;
477 	int balance, rate;
478 
479 	if (e->key.s.rtype == DNS_RRL_RTYPE_TCP) {
480 		rate = 1;
481 	} else {
482 		ratep = get_rate(rrl, e->key.s.rtype);
483 		rate = ratep->scaled;
484 	}
485 
486 	balance = e->responses + age * rate;
487 	if (balance > rate)
488 		balance = rate;
489 	return (balance);
490 }
491 
492 /*
493  * Search for an entry for a response and optionally create it.
494  */
495 static dns_rrl_entry_t *
496 get_entry(dns_rrl_t *rrl, const isc_sockaddr_t *client_addr,
497 	  dns_rdataclass_t qclass, dns_rdatatype_t qtype, dns_name_t *qname,
498 	  dns_rrl_rtype_t rtype, isc_stdtime_t now, isc_boolean_t create,
499 	  char *log_buf, unsigned int log_buf_len)
500 {
501 	dns_rrl_key_t key;
502 	isc_uint32_t hval;
503 	dns_rrl_entry_t *e;
504 	dns_rrl_hash_t *hash;
505 	dns_rrl_bin_t *new_bin, *old_bin;
506 	int probes, age;
507 
508 	make_key(rrl, &key, client_addr, qtype, qname, qclass, rtype);
509 	hval = hash_key(&key);
510 
511 	/*
512 	 * Look for the entry in the current hash table.
513 	 */
514 	new_bin = get_bin(rrl->hash, hval);
515 	probes = 1;
516 	e = ISC_LIST_HEAD(*new_bin);
517 	while (e != NULL) {
518 		if (key_cmp(&e->key, &key)) {
519 			ref_entry(rrl, e, probes, now);
520 			return (e);
521 		}
522 		++probes;
523 		e = ISC_LIST_NEXT(e, hlink);
524 	}
525 
526 	/*
527 	 * Look in the old hash table.
528 	 */
529 	if (rrl->old_hash != NULL) {
530 		old_bin = get_bin(rrl->old_hash, hval);
531 		e = ISC_LIST_HEAD(*old_bin);
532 		while (e != NULL) {
533 			if (key_cmp(&e->key, &key)) {
534 				ISC_LIST_UNLINK(*old_bin, e, hlink);
535 				ISC_LIST_PREPEND(*new_bin, e, hlink);
536 				e->hash_gen = rrl->hash_gen;
537 				ref_entry(rrl, e, probes, now);
538 				return (e);
539 			}
540 			e = ISC_LIST_NEXT(e, hlink);
541 		}
542 
543 		/*
544 		 * Discard prevous hash table when all of its entries are old.
545 		 */
546 		age = delta_rrl_time(rrl->old_hash->check_time, now);
547 		if (age > rrl->window)
548 			free_old_hash(rrl);
549 	}
550 
551 	if (!create)
552 		return (NULL);
553 
554 	/*
555 	 * The entry does not exist, so create it by finding a free entry.
556 	 * Keep currently penalized and logged entries.
557 	 * Try to make more entries if none are idle.
558 	 * Steal the oldest entry if we cannot create more.
559 	 */
560 	for (e = ISC_LIST_TAIL(rrl->lru);
561 	     e != NULL;
562 	     e = ISC_LIST_PREV(e, lru))
563 	{
564 		if (!ISC_LINK_LINKED(e, hlink))
565 			break;
566 		age = get_age(rrl, e, now);
567 		if (age <= 1) {
568 			e = NULL;
569 			break;
570 		}
571 		if (!e->logged && response_balance(rrl, e, age) > 0)
572 			break;
573 	}
574 	if (e == NULL) {
575 		expand_entries(rrl, ISC_MIN((rrl->num_entries+1)/2, 1000));
576 		e = ISC_LIST_TAIL(rrl->lru);
577 	}
578 	if (e->logged)
579 		log_end(rrl, e, ISC_TRUE, log_buf, log_buf_len);
580 	if (ISC_LINK_LINKED(e, hlink)) {
581 		if (e->hash_gen == rrl->hash_gen)
582 			hash = rrl->hash;
583 		else
584 			hash = rrl->old_hash;
585 		old_bin = get_bin(hash, hash_key(&e->key));
586 		ISC_LIST_UNLINK(*old_bin, e, hlink);
587 	}
588 	ISC_LIST_PREPEND(*new_bin, e, hlink);
589 	e->hash_gen = rrl->hash_gen;
590 	e->key = key;
591 	e->ts_valid = ISC_FALSE;
592 	ref_entry(rrl, e, probes, now);
593 	return (e);
594 }
595 
596 static void
597 debit_log(const dns_rrl_entry_t *e, int age, const char *action) {
598 	char buf[sizeof("age=12345678")];
599 	const char *age_str;
600 
601 	if (age == DNS_RRL_FOREVER) {
602 		age_str = "";
603 	} else {
604 		snprintf(buf, sizeof(buf), "age=%d", age);
605 		age_str = buf;
606 	}
607 	isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
608 		      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG3,
609 		      "rrl %08x %6s  responses=%-3d %s",
610 		      hash_key(&e->key), age_str, e->responses, action);
611 }
612 
613 static inline dns_rrl_result_t
614 debit_rrl_entry(dns_rrl_t *rrl, dns_rrl_entry_t *e, double qps, double scale,
615 		const isc_sockaddr_t *client_addr, isc_stdtime_t now,
616 		char *log_buf, unsigned int log_buf_len)
617 {
618 	int rate, new_rate, slip, new_slip, age, log_secs, min;
619 	dns_rrl_rate_t *ratep;
620 	dns_rrl_entry_t const *credit_e;
621 
622 	/*
623 	 * Pick the rate counter.
624 	 * Optionally adjust the rate by the estimated query/second rate.
625 	 */
626 	ratep = get_rate(rrl, e->key.s.rtype);
627 	rate = ratep->r;
628 	if (rate == 0)
629 		return (DNS_RRL_RESULT_OK);
630 
631 	if (scale < 1.0) {
632 		/*
633 		 * The limit for clients that have used TCP is not scaled.
634 		 */
635 		credit_e = get_entry(rrl, client_addr,
636 				     0, dns_rdatatype_none, NULL,
637 				     DNS_RRL_RTYPE_TCP, now, ISC_FALSE,
638 				     log_buf, log_buf_len);
639 		if (credit_e != NULL) {
640 			age = get_age(rrl, e, now);
641 			if (age < rrl->window)
642 				scale = 1.0;
643 		}
644 	}
645 	if (scale < 1.0) {
646 		new_rate = (int) (rate * scale);
647 		if (new_rate < 1)
648 			new_rate = 1;
649 		if (ratep->scaled != new_rate) {
650 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
651 				      DNS_LOGMODULE_REQUEST,
652 				      DNS_RRL_LOG_DEBUG1,
653 				      "%d qps scaled %s by %.2f"
654 				      " from %d to %d",
655 				      (int)qps, ratep->str, scale,
656 				      rate, new_rate);
657 			rate = new_rate;
658 			ratep->scaled = rate;
659 		}
660 	}
661 
662 	min = -rrl->window * rate;
663 
664 	/*
665 	 * Treat time jumps into the recent past as no time.
666 	 * Treat entries older than the window as if they were just created
667 	 * Credit other entries.
668 	 */
669 	age = get_age(rrl, e, now);
670 	if (age > 0) {
671 		/*
672 		 * Credit tokens earned during elapsed time.
673 		 */
674 		if (age > rrl->window) {
675 			e->responses = rate;
676 			e->slip_cnt = 0;
677 		} else {
678 			e->responses += rate*age;
679 			if (e->responses > rate) {
680 				e->responses = rate;
681 				e->slip_cnt = 0;
682 			}
683 		}
684 		/*
685 		 * Find the seconds since last log message without overflowing
686 		 * small counter.  This counter is reset when an entry is
687 		 * created.  It is not necessarily reset when some requests
688 		 * are answered provided other requests continue to be dropped
689 		 * or slipped.  This can happen when the request rate is just
690 		 * at the limit.
691 		 */
692 		if (e->logged) {
693 			log_secs = e->log_secs;
694 			log_secs += age;
695 			if (log_secs > DNS_RRL_MAX_LOG_SECS || log_secs < 0)
696 				log_secs = DNS_RRL_MAX_LOG_SECS;
697 			e->log_secs = log_secs;
698 		}
699 	}
700 	set_age(rrl, e, now);
701 
702 	/*
703 	 * Debit the entry for this response.
704 	 */
705 	if (--e->responses >= 0) {
706 		if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3))
707 			debit_log(e, age, "");
708 		return (DNS_RRL_RESULT_OK);
709 	}
710 
711 	if (e->responses < min)
712 		e->responses = min;
713 
714 	/*
715 	 * Drop this response unless it should slip or leak.
716 	 */
717 	slip = rrl->slip.r;
718 	if (slip > 2 && scale < 1.0) {
719 		new_slip = (int) (slip * scale);
720 		if (new_slip < 2)
721 			new_slip = 2;
722 		if (rrl->slip.scaled != new_slip) {
723 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
724 				      DNS_LOGMODULE_REQUEST,
725 				      DNS_RRL_LOG_DEBUG1,
726 				      "%d qps scaled slip"
727 				      " by %.2f from %d to %d",
728 				      (int)qps, scale,
729 				      slip, new_slip);
730 			slip = new_slip;
731 			rrl->slip.scaled = slip;
732 		}
733 	}
734 	if (slip != 0 && e->key.s.rtype != DNS_RRL_RTYPE_ALL) {
735 		if (e->slip_cnt++ == 0) {
736 			if ((int) e->slip_cnt >= slip)
737 				e->slip_cnt = 0;
738 			if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3))
739 				debit_log(e, age, "slip");
740 			return (DNS_RRL_RESULT_SLIP);
741 		} else if ((int) e->slip_cnt >= slip) {
742 			e->slip_cnt = 0;
743 		}
744 	}
745 
746 	if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG3))
747 		debit_log(e, age, "drop");
748 	return (DNS_RRL_RESULT_DROP);
749 }
750 
751 static inline dns_rrl_qname_buf_t *
752 get_qname(dns_rrl_t *rrl, const dns_rrl_entry_t *e) {
753 	dns_rrl_qname_buf_t *qbuf;
754 
755 	qbuf = rrl->qnames[e->log_qname];
756 	if (qbuf == NULL || qbuf->e != e)
757 		return (NULL);
758 	return (qbuf);
759 }
760 
761 static inline void
762 free_qname(dns_rrl_t *rrl, dns_rrl_entry_t *e) {
763 	dns_rrl_qname_buf_t *qbuf;
764 
765 	qbuf = get_qname(rrl, e);
766 	if (qbuf != NULL) {
767 		qbuf->e = NULL;
768 		ISC_LIST_APPEND(rrl->qname_free, qbuf, link);
769 	}
770 }
771 
772 static void
773 add_log_str(isc_buffer_t *lb, const char *str, unsigned int str_len) {
774 	isc_region_t region;
775 
776 	isc_buffer_availableregion(lb, &region);
777 	if (str_len >= region.length) {
778 		if (region.length <= 0)
779 			return;
780 		str_len = region.length;
781 	}
782 	memmove(region.base, str, str_len);
783 	isc_buffer_add(lb, str_len);
784 }
785 
786 #define ADD_LOG_CSTR(eb, s) add_log_str(eb, s, sizeof(s)-1)
787 
788 /*
789  * Build strings for the logs
790  */
791 static void
792 make_log_buf(dns_rrl_t *rrl, dns_rrl_entry_t *e,
793 	     const char *str1, const char *str2, isc_boolean_t plural,
794 	     dns_name_t *qname, isc_boolean_t save_qname,
795 	     dns_rrl_result_t rrl_result, isc_result_t resp_result,
796 	     char *log_buf, unsigned int log_buf_len)
797 {
798 	isc_buffer_t lb;
799 	dns_rrl_qname_buf_t *qbuf;
800 	isc_netaddr_t cidr;
801 	char strbuf[ISC_MAX(sizeof("/123"), sizeof("  (12345678)"))];
802 	const char *rstr;
803 	isc_result_t msg_result;
804 
805 	if (log_buf_len <= 1) {
806 		if (log_buf_len == 1)
807 			log_buf[0] = '\0';
808 		return;
809 	}
810 	isc_buffer_init(&lb, log_buf, log_buf_len-1);
811 
812 	if (str1 != NULL)
813 		add_log_str(&lb, str1, strlen(str1));
814 	if (str2 != NULL)
815 		add_log_str(&lb, str2, strlen(str2));
816 
817 	switch (rrl_result) {
818 	case DNS_RRL_RESULT_OK:
819 		break;
820 	case DNS_RRL_RESULT_DROP:
821 		ADD_LOG_CSTR(&lb, "drop ");
822 		break;
823 	case DNS_RRL_RESULT_SLIP:
824 		ADD_LOG_CSTR(&lb, "slip ");
825 		break;
826 	default:
827 		INSIST(0);
828 		break;
829 	}
830 
831 	switch (e->key.s.rtype) {
832 	case DNS_RRL_RTYPE_QUERY:
833 		break;
834 	case DNS_RRL_RTYPE_REFERRAL:
835 		ADD_LOG_CSTR(&lb, "referral ");
836 		break;
837 	case DNS_RRL_RTYPE_NODATA:
838 		ADD_LOG_CSTR(&lb, "NODATA ");
839 		break;
840 	case DNS_RRL_RTYPE_NXDOMAIN:
841 		ADD_LOG_CSTR(&lb, "NXDOMAIN ");
842 		break;
843 	case DNS_RRL_RTYPE_ERROR:
844 		if (resp_result == ISC_R_SUCCESS) {
845 			ADD_LOG_CSTR(&lb, "error ");
846 		} else {
847 			rstr = isc_result_totext(resp_result);
848 			add_log_str(&lb, rstr, strlen(rstr));
849 			ADD_LOG_CSTR(&lb, " error ");
850 		}
851 		break;
852 	case DNS_RRL_RTYPE_ALL:
853 		ADD_LOG_CSTR(&lb, "all ");
854 		break;
855 	default:
856 		INSIST(0);
857 	}
858 
859 	if (plural)
860 		ADD_LOG_CSTR(&lb, "responses to ");
861 	else
862 		ADD_LOG_CSTR(&lb, "response to ");
863 
864 	memset(&cidr, 0, sizeof(cidr));
865 	if (e->key.s.ipv6) {
866 		snprintf(strbuf, sizeof(strbuf), "/%d", rrl->ipv6_prefixlen);
867 		cidr.family = AF_INET6;
868 		memset(&cidr.type.in6, 0,  sizeof(cidr.type.in6));
869 		memmove(&cidr.type.in6, e->key.s.ip, sizeof(e->key.s.ip));
870 	} else {
871 		snprintf(strbuf, sizeof(strbuf), "/%d", rrl->ipv4_prefixlen);
872 		cidr.family = AF_INET;
873 		cidr.type.in.s_addr = e->key.s.ip[0];
874 	}
875 	msg_result = isc_netaddr_totext(&cidr, &lb);
876 	if (msg_result != ISC_R_SUCCESS)
877 		ADD_LOG_CSTR(&lb, "?");
878 	add_log_str(&lb, strbuf, strlen(strbuf));
879 
880 	if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY ||
881 	    e->key.s.rtype == DNS_RRL_RTYPE_REFERRAL ||
882 	    e->key.s.rtype == DNS_RRL_RTYPE_NODATA ||
883 	    e->key.s.rtype == DNS_RRL_RTYPE_NXDOMAIN) {
884 		qbuf = get_qname(rrl, e);
885 		if (save_qname && qbuf == NULL &&
886 		    qname != NULL && dns_name_isabsolute(qname)) {
887 			/*
888 			 * Capture the qname for the "stop limiting" message.
889 			 */
890 			qbuf = ISC_LIST_TAIL(rrl->qname_free);
891 			if (qbuf != NULL) {
892 				ISC_LIST_UNLINK(rrl->qname_free, qbuf, link);
893 			} else if (rrl->num_qnames < DNS_RRL_QNAMES) {
894 				qbuf = isc_mem_get(rrl->mctx, sizeof(*qbuf));
895 				if (qbuf != NULL) {
896 					memset(qbuf, 0, sizeof(*qbuf));
897 					ISC_LINK_INIT(qbuf, link);
898 					qbuf->index = rrl->num_qnames;
899 					rrl->qnames[rrl->num_qnames++] = qbuf;
900 				} else {
901 					isc_log_write(dns_lctx,
902 						      DNS_LOGCATEGORY_RRL,
903 						      DNS_LOGMODULE_REQUEST,
904 						      DNS_RRL_LOG_FAIL,
905 						      "isc_mem_get(%d)"
906 						      " failed for RRL qname",
907 						      (int)sizeof(*qbuf));
908 				}
909 			}
910 			if (qbuf != NULL) {
911 				e->log_qname = qbuf->index;
912 				qbuf->e = e;
913 				dns_fixedname_init(&qbuf->qname);
914 				dns_name_copy(qname,
915 					      dns_fixedname_name(&qbuf->qname),
916 					      NULL);
917 			}
918 		}
919 		if (qbuf != NULL)
920 			qname = dns_fixedname_name(&qbuf->qname);
921 		if (qname != NULL) {
922 			ADD_LOG_CSTR(&lb, " for ");
923 			(void)dns_name_totext(qname, ISC_TRUE, &lb);
924 		} else {
925 			ADD_LOG_CSTR(&lb, " for (?)");
926 		}
927 		if (e->key.s.rtype != DNS_RRL_RTYPE_NXDOMAIN) {
928 			ADD_LOG_CSTR(&lb, " ");
929 			(void)dns_rdataclass_totext(e->key.s.qclass, &lb);
930 			if (e->key.s.rtype == DNS_RRL_RTYPE_QUERY) {
931 				ADD_LOG_CSTR(&lb, " ");
932 				(void)dns_rdatatype_totext(e->key.s.qtype, &lb);
933 			}
934 		}
935 		snprintf(strbuf, sizeof(strbuf), "  (%08x)",
936 			 e->key.s.qname_hash);
937 		add_log_str(&lb, strbuf, strlen(strbuf));
938 	}
939 
940 	/*
941 	 * We saved room for '\0'.
942 	 */
943 	log_buf[isc_buffer_usedlength(&lb)] = '\0';
944 }
945 
946 static void
947 log_end(dns_rrl_t *rrl, dns_rrl_entry_t *e, isc_boolean_t early,
948 	char *log_buf, unsigned int log_buf_len)
949 {
950 	if (e->logged) {
951 		make_log_buf(rrl, e,
952 			     early ? "*" : NULL,
953 			     rrl->log_only ? "would stop limiting "
954 					   : "stop limiting ",
955 			     ISC_TRUE, NULL, ISC_FALSE,
956 			     DNS_RRL_RESULT_OK, ISC_R_SUCCESS,
957 			     log_buf, log_buf_len);
958 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
959 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP,
960 			      "%s", log_buf);
961 		free_qname(rrl, e);
962 		e->logged = ISC_FALSE;
963 		--rrl->num_logged;
964 	}
965 }
966 
967 /*
968  * Log messages for streams that have stopped being rate limited.
969  */
970 static void
971 log_stops(dns_rrl_t *rrl, isc_stdtime_t now, int limit,
972 	  char *log_buf, unsigned int log_buf_len)
973 {
974 	dns_rrl_entry_t *e;
975 	int age;
976 
977 	for (e = rrl->last_logged; e != NULL; e = ISC_LIST_PREV(e, lru)) {
978 		if (!e->logged)
979 			continue;
980 		if (now != 0) {
981 			age = get_age(rrl, e, now);
982 			if (age < DNS_RRL_STOP_LOG_SECS ||
983 			    response_balance(rrl, e, age) < 0)
984 				break;
985 		}
986 
987 		log_end(rrl, e, now == 0, log_buf, log_buf_len);
988 		if (rrl->num_logged <= 0)
989 			break;
990 
991 		/*
992 		 * Too many messages could stall real work.
993 		 */
994 		if (--limit < 0) {
995 			rrl->last_logged = ISC_LIST_PREV(e, lru);
996 			return;
997 		}
998 	}
999 	if (e == NULL) {
1000 		INSIST(rrl->num_logged == 0);
1001 		rrl->log_stops_time = now;
1002 	}
1003 	rrl->last_logged = e;
1004 }
1005 
1006 /*
1007  * Main rate limit interface.
1008  */
1009 dns_rrl_result_t
1010 dns_rrl(dns_view_t *view,
1011 	const isc_sockaddr_t *client_addr, isc_boolean_t is_tcp,
1012 	dns_rdataclass_t qclass, dns_rdatatype_t qtype,
1013 	dns_name_t *qname, isc_result_t resp_result, isc_stdtime_t now,
1014 	isc_boolean_t wouldlog, char *log_buf, unsigned int log_buf_len)
1015 {
1016 	dns_rrl_t *rrl;
1017 	dns_rrl_rtype_t rtype;
1018 	dns_rrl_entry_t *e;
1019 	isc_netaddr_t netclient;
1020 	int secs;
1021 	double qps, scale;
1022 	int exempt_match;
1023 	isc_result_t result;
1024 	dns_rrl_result_t rrl_result;
1025 
1026 	INSIST(log_buf != NULL && log_buf_len > 0);
1027 
1028 	rrl = view->rrl;
1029 	if (rrl->exempt != NULL) {
1030 		isc_netaddr_fromsockaddr(&netclient, client_addr);
1031 		result = dns_acl_match(&netclient, NULL, rrl->exempt,
1032 				       &view->aclenv, &exempt_match, NULL);
1033 		if (result == ISC_R_SUCCESS && exempt_match > 0)
1034 			return (DNS_RRL_RESULT_OK);
1035 	}
1036 
1037 	LOCK(&rrl->lock);
1038 
1039 	/*
1040 	 * Estimate total query per second rate when scaling by qps.
1041 	 */
1042 	if (rrl->qps_scale == 0) {
1043 		qps = 0.0;
1044 		scale = 1.0;
1045 	} else {
1046 		++rrl->qps_responses;
1047 		secs = delta_rrl_time(rrl->qps_time, now);
1048 		if (secs <= 0) {
1049 			qps = rrl->qps;
1050 		} else {
1051 			qps = (1.0*rrl->qps_responses) / secs;
1052 			if (secs >= rrl->window) {
1053 				if (isc_log_wouldlog(dns_lctx,
1054 						     DNS_RRL_LOG_DEBUG3))
1055 					isc_log_write(dns_lctx,
1056 						      DNS_LOGCATEGORY_RRL,
1057 						      DNS_LOGMODULE_REQUEST,
1058 						      DNS_RRL_LOG_DEBUG3,
1059 						      "%d responses/%d seconds"
1060 						      " = %d qps",
1061 						      rrl->qps_responses, secs,
1062 						      (int)qps);
1063 				rrl->qps = qps;
1064 				rrl->qps_responses = 0;
1065 				rrl->qps_time = now;
1066 			} else if (qps < rrl->qps) {
1067 				qps = rrl->qps;
1068 			}
1069 		}
1070 		scale = rrl->qps_scale / qps;
1071 	}
1072 
1073 	/*
1074 	 * Do maintenance once per second.
1075 	 */
1076 	if (rrl->num_logged > 0 && rrl->log_stops_time != now)
1077 		log_stops(rrl, now, 8, log_buf, log_buf_len);
1078 
1079 	/*
1080 	 * Notice TCP responses when scaling limits by qps.
1081 	 * Do not try to rate limit TCP responses.
1082 	 */
1083 	if (is_tcp) {
1084 		if (scale < 1.0) {
1085 			e = get_entry(rrl, client_addr,
1086 				      0, dns_rdatatype_none, NULL,
1087 				      DNS_RRL_RTYPE_TCP, now, ISC_TRUE,
1088 				      log_buf, log_buf_len);
1089 			if (e != NULL) {
1090 				e->responses = -(rrl->window+1);
1091 				set_age(rrl, e, now);
1092 			}
1093 		}
1094 		UNLOCK(&rrl->lock);
1095 		return (ISC_R_SUCCESS);
1096 	}
1097 
1098 	/*
1099 	 * Find the right kind of entry, creating it if necessary.
1100 	 * If that is impossible, then nothing more can be done
1101 	 */
1102 	switch (resp_result) {
1103 	case ISC_R_SUCCESS:
1104 		rtype = DNS_RRL_RTYPE_QUERY;
1105 		break;
1106 	case DNS_R_DELEGATION:
1107 		rtype = DNS_RRL_RTYPE_REFERRAL;
1108 		break;
1109 	case DNS_R_NXRRSET:
1110 		rtype = DNS_RRL_RTYPE_NODATA;
1111 		break;
1112 	case DNS_R_NXDOMAIN:
1113 		rtype = DNS_RRL_RTYPE_NXDOMAIN;
1114 		break;
1115 	default:
1116 		rtype = DNS_RRL_RTYPE_ERROR;
1117 		break;
1118 	}
1119 	e = get_entry(rrl, client_addr, qclass, qtype, qname, rtype,
1120 		      now, ISC_TRUE, log_buf, log_buf_len);
1121 	if (e == NULL) {
1122 		UNLOCK(&rrl->lock);
1123 		return (DNS_RRL_RESULT_OK);
1124 	}
1125 
1126 	if (isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DEBUG1)) {
1127 		/*
1128 		 * Do not worry about speed or releasing the lock.
1129 		 * This message appears before messages from debit_rrl_entry().
1130 		 */
1131 		make_log_buf(rrl, e, "consider limiting ", NULL, ISC_FALSE,
1132 			     qname, ISC_FALSE, DNS_RRL_RESULT_OK, resp_result,
1133 			     log_buf, log_buf_len);
1134 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
1135 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DEBUG1,
1136 			      "%s", log_buf);
1137 	}
1138 
1139 	rrl_result = debit_rrl_entry(rrl, e, qps, scale, client_addr, now,
1140 				     log_buf, log_buf_len);
1141 
1142 	if (rrl->all_per_second.r != 0) {
1143 		/*
1144 		 * We must debit the all-per-second token bucket if we have
1145 		 * an all-per-second limit for the IP address.
1146 		 * The all-per-second limit determines the log message
1147 		 * when both limits are hit.
1148 		 * The response limiting must continue if the
1149 		 * all-per-second limiting lapses.
1150 		 */
1151 		dns_rrl_entry_t *e_all;
1152 		dns_rrl_result_t rrl_all_result;
1153 
1154 		e_all = get_entry(rrl, client_addr,
1155 				  0, dns_rdatatype_none, NULL,
1156 				  DNS_RRL_RTYPE_ALL, now, ISC_TRUE,
1157 				  log_buf, log_buf_len);
1158 		if (e_all == NULL) {
1159 			UNLOCK(&rrl->lock);
1160 			return (DNS_RRL_RESULT_OK);
1161 		}
1162 		rrl_all_result = debit_rrl_entry(rrl, e_all, qps, scale,
1163 						 client_addr, now,
1164 						 log_buf, log_buf_len);
1165 		if (rrl_all_result != DNS_RRL_RESULT_OK) {
1166 			int level;
1167 
1168 			e = e_all;
1169 			rrl_result = rrl_all_result;
1170 			if (rrl_result == DNS_RRL_RESULT_OK)
1171 				level = DNS_RRL_LOG_DEBUG2;
1172 			else
1173 				level = DNS_RRL_LOG_DEBUG1;
1174 			if (isc_log_wouldlog(dns_lctx, level)) {
1175 				make_log_buf(rrl, e,
1176 					     "prefer all-per-second limiting ",
1177 					     NULL, ISC_TRUE, qname, ISC_FALSE,
1178 					     DNS_RRL_RESULT_OK, resp_result,
1179 					     log_buf, log_buf_len);
1180 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
1181 					      DNS_LOGMODULE_REQUEST, level,
1182 					      "%s", log_buf);
1183 			}
1184 		}
1185 	}
1186 
1187 	if (rrl_result == DNS_RRL_RESULT_OK) {
1188 		UNLOCK(&rrl->lock);
1189 		return (DNS_RRL_RESULT_OK);
1190 	}
1191 
1192 	/*
1193 	 * Log occassionally in the rate-limit category.
1194 	 */
1195 	if ((!e->logged || e->log_secs >= DNS_RRL_MAX_LOG_SECS) &&
1196 	    isc_log_wouldlog(dns_lctx, DNS_RRL_LOG_DROP)) {
1197 		make_log_buf(rrl, e, rrl->log_only ? "would " : NULL,
1198 			     e->logged ? "continue limiting " : "limit ",
1199 			     ISC_TRUE, qname, ISC_TRUE,
1200 			     DNS_RRL_RESULT_OK, resp_result,
1201 			     log_buf, log_buf_len);
1202 		if (!e->logged) {
1203 			e->logged = ISC_TRUE;
1204 			if (++rrl->num_logged <= 1)
1205 				rrl->last_logged = e;
1206 		}
1207 		e->log_secs = 0;
1208 
1209 		/*
1210 		 * Avoid holding the lock.
1211 		 */
1212 		if (!wouldlog) {
1213 			UNLOCK(&rrl->lock);
1214 			e = NULL;
1215 		}
1216 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_RRL,
1217 			      DNS_LOGMODULE_REQUEST, DNS_RRL_LOG_DROP,
1218 			      "%s", log_buf);
1219 	}
1220 
1221 	/*
1222 	 * Make a log message for the caller.
1223 	 */
1224 	if (wouldlog)
1225 		make_log_buf(rrl, e,
1226 			     rrl->log_only ? "would rate limit " : "rate limit ",
1227 			     NULL, ISC_FALSE, qname, ISC_FALSE,
1228 			     rrl_result, resp_result, log_buf, log_buf_len);
1229 
1230 	if (e != NULL) {
1231 		/*
1232 		 * Do not save the qname unless we might need it for
1233 		 * the ending log message.
1234 		 */
1235 		if (!e->logged)
1236 			free_qname(rrl, e);
1237 		UNLOCK(&rrl->lock);
1238 	}
1239 
1240 	return (rrl_result);
1241 }
1242 
1243 void
1244 dns_rrl_view_destroy(dns_view_t *view) {
1245 	dns_rrl_t *rrl;
1246 	dns_rrl_block_t *b;
1247 	dns_rrl_hash_t *h;
1248 	char log_buf[DNS_RRL_LOG_BUF_LEN];
1249 	int i;
1250 
1251 	rrl = view->rrl;
1252 	if (rrl == NULL)
1253 		return;
1254 	view->rrl = NULL;
1255 
1256 	/*
1257 	 * Assume the caller takes care of locking the view and anything else.
1258 	 */
1259 
1260 	if (rrl->num_logged > 0)
1261 		log_stops(rrl, 0, ISC_INT32_MAX, log_buf, sizeof(log_buf));
1262 
1263 	for (i = 0; i < DNS_RRL_QNAMES; ++i) {
1264 		if (rrl->qnames[i] == NULL)
1265 			break;
1266 		isc_mem_put(rrl->mctx, rrl->qnames[i], sizeof(*rrl->qnames[i]));
1267 	}
1268 
1269 	if (rrl->exempt != NULL)
1270 		dns_acl_detach(&rrl->exempt);
1271 
1272 	DESTROYLOCK(&rrl->lock);
1273 
1274 	while (!ISC_LIST_EMPTY(rrl->blocks)) {
1275 		b = ISC_LIST_HEAD(rrl->blocks);
1276 		ISC_LIST_UNLINK(rrl->blocks, b, link);
1277 		isc_mem_put(rrl->mctx, b, b->size);
1278 	}
1279 
1280 	h = rrl->hash;
1281 	if (h != NULL)
1282 		isc_mem_put(rrl->mctx, h,
1283 			    sizeof(*h) + (h->length - 1) * sizeof(h->bins[0]));
1284 
1285 	h = rrl->old_hash;
1286 	if (h != NULL)
1287 		isc_mem_put(rrl->mctx, h,
1288 			    sizeof(*h) + (h->length - 1) * sizeof(h->bins[0]));
1289 
1290 	isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl));
1291 }
1292 
1293 isc_result_t
1294 dns_rrl_init(dns_rrl_t **rrlp, dns_view_t *view, int min_entries) {
1295 	dns_rrl_t *rrl;
1296 	isc_result_t result;
1297 
1298 	*rrlp = NULL;
1299 
1300 	rrl = isc_mem_get(view->mctx, sizeof(*rrl));
1301 	if (rrl == NULL)
1302 		return (ISC_R_NOMEMORY);
1303 	memset(rrl, 0, sizeof(*rrl));
1304 	isc_mem_attach(view->mctx, &rrl->mctx);
1305 	result = isc_mutex_init(&rrl->lock);
1306 	if (result != ISC_R_SUCCESS) {
1307 		isc_mem_putanddetach(&rrl->mctx, rrl, sizeof(*rrl));
1308 		return (result);
1309 	}
1310 	isc_stdtime_get(&rrl->ts_bases[0]);
1311 
1312 	view->rrl = rrl;
1313 
1314 	result = expand_entries(rrl, min_entries);
1315 	if (result != ISC_R_SUCCESS) {
1316 		dns_rrl_view_destroy(view);
1317 		return (result);
1318 	}
1319 	result = expand_rrl_hash(rrl, 0);
1320 	if (result != ISC_R_SUCCESS) {
1321 		dns_rrl_view_destroy(view);
1322 		return (result);
1323 	}
1324 
1325 	*rrlp = rrl;
1326 	return (ISC_R_SUCCESS);
1327 }
1328