Coverage Report

Created: 2025-07-18 07:00

/src/unbound/services/cache/infra.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * services/cache/infra.c - infrastructure cache, server rtt and capabilities
3
 *
4
 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5
 *
6
 * This software is open source.
7
 * 
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 
12
 * Redistributions of source code must retain the above copyright notice,
13
 * this list of conditions and the following disclaimer.
14
 * 
15
 * Redistributions in binary form must reproduce the above copyright notice,
16
 * this list of conditions and the following disclaimer in the documentation
17
 * and/or other materials provided with the distribution.
18
 * 
19
 * Neither the name of the NLNET LABS nor the names of its contributors may
20
 * be used to endorse or promote products derived from this software without
21
 * specific prior written permission.
22
 * 
23
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
 */
35
36
/**
37
 * \file
38
 *
39
 * This file contains the infrastructure cache.
40
 */
41
#include "config.h"
42
#include "sldns/rrdef.h"
43
#include "sldns/str2wire.h"
44
#include "sldns/sbuffer.h"
45
#include "sldns/wire2str.h"
46
#include "services/cache/infra.h"
47
#include "util/storage/slabhash.h"
48
#include "util/storage/lookup3.h"
49
#include "util/data/dname.h"
50
#include "util/log.h"
51
#include "util/net_help.h"
52
#include "util/config_file.h"
53
#include "iterator/iterator.h"
54
55
/** ratelimit value for delegation point */
56
int infra_dp_ratelimit = 0;
57
58
/** ratelimit value for client ip addresses,
59
 *  in queries per second. */
60
int infra_ip_ratelimit = 0;
61
62
/** ratelimit value for client ip addresses,
63
 *  in queries per second.
64
 *  For clients with a valid DNS Cookie. */
65
int infra_ip_ratelimit_cookie = 0;
66
67
/** Minus 1000 because that is outside of the RTTBAND, so
68
 * blacklisted servers stay blacklisted if this is chosen.
69
 * If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT,
70
 * infra-cache-max-rtt) change it to just above the RTT_BAND. */
71
int
72
still_useful_timeout()
73
0
{
74
0
  return
75
0
  USEFUL_SERVER_TOP_TIMEOUT < 1000 ||
76
0
  USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND
77
0
    ?RTT_BAND + 1
78
0
    :USEFUL_SERVER_TOP_TIMEOUT - 1000;
79
0
}
80
81
size_t 
82
infra_sizefunc(void* k, void* ATTR_UNUSED(d))
83
0
{
84
0
  struct infra_key* key = (struct infra_key*)k;
85
0
  return sizeof(*key) + sizeof(struct infra_data) + key->namelen
86
0
    + lock_get_mem(&key->entry.lock);
87
0
}
88
89
int 
90
infra_compfunc(void* key1, void* key2)
91
0
{
92
0
  struct infra_key* k1 = (struct infra_key*)key1;
93
0
  struct infra_key* k2 = (struct infra_key*)key2;
94
0
  int r = sockaddr_cmp(&k1->addr, k1->addrlen, &k2->addr, k2->addrlen);
95
0
  if(r != 0)
96
0
    return r;
97
0
  if(k1->namelen != k2->namelen) {
98
0
    if(k1->namelen < k2->namelen)
99
0
      return -1;
100
0
    return 1;
101
0
  }
102
0
  return query_dname_compare(k1->zonename, k2->zonename);
103
0
}
104
105
void 
106
infra_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
107
0
{
108
0
  struct infra_key* key = (struct infra_key*)k;
109
0
  if(!key)
110
0
    return;
111
0
  lock_rw_destroy(&key->entry.lock);
112
0
  free(key->zonename);
113
0
  free(key);
114
0
}
115
116
void 
117
infra_deldatafunc(void* d, void* ATTR_UNUSED(arg))
118
0
{
119
0
  struct infra_data* data = (struct infra_data*)d;
120
0
  free(data);
121
0
}
122
123
size_t 
124
rate_sizefunc(void* k, void* ATTR_UNUSED(d))
125
0
{
126
0
  struct rate_key* key = (struct rate_key*)k;
127
0
  return sizeof(*key) + sizeof(struct rate_data) + key->namelen
128
0
    + lock_get_mem(&key->entry.lock);
129
0
}
130
131
int 
132
rate_compfunc(void* key1, void* key2)
133
0
{
134
0
  struct rate_key* k1 = (struct rate_key*)key1;
135
0
  struct rate_key* k2 = (struct rate_key*)key2;
136
0
  if(k1->namelen != k2->namelen) {
137
0
    if(k1->namelen < k2->namelen)
138
0
      return -1;
139
0
    return 1;
140
0
  }
141
0
  return query_dname_compare(k1->name, k2->name);
142
0
}
143
144
void 
145
rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
146
0
{
147
0
  struct rate_key* key = (struct rate_key*)k;
148
0
  if(!key)
149
0
    return;
150
0
  lock_rw_destroy(&key->entry.lock);
151
0
  free(key->name);
152
0
  free(key);
153
0
}
154
155
void 
156
rate_deldatafunc(void* d, void* ATTR_UNUSED(arg))
157
0
{
158
0
  struct rate_data* data = (struct rate_data*)d;
159
0
  free(data);
160
0
}
161
162
/** find or create element in domainlimit tree */
163
static struct domain_limit_data* domain_limit_findcreate(
164
  struct rbtree_type* domain_limits, char* name)
165
0
{
166
0
  uint8_t* nm;
167
0
  int labs;
168
0
  size_t nmlen;
169
0
  struct domain_limit_data* d;
170
171
  /* parse name */
172
0
  nm = sldns_str2wire_dname(name, &nmlen);
173
0
  if(!nm) {
174
0
    log_err("could not parse %s", name);
175
0
    return NULL;
176
0
  }
177
0
  labs = dname_count_labels(nm);
178
179
  /* can we find it? */
180
0
  d = (struct domain_limit_data*)name_tree_find(domain_limits, nm,
181
0
    nmlen, labs, LDNS_RR_CLASS_IN);
182
0
  if(d) {
183
0
    free(nm);
184
0
    return d;
185
0
  }
186
  
187
  /* create it */
188
0
  d = (struct domain_limit_data*)calloc(1, sizeof(*d));
189
0
  if(!d) {
190
0
    free(nm);
191
0
    return NULL;
192
0
  }
193
0
  d->node.node.key = &d->node;
194
0
  d->node.name = nm;
195
0
  d->node.len = nmlen;
196
0
  d->node.labs = labs;
197
0
  d->node.dclass = LDNS_RR_CLASS_IN;
198
0
  d->lim = -1;
199
0
  d->below = -1;
200
0
  if(!name_tree_insert(domain_limits, &d->node, nm, nmlen, labs,
201
0
    LDNS_RR_CLASS_IN)) {
202
0
    log_err("duplicate element in domainlimit tree");
203
0
    free(nm);
204
0
    free(d);
205
0
    return NULL;
206
0
  }
207
0
  return d;
208
0
}
209
210
/** insert rate limit configuration into lookup tree */
211
static int infra_ratelimit_cfg_insert(struct rbtree_type* domain_limits,
212
  struct config_file* cfg)
