1 /*
2  * Copyright (C) 2013, 2015  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 
18 #ifndef DNS_RRL_H
19 #define DNS_RRL_H 1
20 
21 /*
22  * Rate limit DNS responses.
23  */
24 
25 #include <isc/lang.h>
26 
27 #include <dns/fixedname.h>
28 #include <dns/rdata.h>
29 #include <dns/types.h>
30 
31 ISC_LANG_BEGINDECLS
32 
33 
34 /*
35  * Memory allocation or other failures.
36  */
37 #define DNS_RRL_LOG_FAIL	ISC_LOG_WARNING
38 /*
39  * dropped or slipped responses.
40  */
41 #define DNS_RRL_LOG_DROP	ISC_LOG_INFO
42 /*
43  * Major events in dropping or slipping.
44  */
45 #define DNS_RRL_LOG_DEBUG1	ISC_LOG_DEBUG(3)
46 /*
47  * Limit computations.
48  */
49 #define DNS_RRL_LOG_DEBUG2	ISC_LOG_DEBUG(4)
50 /*
51  * Even less interesting.
52  */
53 #define DNS_RRL_LOG_DEBUG3	ISC_LOG_DEBUG(9)
54 
55 
56 #define DNS_RRL_LOG_ERR_LEN	64
57 #define DNS_RRL_LOG_BUF_LEN	(sizeof("would continue limiting") +	\
58 				 DNS_RRL_LOG_ERR_LEN +			\
59 				 sizeof(" responses to ") +		\
60 				 ISC_NETADDR_FORMATSIZE +		\
61 				 sizeof("/128 for IN ") +		\
62 				 DNS_RDATATYPE_FORMATSIZE +		\
63 				 DNS_NAME_FORMATSIZE)
64 
65 
66 typedef struct dns_rrl_hash dns_rrl_hash_t;
67 
68 /*
69  * Response types.
70  */
71 typedef enum {
72 	DNS_RRL_RTYPE_FREE = 0,
73 	DNS_RRL_RTYPE_QUERY,
74 	DNS_RRL_RTYPE_REFERRAL,
75 	DNS_RRL_RTYPE_NODATA,
76 	DNS_RRL_RTYPE_NXDOMAIN,
77 	DNS_RRL_RTYPE_ERROR,
78 	DNS_RRL_RTYPE_ALL,
79 	DNS_RRL_RTYPE_TCP,
80 } dns_rrl_rtype_t;
81 
82 /*
83  * A rate limit bucket key.
84  * This should be small to limit the total size of the database.
85  * The hash of the qname should be wide enough to make the probability
86  * of collisions among requests from a single IP address block less than 50%.
87  * We need a 32-bit hash value for 10000 qps (e.g. random qnames forged
88  * by attacker) to collide with legitimate qnames from the target with
89  * probability at most 1%.
90  */
91 #define DNS_RRL_MAX_PREFIX  64
92 typedef union dns_rrl_key dns_rrl_key_t;
93 struct dns__rrl_key {
94 	isc_uint32_t	    ip[DNS_RRL_MAX_PREFIX/32];
95 	isc_uint32_t	    qname_hash;
96 	dns_rdatatype_t	    qtype;
97 	isc_uint8_t         qclass;
98 	dns_rrl_rtype_t	    rtype   :4; /* 3 bits + sign bit */
99 	isc_boolean_t	    ipv6    :1;
100 };
101 union dns_rrl_key {
102 	struct dns__rrl_key s;
103 	isc_uint16_t	w[sizeof(struct dns__rrl_key)/sizeof(isc_uint16_t)];
104 };
105 
106 /*
107  * A rate-limit entry.
108  * This should be small to limit the total size of the table of entries.
109  */
110 typedef struct dns_rrl_entry dns_rrl_entry_t;
111 typedef ISC_LIST(dns_rrl_entry_t) dns_rrl_bin_t;
112 struct dns_rrl_entry {
113 	ISC_LINK(dns_rrl_entry_t) lru;
114 	ISC_LINK(dns_rrl_entry_t) hlink;
115 	dns_rrl_key_t	key;
116 # define DNS_RRL_RESPONSE_BITS	24
117 	signed int	responses   :DNS_RRL_RESPONSE_BITS;
118 # define DNS_RRL_QNAMES_BITS	8
119 	unsigned int	log_qname   :DNS_RRL_QNAMES_BITS;
120 
121 # define DNS_RRL_TS_GEN_BITS	2
122 	unsigned int	ts_gen	    :DNS_RRL_TS_GEN_BITS;
123 	isc_boolean_t	ts_valid    :1;
124 # define DNS_RRL_HASH_GEN_BITS	1
125 	unsigned int	hash_gen    :DNS_RRL_HASH_GEN_BITS;
126 	isc_boolean_t	logged	    :1;
127 # define DNS_RRL_LOG_BITS	11
128 	unsigned int	log_secs    :DNS_RRL_LOG_BITS;
129 
130 # define DNS_RRL_TS_BITS	12
131 	unsigned int	ts	    :DNS_RRL_TS_BITS;
132 
133 # define DNS_RRL_MAX_SLIP	10
134 	unsigned int	slip_cnt    :4;
135 };
136 
137 #define DNS_RRL_MAX_TIME_TRAVEL	5
138 #define DNS_RRL_FOREVER		(1<<DNS_RRL_TS_BITS)
139 #define DNS_RRL_MAX_TS		(DNS_RRL_FOREVER - 1)
140 
141 #define DNS_RRL_MAX_RESPONSES	((1<<(DNS_RRL_RESPONSE_BITS-1))-1)
142 #define DNS_RRL_MAX_WINDOW	3600
143 #if DNS_RRL_MAX_WINDOW >= DNS_RRL_MAX_TS
144 #error "DNS_RRL_MAX_WINDOW is too large"
145 #endif
146 #define DNS_RRL_MAX_RATE	1000
147 #if DNS_RRL_MAX_RATE >= (DNS_RRL_MAX_RESPONSES / DNS_RRL_MAX_WINDOW)
148 #error "DNS_RRL_MAX_rate is too large"
149 #endif
150 
151 #if (1<<DNS_RRL_LOG_BITS) >= DNS_RRL_FOREVER
152 #error DNS_RRL_LOG_BITS is too big
153 #endif
154 #define DNS_RRL_MAX_LOG_SECS	1800
155 #if DNS_RRL_MAX_LOG_SECS >= (1<<DNS_RRL_LOG_BITS)
156 #error "DNS_RRL_MAX_LOG_SECS is too large"
157 #endif
158 #define DNS_RRL_STOP_LOG_SECS	60
159 #if DNS_RRL_STOP_LOG_SECS >= (1<<DNS_RRL_LOG_BITS)
160 #error "DNS_RRL_STOP_LOG_SECS is too large"
161 #endif
162 
163 
164 /*
165  * A hash table of rate-limit entries.
166  */
167 struct dns_rrl_hash {
168 	isc_stdtime_t	check_time;
169 	unsigned int	gen	    :DNS_RRL_HASH_GEN_BITS;
170 	int		length;
171 	dns_rrl_bin_t	bins[1];
172 };
173 
174 /*
175  * A block of rate-limit entries.
176  */
177 typedef struct dns_rrl_block dns_rrl_block_t;
178 struct dns_rrl_block {
179 	ISC_LINK(dns_rrl_block_t) link;
180 	int		size;
181 	dns_rrl_entry_t	entries[1];
182 };
183 
184 /*
185  * A rate limited qname buffer.
186  */
187 typedef struct dns_rrl_qname_buf dns_rrl_qname_buf_t;
188 struct dns_rrl_qname_buf {
189 	ISC_LINK(dns_rrl_qname_buf_t) link;
190 	const dns_rrl_entry_t *e;
191 	unsigned int	    index;
192 	dns_fixedname_t	    qname;
193 };
194 
195 typedef struct dns_rrl_rate dns_rrl_rate_t;
196 struct dns_rrl_rate {
197 	int	    r;
198 	int	    scaled;
199 	const char  *str;
200 };
201 
202 /*
203  * Per-view query rate limit parameters and a pointer to database.
204  */
205 typedef struct dns_rrl dns_rrl_t;
206 struct dns_rrl {
207 	isc_mutex_t	lock;
208 	isc_mem_t	*mctx;
209 
210 	isc_boolean_t	log_only;
211 	dns_rrl_rate_t	responses_per_second;
212 	dns_rrl_rate_t	referrals_per_second;
213 	dns_rrl_rate_t	nodata_per_second;
214 	dns_rrl_rate_t	nxdomains_per_second;
215 	dns_rrl_rate_t	errors_per_second;
216 	dns_rrl_rate_t	all_per_second;
217 	dns_rrl_rate_t	slip;
218 	int		window;
219 	double		qps_scale;
220 	int		max_entries;
221 
222 	dns_acl_t	*exempt;
223 
224 	int		num_entries;
225 
226 	int		qps_responses;
227 	isc_stdtime_t	qps_time;
228 	double		qps;
229 
230 	unsigned int	probes;
231 	unsigned int	searches;
232 
233 	ISC_LIST(dns_rrl_block_t) blocks;
234 	ISC_LIST(dns_rrl_entry_t) lru;
235 
236 	dns_rrl_hash_t	*hash;
237 	dns_rrl_hash_t	*old_hash;
238 	unsigned int	hash_gen;
239 
240 	unsigned int	ts_gen;
241 # define DNS_RRL_TS_BASES   (1<<DNS_RRL_TS_GEN_BITS)
242 	isc_stdtime_t	ts_bases[DNS_RRL_TS_BASES];
243 
244 	int		ipv4_prefixlen;
245 	isc_uint32_t	ipv4_mask;
246 	int		ipv6_prefixlen;
247 	isc_uint32_t	ipv6_mask[4];
248 
249 	isc_stdtime_t	log_stops_time;
250 	dns_rrl_entry_t	*last_logged;
251 	int		num_logged;
252 	int		num_qnames;
253 	ISC_LIST(dns_rrl_qname_buf_t) qname_free;
254 # define DNS_RRL_QNAMES	    (1<<DNS_RRL_QNAMES_BITS)
255 	dns_rrl_qname_buf_t *qnames[DNS_RRL_QNAMES];
256 };
257 
258 typedef enum {
259 	DNS_RRL_RESULT_OK,
260 	DNS_RRL_RESULT_DROP,
261 	DNS_RRL_RESULT_SLIP,
262 } dns_rrl_result_t;
263 
264 dns_rrl_result_t
265 dns_rrl(dns_view_t *view,
266 	const isc_sockaddr_t *client_addr, isc_boolean_t is_tcp,
267 	dns_rdataclass_t rdclass, dns_rdatatype_t qtype,
268 	dns_name_t *qname, isc_result_t resp_result, isc_stdtime_t now,
269 	isc_boolean_t wouldlog, char *log_buf, unsigned int log_buf_len);
270 
271 void
272 dns_rrl_view_destroy(dns_view_t *view);
273 
274 isc_result_t
275 dns_rrl_init(dns_rrl_t **rrlp, dns_view_t *view, int min_entries);
276 
277 ISC_LANG_ENDDECLS
278 
279 #endif /* DNS_RRL_H */
280