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