213
0
{
214
0
  struct config_str2list* p;
215
0
  struct domain_limit_data* d;
216
0
  for(p = cfg->ratelimit_for_domain; p; p = p->next) {
217
0
    d = domain_limit_findcreate(domain_limits, p->str);
218
0
    if(!d)
219
0
      return 0;
220
0
    d->lim = atoi(p->str2);
221
0
  }
222
0
  for(p = cfg->ratelimit_below_domain; p; p = p->next) {
223
0
    d = domain_limit_findcreate(domain_limits, p->str);
224
0
    if(!d)
225
0
      return 0;
226
0
    d->below = atoi(p->str2);
227
0
  }
228
0
  return 1;
229
0
}
230
231
int
232
setup_domain_limits(struct rbtree_type* domain_limits, struct config_file* cfg)
233
0
{
234
0
  name_tree_init(domain_limits);
235
0
  if(!infra_ratelimit_cfg_insert(domain_limits, cfg)) {
236
0
    return 0;
237
0
  }
238
0
  name_tree_init_parents(domain_limits);
239
0
  return 1;
240
0
}
241
242
/** find or create element in wait limit netblock tree */
243
static struct wait_limit_netblock_info*
244
wait_limit_netblock_findcreate(struct rbtree_type* tree, char* str)
245
0
{
246
0
  struct sockaddr_storage addr;
247
0
  int net;
248
0
  socklen_t addrlen;
249
0
  struct wait_limit_netblock_info* d;
250
251
0
  if(!netblockstrtoaddr(str, 0, &addr, &addrlen, &net)) {
252
0
    log_err("cannot parse wait limit netblock '%s'", str);
253
0
    return 0;
254
0
  }
255
256
  /* can we find it? */
257
0
  d = (struct wait_limit_netblock_info*)addr_tree_find(tree, &addr,
258
0
    addrlen, net);
259
0
  if(d)
260
0
    return d;
261
262
  /* create it */
263
0
  d = (struct wait_limit_netblock_info*)calloc(1, sizeof(*d));
264
0
  if(!d)
265
0
    return NULL;
266
0
  d->limit = -1;
267
0
  if(!addr_tree_insert(tree, &d->node, &addr, addrlen, net)) {
268
0
    log_err("duplicate element in domainlimit tree");
269
0
    free(d);
270
0
    return NULL;
271
0
  }
272
0
  return d;
273
0
}
274
275
276
/** insert wait limit information into lookup tree */
277
static int
278
infra_wait_limit_netblock_insert(rbtree_type* wait_limits_netblock,
279
        rbtree_type* wait_limits_cookie_netblock, struct config_file* cfg)
280
0
{
281
0
  struct config_str2list* p;
282
0
  struct wait_limit_netblock_info* d;
283
0
  for(p = cfg->wait_limit_netblock; p; p = p->next) {
284
0
    d = wait_limit_netblock_findcreate(wait_limits_netblock,
285
0
      p->str);
286
0
    if(!d)
287
0
      return 0;
288
0
    d->limit = atoi(p->str2);
289
0
  }
290
0
  for(p = cfg->wait_limit_cookie_netblock; p; p = p->next) {
291
0
    d = wait_limit_netblock_findcreate(wait_limits_cookie_netblock,
292
0
      p->str);
293
0
    if(!d)
294
0
      return 0;
295
0
    d->limit = atoi(p->str2);
296
0
  }
297
0
  return 1;
298
0
}
299
300
/** Add a default wait limit netblock */
301
static int
302
wait_limit_netblock_default(struct rbtree_type* tree, char* str, int limit)
303
0
{
304
0
  struct wait_limit_netblock_info* d;
305
0
  d = wait_limit_netblock_findcreate(tree, str);
306
0
  if(!d)
307
0
    return 0;
308
0
  d->limit = limit;
309
0
  return 1;
310
0
}
311
312
int
313
setup_wait_limits(rbtree_type* wait_limits_netblock,
314
  rbtree_type* wait_limits_cookie_netblock, struct config_file* cfg)
315
0
{
316
0
  addr_tree_init(wait_limits_netblock);
317
0
  addr_tree_init(wait_limits_cookie_netblock);
318
319
  /* Insert defaults */
320
  /* The loopback address is separated from the rest of the network. */
321
  /* wait-limit-netblock: 127.0.0.0/8 -1 */
322
0
  if(!wait_limit_netblock_default(wait_limits_netblock, "127.0.0.0/8",
323
0
    -1))
324
0
    return 0;
325
  /* wait-limit-netblock: ::1/128 -1 */
326
0
  if(!wait_limit_netblock_default(wait_limits_netblock, "::1/128", -1))
327
0
    return 0;
328
  /* wait-limit-cookie-netblock: 127.0.0.0/8 -1 */
329
0
  if(!wait_limit_netblock_default(wait_limits_cookie_netblock,
330
0
    "127.0.0.0/8", -1))
331
0
    return 0;
332
  /* wait-limit-cookie-netblock: ::1/128 -1 */
333
0
  if(!wait_limit_netblock_default(wait_limits_cookie_netblock,
334
0
    "::1/128", -1))
335
0
    return 0;
336
337
0
  if(!infra_wait_limit_netblock_insert(wait_limits_netblock,
338
0
    wait_limits_cookie_netblock, cfg))
339
0
    return 0;
340
0
  addr_tree_init_parents(wait_limits_netblock);
341
0
  addr_tree_init_parents(wait_limits_cookie_netblock);
342
0
  return 1;
343
0
}
344
345
struct infra_cache* 
346
infra_create(struct config_file* cfg)
347
0
{
348
0
  struct infra_cache* infra = (struct infra_cache*)calloc(1, 
349
0
    sizeof(struct infra_cache));
350
0
  size_t maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
351
0
    sizeof(struct infra_data)+INFRA_BYTES_NAME);
352
0
  if(!infra) {
353
0
    return NULL;
354
0
  }
355
0
  infra->hosts = slabhash_create(cfg->infra_cache_slabs,
356
0
    INFRA_HOST_STARTSIZE, maxmem, &infra_sizefunc, &infra_compfunc,
357
0
    &infra_delkeyfunc, &infra_deldatafunc, NULL);
358
0
  if(!infra->hosts) {
359
0
    free(infra);
360
0
    return NULL;
361
0
  }
362
0
  infra->host_ttl = cfg->host_ttl;
363
0
  infra->infra_keep_probing = cfg->infra_keep_probing;
364
0
  infra_dp_ratelimit = cfg->ratelimit;
365
0
  infra->domain_rates = slabhash_create(cfg->ratelimit_slabs,
366
0
    INFRA_HOST_STARTSIZE, cfg->ratelimit_size,
367
0
    &rate_sizefunc, &rate_compfunc, &rate_delkeyfunc,
368
0
    &rate_deldatafunc, NULL);
369
0
  if(!infra->domain_rates) {
370
0
    infra_delete(infra);
371
0
    return NULL;
372
0
  }
