"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/dns/include/dns/rrl.h" (7 Sep 2020, 6639 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "rrl.h" see the Fossies "Dox" file reference documentation.

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