373
  /* insert config data into ratelimits */
374
0
  if(!setup_domain_limits(&infra->domain_limits, cfg)) {
375
0
    infra_delete(infra);
376
0
    return NULL;
377
0
  }
378
0
  if(!setup_wait_limits(&infra->wait_limits_netblock,
379
0
    &infra->wait_limits_cookie_netblock, cfg)) {
380
0
    infra_delete(infra);
381
0
    return NULL;
382
0
  }
383
0
  infra_ip_ratelimit = cfg->ip_ratelimit;
384
0
  infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
385
0
  infra->client_ip_rates = slabhash_create(cfg->ip_ratelimit_slabs,
386
0
      INFRA_HOST_STARTSIZE, cfg->ip_ratelimit_size, &ip_rate_sizefunc,
387
0
      &ip_rate_compfunc, &ip_rate_delkeyfunc, &ip_rate_deldatafunc, NULL);
388
0
  if(!infra->client_ip_rates) {
389
0
    infra_delete(infra);
390
0
    return NULL;
391
0
  }
392
0
  return infra;
393
0
}
394
395
/** delete domain_limit entries */
396
static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg))
397
0
{
398
0
  if(n) {
399
0
    free(((struct domain_limit_data*)n)->node.name);
400
0
    free(n);
401
0
  }
402
0
}
403
404
void
405
domain_limits_free(struct rbtree_type* domain_limits)
406
0
{
407
0
  if(!domain_limits)
408
0
    return;
409
0
  traverse_postorder(domain_limits, domain_limit_free, NULL);
410
0
}
411
412
/** delete wait_limit_netblock_info entries */
413
static void wait_limit_netblock_del(rbnode_type* n, void* ATTR_UNUSED(arg))
414
0
{
415
0
  free(n);
416
0
}
417
418
void
419
wait_limits_free(struct rbtree_type* wait_limits_tree)
420
0
{
421
0
  if(!wait_limits_tree)
422
0
    return;
423
0
  traverse_postorder(wait_limits_tree, wait_limit_netblock_del,
424
0
    NULL);
425
0
}
426
427
void 
428
infra_delete(struct infra_cache* infra)
429
0
{
430
0
  if(!infra)
431
0
    return;
432
0
  slabhash_delete(infra->hosts);
433
0
  slabhash_delete(infra->domain_rates);
434
0
  domain_limits_free(&infra->domain_limits);
435
0
  slabhash_delete(infra->client_ip_rates);
436
0
  wait_limits_free(&infra->wait_limits_netblock);
437
0
  wait_limits_free(&infra->wait_limits_cookie_netblock);
438
0
  free(infra);
439
0
}
440
441
struct infra_cache* 
442
infra_adjust(struct infra_cache* infra, struct config_file* cfg)
443
0
{
444
0
  size_t maxmem;
445
0
  if(!infra)
446
0
    return infra_create(cfg);
447
0
  infra->host_ttl = cfg->host_ttl;
448
0
  infra->infra_keep_probing = cfg->infra_keep_probing;
449
0
  infra_dp_ratelimit = cfg->ratelimit;
450
0
  infra_ip_ratelimit = cfg->ip_ratelimit;
451
0
  infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie;
452
0
  maxmem = cfg->infra_cache_numhosts * (sizeof(struct infra_key)+
453
0
    sizeof(struct infra_data)+INFRA_BYTES_NAME);
454
  /* divide cachesize by slabs and multiply by slabs, because if the
455
   * cachesize is not an even multiple of slabs, that is the resulting
456
   * size of the slabhash */
457
0
  if(!slabhash_is_size(infra->hosts, maxmem, cfg->infra_cache_slabs) ||
458
0
     !slabhash_is_size(infra->domain_rates, cfg->ratelimit_size,
459
0
      cfg->ratelimit_slabs) ||
460
0
     !slabhash_is_size(infra->client_ip_rates, cfg->ip_ratelimit_size,
461
0
      cfg->ip_ratelimit_slabs)) {
462
0
    infra_delete(infra);
463
0
    infra = infra_create(cfg);
464
0
  } else {
465
    /* reapply domain limits */
466
0
    traverse_postorder(&infra->domain_limits, domain_limit_free,
467
0
      NULL);
468
0
    if(!setup_domain_limits(&infra->domain_limits, cfg)) {
469
0
      infra_delete(infra);
470
0
      return NULL;
471
0
    }
472
0
  }
473
0
  return infra;
474
0
}
475
476
/** calculate the hash value for a host key
477
 *  set use_port to a non-0 number to use the port in
478
 *  the hash calculation; 0 to ignore the port.*/
479
static hashvalue_type
480
hash_addr(struct sockaddr_storage* addr, socklen_t addrlen,
481
  int use_port)
482
0
{
483
0
  hashvalue_type h = 0xab;
484
  /* select the pieces to hash, some OS have changing data inside */
485
0
  if(addr_is_ip6(addr, addrlen)) {
486
0
    struct sockaddr_in6* in6 = (struct sockaddr_in6*)addr;
487
0
    h = hashlittle(&in6->sin6_family, sizeof(in6->sin6_family), h);
488
0
    if(use_port){
489
0
      h = hashlittle(&in6->sin6_port, sizeof(in6->sin6_port), h);
490
0
    }
491
0
    h = hashlittle(&in6->sin6_addr, INET6_SIZE, h);
492
0
  } else {
493
0
    struct sockaddr_in* in = (struct sockaddr_in*)addr;
494
0
    h = hashlittle(&in->sin_family, sizeof(in->sin_family), h);
495
0
    if(use_port){
496
0
      h = hashlittle(&in->sin_port, sizeof(in->sin_port), h);
497
0
    }
498
0
    h = hashlittle(&in->sin_addr, INET_SIZE, h);
499
0
  }
500
0
  return h;
501
0
}
502
503
/** calculate infra hash for a key */
504
static hashvalue_type
505
hash_infra(struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name)
506
0
{
507
0
  return dname_query_hash(name, hash_addr(addr, addrlen, 1));
508
0
}
509
510
/** lookup version that does not check host ttl (you check it) */
511
struct lruhash_entry* 
512
infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr,
513
  socklen_t addrlen, uint8_t* name, size_t namelen, int wr)
514
0
{
515
0
  struct infra_key k;
516
0
  k.addrlen = addrlen;
517
0
  memcpy(&k.addr, addr, addrlen);
518
0
  k.namelen = namelen;
519
0
  k.zonename = name;
520
0
  k.entry.hash = hash_infra(addr, addrlen, name);
521
0
  k.entry.key = (void*)&k;
522
0
  k.entry.data = NULL;
523
0
  return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr);
524
0
}
525
526
/** init the data elements */
527
static void
528
data_entry_init(struct infra_cache* infra, struct lruhash_entry* e, 
529
  time_t timenow)
530
0
{
531
0
  struct infra_data* data = (struct infra_data*)e->data;
532
0
  data->ttl = timenow + infra->host_ttl;
533
0
  rtt_init(&data->rtt);
534
0
  data->edns_version = 0;
535
0
  data->edns_lame_known = 0;
536
0
  data->probedelay = 0;
537
0
  data->isdnsseclame = 0;
538
0
  data->rec_lame = 0;
539
0
  data->lame_type_A = 0;
540
0
  data->lame_other = 0;
541
0
  data->timeout_A = 0;
542
0
  data->timeout_AAAA = 0;
543
0
  data->timeout_other = 0;
544
0
}
545
546
/** 
547
 * Create and init a new entry for a host 
548
 * @param infra: infra structure with config parameters.
549
 * @param addr: host address.
550
 * @param addrlen: length of addr.
551
 * @param name: name of zone
552
 * @param namelen: length of name.
553
 * @param tm: time now.
554
 * @return: the new entry or NULL on malloc failure.
555
 */
556
static struct lruhash_entry*
557
new_entry(struct infra_cache* infra, struct sockaddr_storage* addr, 
558
  socklen_t addrlen, uint8_t* name, size_t namelen, time_t tm)
559
0
{
560
0
  struct infra_data* data;
561
0
  struct infra_key* key = (struct infra_key*)malloc(sizeof(*key));
562
0
  if(!key)
563
0
    return NULL;
564
0
  data = (struct infra_data*)malloc(sizeof(struct infra_data));
565
0
  if(!data) {
566
0
    free(key);
567
0
    return NULL;
568
0
  }
569
0
  key->zonename = memdup(name, namelen);
570
0
  if(!key->zonename) {
571
0
    free(key);
572
0
    free(data);
573
0
    return NULL;
574
0
  }
575
0
  key->namelen = namelen;
576
0
  lock_rw_init(&key->entry.lock);
577
0
  key->entry.hash = hash_infra(addr, addrlen, name);
578
0
  key->entry.key = (void*)key;
579
0
  key->entry.data = (void*)data;
580
0
  key->addrlen = addrlen;
581
0
  memcpy(&key->addr, addr, addrlen);
582
0
  data_entry_init(infra, &key->entry, tm);
583
0
  return &key->entry;
584
0
}
585
586
int 
587
infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
588
        socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow,
589
  int* edns_vs, uint8_t* edns_lame_known, int* to)
590
0
{
591
0
  struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
592
0
    nm, nmlen, 0);
593
0
  struct infra_data* data;
594
0
  int wr = 0;
595
0
  if(e && ((struct infra_data*)e->data)->ttl < timenow) {
596
    /* it expired, try to reuse existing entry */
597
0
    int old = ((struct infra_data*)e->data)->rtt.rto;
598
0
    time_t tprobe = ((struct infra_data*)e->data)->probedelay;
599
0
    uint8_t tA = ((struct infra_data*)e->data)->timeout_A;
600
0
    uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA;
601
0
    uint8_t tother = ((struct infra_data*)e->data)->timeout_other;
602
0
    lock_rw_unlock(&e->lock);
603
0
    e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
604
0
    if(e) {
605
      /* if its still there we have a writelock, init */
606
      /* re-initialise */
607
      /* do not touch lameness, it may be valid still */
608
0
      data_entry_init(infra, e, timenow);
609
0
      wr = 1;
610
      /* TOP_TIMEOUT remains on reuse */
611
0
      if(old >= USEFUL_SERVER_TOP_TIMEOUT) {
612
0
        ((struct infra_data*)e->data)->rtt.rto
613
0
          = USEFUL_SERVER_TOP_TIMEOUT;
614
0
        ((struct infra_data*)e->data)->probedelay = tprobe;
615
0
        ((struct infra_data*)e->data)->timeout_A = tA;
616
0
        ((struct infra_data*)e->data)->timeout_AAAA = tAAAA;
617
0
        ((struct infra_data*)e->data)->timeout_other = tother;
618
0
      }
619
0
    }
620
0
  }
621
0
  if(!e) {
622
    /* insert new entry */
623
0
    if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
624
0
      return 0;
625
0
    data = (struct infra_data*)e->data;
626
0
    *edns_vs = data->edns_version;
627
0
    *edns_lame_known = data->edns_lame_known;
628
0
    *to = rtt_timeout(&data->rtt);
629
0
    slabhash_insert(infra->hosts, e->hash, e, data, NULL);
630
0
    return 1;
631
0
  }
632
  /* use existing entry */
633
0
  data = (struct infra_data*)e->data;
634
0
  *edns_vs = data->edns_version;
635
0
  *edns_lame_known = data->edns_lame_known;
636
0
  *to = rtt_timeout(&data->rtt);
637
0
  if(*to >= PROBE_MAXRTO && (infra->infra_keep_probing ||
638
0
    rtt_notimeout(&data->rtt)*4 <= *to)) {
639
    /* delay other queries, this is the probe query */
640
0
    if(!wr) {
641
0
      lock_rw_unlock(&e->lock);
642
0
      e = infra_lookup_nottl(infra, addr,addrlen,nm,nmlen, 1);
643
0
      if(!e) { /* flushed from cache real fast, no use to
644
        allocate just for the probedelay */
645
0
        return 1;
646
0
      }
647
0
      data = (struct infra_data*)e->data;
648
0
    }
649
    /* add 999 to round up the timeout value from msec to sec,
650
     * then add a whole second so it is certain that this probe
651
     * has timed out before the next is allowed */
652
0
    data->probedelay = timenow + ((*to)+1999)/1000;
653
0
  }
654
0
  lock_rw_unlock(&e->lock);
655
0
  return 1;
656
0
}
657
658
int 
659
infra_set_lame(struct infra_cache* infra, struct sockaddr_storage* addr,
660
  socklen_t addrlen, uint8_t* nm, size_t nmlen, time_t timenow,
661
  int dnsseclame, int reclame, uint16_t qtype)
662
0
{
663
0
  struct infra_data* data;
664
0
  struct lruhash_entry* e;
665
0
  int needtoinsert = 0;
666
0
  e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1);
667
0
  if(!e) {
668
    /* insert it */
669
0
    if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) {
670
0
      log_err("set_lame: malloc failure");
671
0
      return 0;
672
0
    }
673
0
    needtoinsert = 1;
674
0
  } else if( ((struct infra_data*)e->data)->ttl < timenow) {
675
    /* expired, reuse existing entry */
676
0
    data_entry_init(infra, e, timenow);
677
0
  }
678
  /* got an entry, now set the zone lame */
679
0
  data = (struct infra_data*)e->data;
680
  /* merge data (if any) */
681
0
  if(dnsseclame)
682
0
    data->isdnsseclame = 1;
683
0
  if(reclame)
684
0
    data->rec_lame = 1;
685
0
  if(!dnsseclame && !reclame && qtype == LDNS_RR_TYPE_A)
686
0
    data->lame_type_A = 1;
687
0
  if(!dnsseclame  && !reclame && qtype != LDNS_RR_TYPE_A)
688
0
    data->lame_other = 1;
689
  /* done */
690
0
  if(needtoinsert)
691
0
    slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
692
0
  else  { lock_rw_unlock(&e->lock); }
693
0
  return 1;
694
0
}
695
696
void 
697
infra_update_tcp_works(struct infra_cache* infra,
698
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
699
  size_t nmlen)
700
0
{
701
0
  struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
702
0
    nm, nmlen, 1);
703
0
  struct infra_data* data;
704
0
  if(!e)
705
0
    return; /* doesn't exist */
706
0
  data = (struct infra_data*)e->data;
707
0
  if(data->rtt.rto >= RTT_MAX_TIMEOUT)
708
    /* do not disqualify this server altogether, it is better
709
     * than nothing */
710
0
    data->rtt.rto = still_useful_timeout();
711
0
  lock_rw_unlock(&e->lock);
712
0
}
713
714
int 
715
infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr,
716
  socklen_t addrlen, uint8_t* nm, size_t nmlen, int qtype,
717
  int roundtrip, int orig_rtt, time_t timenow)
718
0
{
719
0
  struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
720
0
    nm, nmlen, 1);
721
0
  struct infra_data* data;
722
0
  int needtoinsert = 0, expired = 0;
723
0
  int rto = 1;
724
0
  time_t oldprobedelay = 0;
725
0
  if(!e) {
726
0
    if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
727
0
      return 0;
728
0
    needtoinsert = 1;
729
0
  } else if(((struct infra_data*)e->data)->ttl < timenow) {
730
0
    oldprobedelay = ((struct infra_data*)e->data)->probedelay;
731
0
    data_entry_init(infra, e, timenow);
732
0
    expired = 1;
733
0
  }
734
  /* have an entry, update the rtt */
735
0
  data = (struct infra_data*)e->data;
736
0
  if(roundtrip == -1) {
737
0
    if(needtoinsert || expired) {
738
      /* timeout on entry that has expired before the timer
739
       * keep old timeout from the function caller */
740
0
      data->rtt.rto = orig_rtt;
741
0
      data->probedelay = oldprobedelay;
742
0
    }
743
0
    rtt_lost(&data->rtt, orig_rtt);
744
0
    if(qtype == LDNS_RR_TYPE_A) {
745
0
      if(data->timeout_A < TIMEOUT_COUNT_MAX)
746
0
        data->timeout_A++;
747
0
    } else if(qtype == LDNS_RR_TYPE_AAAA) {
748
0
      if(data->timeout_AAAA < TIMEOUT_COUNT_MAX)
749
0
        data->timeout_AAAA++;
750
0
    } else {
751
0
      if(data->timeout_other < TIMEOUT_COUNT_MAX)
752
0
        data->timeout_other++;
753
0
    }
754
0
  } else {
755
    /* if we got a reply, but the old timeout was above server
756
     * selection height, delete the timeout so the server is
757
     * fully available again */
758
0
    if(rtt_unclamped(&data->rtt) >= USEFUL_SERVER_TOP_TIMEOUT)
759
0
      rtt_init(&data->rtt);
760
0
    rtt_update(&data->rtt, roundtrip);
761
0
    data->probedelay = 0;
762
0
    if(qtype == LDNS_RR_TYPE_A)
763
0
      data->timeout_A = 0;
764
0
    else if(qtype == LDNS_RR_TYPE_AAAA)
765
0
      data->timeout_AAAA = 0;
766
0
    else  data->timeout_other = 0;
767
0
  }
768
0
  if(data->rtt.rto > 0)
769
0
    rto = data->rtt.rto;
770
771
0
  if(needtoinsert)
772
0
    slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
773
0
  else  { lock_rw_unlock(&e->lock); }
774
0
  return rto;
775
0
}
776
777
long long infra_get_host_rto(struct infra_cache* infra,
778
        struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm,
779
  size_t nmlen, struct rtt_info* rtt, int* delay, time_t timenow,
780
  int* tA, int* tAAAA, int* tother)
781
0
{
782
0
  struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
783
0
    nm, nmlen, 0);
784
0
  struct infra_data* data;
785
0
  long long ttl = -2;
786
0
  if(!e) return -1;
787
0
  data = (struct infra_data*)e->data;
788
0
  if(data->ttl >= timenow) {
789
0
    ttl = (long long)(data->ttl - timenow);
790
0
    memmove(rtt, &data->rtt, sizeof(*rtt));
791
0
    if(timenow < data->probedelay)
792
0
      *delay = (int)(data->probedelay - timenow);
793
0
    else  *delay = 0;
794
0
  }
795
0
  *tA = (int)data->timeout_A;
796
0
  *tAAAA = (int)data->timeout_AAAA;
797
0
  *tother = (int)data->timeout_other;
798
0
  lock_rw_unlock(&e->lock);
799
0
  return ttl;
800
0
}
801
802
int 
803
infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr,
804
  socklen_t addrlen, uint8_t* nm, size_t nmlen, int edns_version,
805
  time_t timenow)
806
0
{
807
0
  struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
808
0
    nm, nmlen, 1);
809
0
  struct infra_data* data;
810
0
  int needtoinsert = 0;
811
0
  if(!e) {
812
0
    if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow)))
813
0
      return 0;
814
0
    needtoinsert = 1;
815
0
  } else if(((struct infra_data*)e->data)->ttl < timenow) {
816
0
    data_entry_init(infra, e, timenow);
817
0
  }
818
  /* have an entry, update the rtt, and the ttl */
819
0
  data = (struct infra_data*)e->data;
820
  /* do not update if noEDNS and stored is yesEDNS */
821
0
  if(!(edns_version == -1 && (data->edns_version != -1 &&
822
0
    data->edns_lame_known))) {
823
0
    data->edns_version = edns_version;
824
0
    data->edns_lame_known = 1;
825
0
  }
826
827
0
  if(needtoinsert)
828
0
    slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
829
0
  else  { lock_rw_unlock(&e->lock); }
830
0
  return 1;
831
0
}
832
833
int
834
infra_get_lame_rtt(struct infra_cache* infra,
835
        struct sockaddr_storage* addr, socklen_t addrlen,
836
        uint8_t* name, size_t namelen, uint16_t qtype, 
837
  int* lame, int* dnsseclame, int* reclame, int* rtt, time_t timenow)
838
0
{
839
0
  struct infra_data* host;
840
0
  struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
841
0
    name, namelen, 0);
842
0
  if(!e) 
843
0
    return 0;
844
0
  host = (struct infra_data*)e->data;
845
0
  *rtt = rtt_unclamped(&host->rtt);
846
0
  if(host->rtt.rto >= PROBE_MAXRTO && timenow >= host->probedelay
847
0
    && infra->infra_keep_probing) {
848
    /* single probe, keep probing */
849
0
    if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT)
850
0
      *rtt = still_useful_timeout();
851
0
  } else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay
852
0
    && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) {
853
    /* single probe for this domain, and we are not probing */
854
    /* unless the query type allows a probe to happen */
855
0
    if(qtype == LDNS_RR_TYPE_A) {
856
0
      if(host->timeout_A >= TIMEOUT_COUNT_MAX)
857
0
        *rtt = USEFUL_SERVER_TOP_TIMEOUT;
858
0
      else  *rtt = still_useful_timeout();
859
0
    } else if(qtype == LDNS_RR_TYPE_AAAA) {
860
0
      if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX)
861
0
        *rtt = USEFUL_SERVER_TOP_TIMEOUT;
862
0
      else  *rtt = still_useful_timeout();
863
0
    } else {
864
0
      if(host->timeout_other >= TIMEOUT_COUNT_MAX)
865
0
        *rtt = USEFUL_SERVER_TOP_TIMEOUT;
866
0
      else  *rtt = still_useful_timeout();
867
0
    }
868
0
  }
869
  /* expired entry */
870
0
  if(timenow > host->ttl) {
871
    /* see if this can be a re-probe of an unresponsive server */
872
0
    if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) {
873
0
      lock_rw_unlock(&e->lock);
874
0
      *rtt = still_useful_timeout();
875
0
      *lame = 0;
876
0
      *dnsseclame = 0;
877
0
      *reclame = 0;
878
0
      return 1;
879
0
    }
880
0
    lock_rw_unlock(&e->lock);
881
0
    return 0;
882
0
  }
883
  /* check lameness first */
884
0
  if(host->lame_type_A && qtype == LDNS_RR_TYPE_A) {
885
0
    lock_rw_unlock(&e->lock);
886
0
    *lame = 1;
887
0
    *dnsseclame = 0;
888
0
    *reclame = 0;
889
0
    return 1;
890
0
  } else if(host->lame_other && qtype != LDNS_RR_TYPE_A) {
891
0
    lock_rw_unlock(&e->lock);
892
0
    *lame = 1;
893
0
    *dnsseclame = 0;
894
0
    *reclame = 0;
895
0
    return 1;
896
0
  } else if(host->isdnsseclame) {
897
0
    lock_rw_unlock(&e->lock);
898
0
    *lame = 0;
899
0
    *dnsseclame = 1;
900
0
    *reclame = 0;
901
0
    return 1;
902
0
  } else if(host->rec_lame) {
903
0
    lock_rw_unlock(&e->lock);
904
0
    *lame = 0;
905
0
    *dnsseclame = 0;
906
0
    *reclame = 1;
907
0
    return 1;
908
0
  }
909
  /* no lameness for this type of query */
910
0
  lock_rw_unlock(&e->lock);
911
0
  *lame = 0;
912
0
  *dnsseclame = 0;
913
0
  *reclame = 0;
914
0
  return 1;
915
0
}
916
917
int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name,
918
  size_t namelen)
919
0
{
920
0
  int labs = dname_count_labels(name);
921
0
  struct domain_limit_data* d = (struct domain_limit_data*)
922
0
    name_tree_lookup(&infra->domain_limits, name, namelen, labs,
923
0
    LDNS_RR_CLASS_IN);
924
0
  if(!d) return infra_dp_ratelimit;
925
926
0
  if(d->node.labs == labs && d->lim != -1)
927
0
    return d->lim; /* exact match */
928
929
  /* find 'below match' */
930
0
  if(d->node.labs == labs)
931
0
    d = (struct domain_limit_data*)d->node.parent;
932
0
  while(d) {
933
0
    if(d->below != -1)
934
0
      return d->below;
935
0
    d = (struct domain_limit_data*)d->node.parent;
936
0
  }
937
0
  return infra_dp_ratelimit;
938
0
}
939
940
size_t ip_rate_sizefunc(void* k, void* ATTR_UNUSED(d))
941
0
{
942
0
  struct ip_rate_key* key = (struct ip_rate_key*)k;
943
0
  return sizeof(*key) + sizeof(struct ip_rate_data)
944
0
    + lock_get_mem(&key->entry.lock);
945
0
}
946
947
int ip_rate_compfunc(void* key1, void* key2)
948
0
{
949
0
  struct ip_rate_key* k1 = (struct ip_rate_key*)key1;
950
0
  struct ip_rate_key* k2 = (struct ip_rate_key*)key2;
951
0
  return sockaddr_cmp_addr(&k1->addr, k1->addrlen,
952
0
    &k2->addr, k2->addrlen);
953
0
}
954
955
void ip_rate_delkeyfunc(void* k, void* ATTR_UNUSED(arg))
956
0
{
957
0
  struct ip_rate_key* key = (struct ip_rate_key*)k;
958
0
  if(!key)
959
0
    return;
960
0
  lock_rw_destroy(&key->entry.lock);
961
0
  free(key);
962
0
}
963
964
/** find data item in array, for write access, caller unlocks */
965
static struct lruhash_entry* infra_find_ratedata(struct infra_cache* infra,
966
  uint8_t* name, size_t namelen, int wr)
967
0
{
968
0
  struct rate_key key;
969
0
  hashvalue_type h = dname_query_hash(name, 0xab);
970
0
  memset(&key, 0, sizeof(key));
971
0
  key.name = name;
972
0
  key.namelen = namelen;
973
0
  key.entry.hash = h;
974
0
  return slabhash_lookup(infra->domain_rates, h, &key, wr);
975
0
}
976
977
/** find data item in array for ip addresses */
978
static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
979
  struct sockaddr_storage* addr, socklen_t addrlen, int wr)
980
0
{
981
0
  struct ip_rate_key key;
982
0
  hashvalue_type h = hash_addr(addr, addrlen, 0);
983
0
  memset(&key, 0, sizeof(key));
984
0
  key.addr = *addr;
985
0
  key.addrlen = addrlen;
986
0
  key.entry.hash = h;
987
0
  return slabhash_lookup(infra->client_ip_rates, h, &key, wr);
988
0
}
989
990
/** create rate data item for name, number 1 in now */
991
static void infra_create_ratedata(struct infra_cache* infra,
992
  uint8_t* name, size_t namelen, time_t timenow)
993
0
{
994
0
  hashvalue_type h = dname_query_hash(name, 0xab);
995
0
  struct rate_key* k = (struct rate_key*)calloc(1, sizeof(*k));
996
0
  struct rate_data* d = (struct rate_data*)calloc(1, sizeof(*d));
997
0
  if(!k || !d) {
998
0
    free(k);
999
0
    free(d);
1000
0
    return; /* alloc failure */
1001
0
  }
1002
0
  k->namelen = namelen;
1003
0
  k->name = memdup(name, namelen);
1004
0
  if(!k->name) {
1005
0
    free(k);
1006
0
    free(d);
1007
0
    return; /* alloc failure */
1008
0
  }
1009
0
  lock_rw_init(&k->entry.lock);
1010
0
  k->entry.hash = h;
1011
0
  k->entry.key = k;
1012
0
  k->entry.data = d;
1013
0
  d->qps[0] = 1;
1014
0
  d->timestamp[0] = timenow;
1015
0
  slabhash_insert(infra->domain_rates, h, &k->entry, d, NULL);
1016
0
}
1017
1018
/** create rate data item for ip address */
1019
static void infra_ip_create_ratedata(struct infra_cache* infra,
1020
  struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
1021
  int mesh_wait)
1022
0
{
1023
0
  hashvalue_type h = hash_addr(addr, addrlen, 0);
1024
0
  struct ip_rate_key* k = (struct ip_rate_key*)calloc(1, sizeof(*k));
1025
0
  struct ip_rate_data* d = (struct ip_rate_data*)calloc(1, sizeof(*d));
1026
0
  if(!k || !d) {
1027
0
    free(k);
1028
0
    free(d);
1029
0
    return; /* alloc failure */
1030
0
  }
1031
0
  k->addr = *addr;
1032
0
  k->addrlen = addrlen;
1033
0
  lock_rw_init(&k->entry.lock);
1034
0
  k->entry.hash = h;
1035
0
  k->entry.key = k;
1036
0
  k->entry.data = d;
1037
0
  d->qps[0] = 1;
1038
0
  d->timestamp[0] = timenow;
1039
0
  d->mesh_wait = mesh_wait;
1040
0
  slabhash_insert(infra->client_ip_rates, h, &k->entry, d, NULL);
1041
0
}
1042
1043
/** Find the second and return its rate counter. If none and should_add, remove
1044
 *  oldest to accommodate. Else return none. */
1045
static int* infra_rate_find_second_or_none(void* data, time_t t, int should_add)
1046
0
{
1047
0
  struct rate_data* d = (struct rate_data*)data;
1048
0
  int i, oldest;
1049
0
  for(i=0; i<RATE_WINDOW; i++) {
1050
0
    if(d->timestamp[i] == t)
1051
0
      return &(d->qps[i]);
1052
0
  }
1053
0
  if(!should_add) return NULL;
1054
  /* remove oldest timestamp, and insert it at t with 0 qps */
1055
0
  oldest = 0;
1056
0
  for(i=0; i<RATE_WINDOW; i++) {
1057
0
    if(d->timestamp[i] < d->timestamp[oldest])
1058
0
      oldest = i;
1059
0
  }
1060
0
  d->timestamp[oldest] = t;
1061
0
  d->qps[oldest] = 0;
1062
0
  return &(d->qps[oldest]);
1063
0
}
1064
1065
/** find the second and return its rate counter, if none, remove oldest to
1066
 *  accommodate */
1067
static int* infra_rate_give_second(void* data, time_t t)
1068
0
{
1069
0
    return infra_rate_find_second_or_none(data, t, 1);
1070
0
}
1071
1072
/** find the second and return its rate counter only if it exists. Caller
1073
 *  should check for NULL return value */
1074
static int* infra_rate_get_second(void* data, time_t t)
1075
0
{
1076
0
    return infra_rate_find_second_or_none(data, t, 0);
1077
0
}
1078
1079
int infra_rate_max(void* data, time_t now, int backoff)
1080
0
{
1081
0
  struct rate_data* d = (struct rate_data*)data;
1082
0
  int i, max = 0;
1083
0
  for(i=0; i<RATE_WINDOW; i++) {
1084
0
    if(backoff) {
1085
0
      if(now-d->timestamp[i] <= RATE_WINDOW &&
1086
0
        d->qps[i] > max) {
1087
0
        max = d->qps[i];
1088
0
      }
1089
0
    } else {
1090
0
      if(now == d->timestamp[i]) {
1091
0
        return d->qps[i];
1092
0
      }
1093
0
    }
1094
0
  }
1095
0
  return max;
1096
0
}
1097
1098
int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name,
1099
  size_t namelen, time_t timenow, int backoff, struct query_info* qinfo,
1100
  struct comm_reply* replylist)
1101
0
{
1102
0
  int lim, max;
1103
0
  struct lruhash_entry* entry;
1104
1105
0
  if(!infra_dp_ratelimit)
1106
0
    return 1; /* not enabled */
1107
1108
  /* find ratelimit */
1109
0
  lim = infra_find_ratelimit(infra, name, namelen);
1110
0
  if(!lim)
1111
0
    return 1; /* disabled for this domain */
1112
  
1113
  /* find or insert ratedata */
1114
0
  entry = infra_find_ratedata(infra, name, namelen, 1);
1115
0
  if(entry) {
1116
0
    int premax = infra_rate_max(entry->data, timenow, backoff);
1117
0
    int* cur = infra_rate_give_second(entry->data, timenow);
1118
0
    (*cur)++;
1119
0
    max = infra_rate_max(entry->data, timenow, backoff);
1120
0
    lock_rw_unlock(&entry->lock);
1121
1122
0
    if(premax <= lim && max > lim) {
1123
0
      char buf[LDNS_MAX_DOMAINLEN], qnm[LDNS_MAX_DOMAINLEN];
1124
0
      char ts[12], cs[12], ip[128];
1125
0
      dname_str(name, buf);
1126
0
      dname_str(qinfo->qname, qnm);
1127
0
      sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts));
1128
0
      sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs));
1129
0
      ip[0]=0;
1130
0
      if(replylist) {
1131
0
        addr_to_str((struct sockaddr_storage *)&replylist->remote_addr,
1132
0
          replylist->remote_addrlen, ip, sizeof(ip));
1133
0
        verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip);
1134
0
      } else {
1135
0
        verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts);
1136
0
      }
1137
0
    }
1138
0
    return (max <= lim);
1139
0
  }
1140
1141
  /* create */
1142
0
  infra_create_ratedata(infra, name, namelen, timenow);
1143
0
  return (1 <= lim);
1144
0
}
1145
1146
void infra_ratelimit_dec(struct infra_cache* infra, uint8_t* name,
1147
  size_t namelen, time_t timenow)
1148
0
{
1149
0
  struct lruhash_entry* entry;
1150
0
  int* cur;
1151
0
  if(!infra_dp_ratelimit)
1152
0
    return; /* not enabled */
1153
0
  entry = infra_find_ratedata(infra, name, namelen, 1);
1154
0
  if(!entry) return; /* not cached */
1155
0
  cur = infra_rate_get_second(entry->data, timenow);
1156
0
  if(cur == NULL) {
1157
    /* our timenow is not available anymore; nothing to decrease */
1158
0
    lock_rw_unlock(&entry->lock);
1159
0
    return;
1160
0
  }
1161
0
  if((*cur) > 0)
1162
0
    (*cur)--;
1163
0
  lock_rw_unlock(&entry->lock);
1164
0
}
1165
1166
int infra_ratelimit_exceeded(struct infra_cache* infra, uint8_t* name,
1167
  size_t namelen, time_t timenow, int backoff)
1168
0
{
1169
0
  struct lruhash_entry* entry;
1170
0
  int lim, max;
1171
0
  if(!infra_dp_ratelimit)
1172
0
    return 0; /* not enabled */
1173
1174
  /* find ratelimit */
1175
0
  lim = infra_find_ratelimit(infra, name, namelen);
1176
0
  if(!lim)
1177
0
    return 0; /* disabled for this domain */
1178
1179
  /* find current rate */
1180
0
  entry = infra_find_ratedata(infra, name, namelen, 0);
1181
0
  if(!entry)
1182
0
    return 0; /* not cached */
1183
0
  max = infra_rate_max(entry->data, timenow, backoff);
1184
0
  lock_rw_unlock(&entry->lock);
1185
1186
0
  return (max > lim);
1187
0
}
1188
1189
size_t 
1190
infra_get_mem(struct infra_cache* infra)
1191
0
{
1192
0
  size_t s = sizeof(*infra) + slabhash_get_mem(infra->hosts);
1193
0
  if(infra->domain_rates) s += slabhash_get_mem(infra->domain_rates);
1194
0
  if(infra->client_ip_rates) s += slabhash_get_mem(infra->client_ip_rates);
1195
  /* ignore domain_limits because walk through tree is big */
1196
0
  return s;
1197
0
}
1198
1199
/* Returns 1 if the limit has not been exceeded, 0 otherwise. */
1200
static int
1201
check_ip_ratelimit(struct sockaddr_storage* addr, socklen_t addrlen,
1202
  struct sldns_buffer* buffer, int premax, int max, int has_cookie)
1203
0
{
1204
0
  int limit;
1205
1206
0
  if(has_cookie) limit = infra_ip_ratelimit_cookie;
1207
0
  else           limit = infra_ip_ratelimit;
1208
1209
  /* Disabled */
1210
0
  if(limit == 0) return 1;
1211
1212
0
  if(premax <= limit && max > limit) {
1213
0
    char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12];
1214
0
    addr_to_str(addr, addrlen, client_ip, sizeof(client_ip));
1215
0
    qnm[0]=0;
1216
0
    if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE &&
1217
0
      LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) {
1218
0
      (void)sldns_wire2str_rrquestion_buf(
1219
0
        sldns_buffer_at(buffer, LDNS_HEADER_SIZE),
1220
0
        sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE,
1221
0
        qnm, sizeof(qnm));
1222
0
      if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n')
1223
0
        qnm[strlen(qnm)-1] = 0; /*remove newline*/
1224
0
      if(strchr(qnm, '\t'))
1225
0
        *strchr(qnm, '\t') = ' ';
1226
0
      if(strchr(qnm, '\t'))
1227
0
        *strchr(qnm, '\t') = ' ';
1228
0
      verbose(VERB_OPS, "ip_ratelimit exceeded %s %d%s %s",
1229
0
        client_ip, limit,
1230
0
        has_cookie?"(cookie)":"", qnm);
1231
0
    } else {
1232
0
      verbose(VERB_OPS, "ip_ratelimit exceeded %s %d%s (no query name)",
1233
0
        client_ip, limit,
1234
0
        has_cookie?"(cookie)":"");
1235
0
    }
1236
0
  }
1237
0
  return (max <= limit);
1238
0
}
1239
1240
int infra_ip_ratelimit_inc(struct infra_cache* infra,
1241
  struct sockaddr_storage* addr, socklen_t addrlen, time_t timenow,
1242
  int has_cookie, int backoff, struct sldns_buffer* buffer)
1243
0
{
1244
0
  int max;
1245
0
  struct lruhash_entry* entry;
1246
1247
  /* not enabled */
1248
0
  if(!infra_ip_ratelimit) {
1249
0
    return 1;
1250
0
  }
1251
  /* find or insert ratedata */
1252
0
  entry = infra_find_ip_ratedata(infra, addr, addrlen, 1);
1253
0
  if(entry) {
1254
0
    int premax = infra_rate_max(entry->data, timenow, backoff);
1255
0
    int* cur = infra_rate_give_second(entry->data, timenow);
1256
0
    (*cur)++;
1257
0
    max = infra_rate_max(entry->data, timenow, backoff);
1258
0
    lock_rw_unlock(&entry->lock);
1259
0
    return check_ip_ratelimit(addr, addrlen, buffer, premax, max,
1260
0
      has_cookie);
1261
0
  }
1262
1263
  /* create */
1264
0
  infra_ip_create_ratedata(infra, addr, addrlen, timenow, 0);
1265
0
  return 1;
1266
0
}
1267
1268
int infra_wait_limit_allowed(struct infra_cache* infra, struct comm_reply* rep,
1269
  int cookie_valid, struct config_file* cfg)
1270
0
{
1271
0
  struct lruhash_entry* entry;
1272
0
  if(cfg->wait_limit == 0)
1273
0
    return 1;
1274
1275
0
  entry = infra_find_ip_ratedata(infra, &rep->client_addr,
1276
0
    rep->client_addrlen, 0);
1277
0
  if(entry) {
1278
0
    rbtree_type* tree;
1279
0
    struct wait_limit_netblock_info* w;
1280
0
    struct rate_data* d = (struct rate_data*)entry->data;
1281
0
    int mesh_wait = d->mesh_wait;
1282
0
    lock_rw_unlock(&entry->lock);
1283
1284
    /* have the wait amount, check how much is allowed */
1285
0
    if(cookie_valid)
1286
0
      tree = &infra->wait_limits_cookie_netblock;
1287
0
    else  tree = &infra->wait_limits_netblock;
1288
0
    w = (struct wait_limit_netblock_info*)addr_tree_lookup(tree,
1289
0
      &rep->client_addr, rep->client_addrlen);
1290
0
    if(w) {
1291
0
      if(w->limit != -1 && mesh_wait > w->limit)
1292
0
        return 0;
1293
0
    } else {
1294
      /* if there is no IP netblock specific information,
1295
       * use the configured value. */
1296
0
      if(mesh_wait > (cookie_valid?cfg->wait_limit_cookie:
1297
0
        cfg->wait_limit))
1298
0
        return 0;
1299
0
    }
1300
0
  }
1301
0
  return 1;
1302
0
}
1303
1304
void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep,
1305
  time_t timenow, struct config_file* cfg)
1306
0
{
1307
0
  struct lruhash_entry* entry;
1308
0
  if(cfg->wait_limit == 0)
1309
0
    return;
1310
1311
  /* Find it */
1312
0
  entry = infra_find_ip_ratedata(infra, &rep->client_addr,
1313
0
    rep->client_addrlen, 1);
1314
0
  if(entry) {
1315
0
    struct rate_data* d = (struct rate_data*)entry->data;
1316
0
    d->mesh_wait++;
1317
0
    lock_rw_unlock(&entry->lock);
1318
0
    return;
1319
0
  }
1320
1321
  /* Create it */
1322
0
  infra_ip_create_ratedata(infra, &rep->client_addr,
1323
0
    rep->client_addrlen, timenow, 1);
1324
0
}
1325
1326
void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep,
1327
  struct config_file* cfg)
1328
0
{
1329
0
  struct lruhash_entry* entry;
1330
0
  if(cfg->wait_limit == 0)
1331
0
    return;
1332
1333
0
  entry = infra_find_ip_ratedata(infra, &rep->client_addr,
1334
0
    rep->client_addrlen, 1);
1335
0
  if(entry) {
1336
0
    struct rate_data* d = (struct rate_data*)entry->data;
1337
0
    if(d->mesh_wait > 0)
1338
0
      d->mesh_wait--;
1339
0
    lock_rw_unlock(&entry->lock);
1340
0
  }
1341
0
}