Coverage Report

Created: 2023-06-07 06:23

/src/bind9/lib/dns/rpz.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3
 *
4
 * SPDX-License-Identifier: MPL-2.0
5
 *
6
 * This Source Code Form is subject to the terms of the Mozilla Public
7
 * License, v. 2.0. If a copy of the MPL was not distributed with this
8
 * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9
 *
10
 * See the COPYRIGHT file distributed with this work for additional
11
 * information regarding copyright ownership.
12
 */
13
14
/*! \file */
15
16
#include <inttypes.h>
17
#include <stdbool.h>
18
#include <stdint.h>
19
#include <stdlib.h>
20
21
#include <isc/async.h>
22
#include <isc/buffer.h>
23
#include <isc/loop.h>
24
#include <isc/magic.h>
25
#include <isc/mem.h>
26
#include <isc/net.h>
27
#include <isc/netaddr.h>
28
#include <isc/result.h>
29
#include <isc/rwlock.h>
30
#include <isc/string.h>
31
#include <isc/util.h>
32
#include <isc/work.h>
33
34
#include <dns/db.h>
35
#include <dns/dbiterator.h>
36
#include <dns/dnsrps.h>
37
#include <dns/fixedname.h>
38
#include <dns/log.h>
39
#include <dns/rbt.h>
40
#include <dns/rdata.h>
41
#include <dns/rdataset.h>
42
#include <dns/rdatasetiter.h>
43
#include <dns/rdatastruct.h>
44
#include <dns/rpz.h>
45
#include <dns/view.h>
46
47
0
#define DNS_RPZ_ZONE_MAGIC  ISC_MAGIC('r', 'p', 'z', ' ')
48
0
#define DNS_RPZ_ZONES_MAGIC ISC_MAGIC('r', 'p', 'z', 's')
49
50
#define DNS_RPZ_ZONE_VALID(rpz)   ISC_MAGIC_VALID(rpz, DNS_RPZ_ZONE_MAGIC)
51
#define DNS_RPZ_ZONES_VALID(rpzs) ISC_MAGIC_VALID(rpzs, DNS_RPZ_ZONES_MAGIC)
52
53
/*
54
 * Parallel radix trees for databases of response policy IP addresses
55
 *
56
 * The radix or patricia trees are somewhat specialized to handle response
57
 * policy addresses by representing the two sets of IP addresses and name
58
 * server IP addresses in a single tree.  One set of IP addresses is
59
 * for rpz-ip policies or policies triggered by addresses in A or
60
 * AAAA records in responses.
61
 * The second set is for rpz-nsip policies or policies triggered by addresses
62
 * in A or AAAA records for NS records that are authorities for responses.
63
 *
64
 * Each leaf indicates that an IP address is listed in the IP address or the
65
 * name server IP address policy sub-zone (or both) of the corresponding
66
 * response policy zone.  The policy data such as a CNAME or an A record
67
 * is kept in the policy zone.  After an IP address has been found in a radix
68
 * tree, the node in the policy zone's database is found by converting
69
 * the IP address to a domain name in a canonical form.
70
 *
71
 *
72
 * The response policy zone canonical form of an IPv6 address is one of:
73
 *  prefix.W.W.W.W.W.W.W.W
74
 *  prefix.WORDS.zz
75
 *  prefix.WORDS.zz.WORDS
76
 *  prefix.zz.WORDS
77
 *  where
78
 *  prefix  is the prefix length of the IPv6 address between 1 and 128
79
 *  W is a number between 0 and 65535
80
 *  WORDS is one or more numbers W separated with "."
81
 *  zz  corresponds to :: in the standard IPv6 text representation
82
 *
83
 * The canonical form of IPv4 addresses is:
84
 *  prefix.B.B.B.B
85
 *  where
86
 *  prefix  is the prefix length of the address between 1 and 32
87
 *  B is a number between 0 and 255
88
 *
89
 * Names for IPv4 addresses are distinguished from IPv6 addresses by having
90
 * 5 labels all of which are numbers, and a prefix between 1 and 32.
91
 */
92
93
/*
94
 * Nodes hashtable calculation parameters
95
 */
96
#define DNS_RPZ_HTSIZE_MAX 24
97
#define DNS_RPZ_HTSIZE_DIV 3
98
99
static isc_result_t
100
dns__rpz_shuttingdown(dns_rpz_zones_t *rpzs);
101
static void
102
dns__rpz_timer_cb(void *);
103
static void
104
dns__rpz_timer_start(dns_rpz_zone_t *rpz);
105
106
/*
107
 * Use a private definition of IPv6 addresses because s6_addr32 is not
108
 * always defined and our IPv6 addresses are in non-standard byte order
109
 */
110
typedef uint32_t dns_rpz_cidr_word_t;
111
0
#define DNS_RPZ_CIDR_WORD_BITS ((int)sizeof(dns_rpz_cidr_word_t) * 8)
112
0
#define DNS_RPZ_CIDR_KEY_BITS  ((int)sizeof(dns_rpz_cidr_key_t) * 8)
113
0
#define DNS_RPZ_CIDR_WORDS     (128 / DNS_RPZ_CIDR_WORD_BITS)
114
typedef struct {
115
  dns_rpz_cidr_word_t w[DNS_RPZ_CIDR_WORDS];
116
} dns_rpz_cidr_key_t;
117
118
0
#define ADDR_V4MAPPED 0xffff
119
#define KEY_IS_IPV4(prefix, ip)                                  \
120
0
  ((prefix) >= 96 && (ip)->w[0] == 0 && (ip)->w[1] == 0 && \
121
0
   (ip)->w[2] == ADDR_V4MAPPED)
122
123
#define DNS_RPZ_WORD_MASK(b)                   \
124
0
  ((b) == 0 ? (dns_rpz_cidr_word_t)(-1)  \
125
0
      : ((dns_rpz_cidr_word_t)(-1) \
126
0
         << (DNS_RPZ_CIDR_WORD_BITS - (b))))
127
128
/*
129
 * Get bit #n from the array of words of an IP address.
130
 */
131
#define DNS_RPZ_IP_BIT(ip, n)                          \
132
0
  (1 & ((ip)->w[(n) / DNS_RPZ_CIDR_WORD_BITS] >> \
133
0
        (DNS_RPZ_CIDR_WORD_BITS - 1 - ((n) % DNS_RPZ_CIDR_WORD_BITS))))
134
135
/*
136
 * A triplet of arrays of bits flagging the existence of
137
 * client-IP, IP, and NSIP policy triggers.
138
 */
139
typedef struct dns_rpz_addr_zbits dns_rpz_addr_zbits_t;
140
struct dns_rpz_addr_zbits {
141
  dns_rpz_zbits_t client_ip;
142
  dns_rpz_zbits_t ip;
143
  dns_rpz_zbits_t nsip;
144
};
145
146
/*
147
 * A CIDR or radix tree node.
148
 */
149
struct dns_rpz_cidr_node {
150
  dns_rpz_cidr_node_t *parent;
151
  dns_rpz_cidr_node_t *child[2];
152
  dns_rpz_cidr_key_t ip;
153
  dns_rpz_prefix_t prefix;
154
  dns_rpz_addr_zbits_t set;
155
  dns_rpz_addr_zbits_t sum;
156
};
157
158
/*
159
 * A pair of arrays of bits flagging the existence of
160
 * QNAME and NSDNAME policy triggers.
161
 */
162
typedef struct dns_rpz_nm_zbits dns_rpz_nm_zbits_t;
163
struct dns_rpz_nm_zbits {
164
  dns_rpz_zbits_t qname;
165
  dns_rpz_zbits_t ns;
166
};
167
168
/*
169
 * The data in a RBT node has two pairs of bits for policy zones.
170
 * One pair is for the corresponding name of the node such as example.com
171
 * and the other pair is for a wildcard child such as *.example.com.
172
 */
173
typedef struct dns_rpz_nm_data dns_rpz_nm_data_t;
174
struct dns_rpz_nm_data {
175
  dns_rpz_nm_zbits_t set;
176
  dns_rpz_nm_zbits_t wild;
177
};
178
179
static isc_result_t
180
rpz_add(dns_rpz_zone_t *rpz, const dns_name_t *src_name);
181
static void
182
rpz_del(dns_rpz_zone_t *rpz, const dns_name_t *src_name);
183
184
const char *
185
0
dns_rpz_type2str(dns_rpz_type_t type) {
186
0
  switch (type) {
187
0
  case DNS_RPZ_TYPE_CLIENT_IP:
188
0
    return ("CLIENT-IP");
189
0
  case DNS_RPZ_TYPE_QNAME:
190
0
    return ("QNAME");
191
0
  case DNS_RPZ_TYPE_IP:
192
0
    return ("IP");
193
0
  case DNS_RPZ_TYPE_NSIP:
194
0
    return ("NSIP");
195
0
  case DNS_RPZ_TYPE_NSDNAME:
196
0
    return ("NSDNAME");
197
0
  case DNS_RPZ_TYPE_BAD:
198
0
    break;
199
0
  }
200
0
  FATAL_ERROR("impossible rpz type %d", type);
201
0
  return ("impossible");
202
0
}
203
204
dns_rpz_policy_t
205
0
dns_rpz_str2policy(const char *str) {
206
0
  static struct {
207
0
    const char *str;
208
0
    dns_rpz_policy_t policy;
209
0
  } tbl[] = {
210
0
    { "given", DNS_RPZ_POLICY_GIVEN },
211
0
    { "disabled", DNS_RPZ_POLICY_DISABLED },
212
0
    { "passthru", DNS_RPZ_POLICY_PASSTHRU },
213
0
    { "drop", DNS_RPZ_POLICY_DROP },
214
0
    { "tcp-only", DNS_RPZ_POLICY_TCP_ONLY },
215
0
    { "nxdomain", DNS_RPZ_POLICY_NXDOMAIN },
216
0
    { "nodata", DNS_RPZ_POLICY_NODATA },
217
0
    { "cname", DNS_RPZ_POLICY_CNAME },
218
0
    { "no-op", DNS_RPZ_POLICY_PASSTHRU }, /* old passthru */
219
0
  };
220
0
  unsigned int n;
221
222
0
  if (str == NULL) {
223
0
    return (DNS_RPZ_POLICY_ERROR);
224
0
  }
225
0
  for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) {
226
0
    if (!strcasecmp(tbl[n].str, str)) {
227
0
      return (tbl[n].policy);
228
0
    }
229
0
  }
230
0
  return (DNS_RPZ_POLICY_ERROR);
231
0
}
232
233
const char *
234
0
dns_rpz_policy2str(dns_rpz_policy_t policy) {
235
0
  const char *str = NULL;
236
237
0
  switch (policy) {
238
0
  case DNS_RPZ_POLICY_PASSTHRU:
239
0
    str = "PASSTHRU";
240
0
    break;
241
0
  case DNS_RPZ_POLICY_DROP:
242
0
    str = "DROP";
243
0
    break;
244
0
  case DNS_RPZ_POLICY_TCP_ONLY:
245
0
    str = "TCP-ONLY";
246
0
    break;
247
0
  case DNS_RPZ_POLICY_NXDOMAIN:
248
0
    str = "NXDOMAIN";
249
0
    break;
250
0
  case DNS_RPZ_POLICY_NODATA:
251
0
    str = "NODATA";
252
0
    break;
253
0
  case DNS_RPZ_POLICY_RECORD:
254
0
    str = "Local-Data";
255
0
    break;
256
0
  case DNS_RPZ_POLICY_CNAME:
257
0
  case DNS_RPZ_POLICY_WILDCNAME:
258
0
    str = "CNAME";
259
0
    break;
260
0
  case DNS_RPZ_POLICY_MISS:
261
0
    str = "MISS";
262
0
    break;
263
0
  case DNS_RPZ_POLICY_DNS64:
264
0
    str = "DNS64";
265
0
    break;
266
0
  case DNS_RPZ_POLICY_ERROR:
267
0
    str = "ERROR";
268
0
    break;
269
0
  default:
270
0
    UNREACHABLE();
271
0
  }
272
0
  return (str);
273
0
}
274
275
uint16_t
276
0
dns_rpz_str2ede(const char *str) {
277
0
  static struct {
278
0
    const char *str;
279
0
    uint16_t ede;
280
0
  } tbl[] = {
281
0
    { "none", 0 },
282
0
    { "forged", DNS_EDE_FORGEDANSWER },
283
0
    { "blocked", DNS_EDE_BLOCKED },
284
0
    { "censored", DNS_EDE_CENSORED },
285
0
    { "filtered", DNS_EDE_FILTERED },
286
0
    { "prohibited", DNS_EDE_PROHIBITED },
287
0
  };
288
0
  unsigned int n;
289
290
0
  if (str == NULL) {
291
0
    return (UINT16_MAX);
292
0
  }
293
0
  for (n = 0; n < sizeof(tbl) / sizeof(tbl[0]); ++n) {
294
0
    if (!strcasecmp(tbl[n].str, str)) {
295
0
      return (tbl[n].ede);
296
0
    }
297
0
  }
298
0
  return (UINT16_MAX);
299
0
}
300
301
/*
302
 * Return the bit number of the highest set bit in 'zbit'.
303
 * (for example, 0x01 returns 0, 0xFF returns 7, etc.)
304
 */
305
static int
306
0
zbit_to_num(dns_rpz_zbits_t zbit) {
307
0
  dns_rpz_num_t rpz_num;
308
309
0
  REQUIRE(zbit != 0);
310
0
  rpz_num = 0;
311
0
  if ((zbit & 0xffffffff00000000ULL) != 0) {
312
0
    zbit >>= 32;
313
0
    rpz_num += 32;
314
0
  }
315
0
  if ((zbit & 0xffff0000) != 0) {
316
0
    zbit >>= 16;
317
0
    rpz_num += 16;
318
0
  }
319
0
  if ((zbit & 0xff00) != 0) {
320
0
    zbit >>= 8;
321
0
    rpz_num += 8;
322
0
  }
323
0
  if ((zbit & 0xf0) != 0) {
324
0
    zbit >>= 4;
325
0
    rpz_num += 4;
326
0
  }
327
0
  if ((zbit & 0xc) != 0) {
328
0
    zbit >>= 2;
329
0
    rpz_num += 2;
330
0
  }
331
0
  if ((zbit & 2) != 0) {
332
0
    ++rpz_num;
333
0
  }
334
0
  return (rpz_num);
335
0
}
336
337
/*
338
 * Make a set of bit masks given one or more bits and their type.
339
 */
340
static void
341
make_addr_set(dns_rpz_addr_zbits_t *tgt_set, dns_rpz_zbits_t zbits,
342
0
        dns_rpz_type_t type) {
343
0
  switch (type) {
344
0
  case DNS_RPZ_TYPE_CLIENT_IP:
345
0
    tgt_set->client_ip = zbits;
346
0
    tgt_set->ip = 0;
347
0
    tgt_set->nsip = 0;
348
0
    break;
349
0
  case DNS_RPZ_TYPE_IP:
350
0
    tgt_set->client_ip = 0;
351
0
    tgt_set->ip = zbits;
352
0
    tgt_set->nsip = 0;
353
0
    break;
354
0
  case DNS_RPZ_TYPE_NSIP:
355
0
    tgt_set->client_ip = 0;
356
0
    tgt_set->ip = 0;
357
0
    tgt_set->nsip = zbits;
358
0
    break;
359
0
  default:
360
0
    UNREACHABLE();
361
0
  }
362
0
}
363
364
static void
365
make_nm_set(dns_rpz_nm_zbits_t *tgt_set, dns_rpz_num_t rpz_num,
366
0
      dns_rpz_type_t type) {
367
0
  switch (type) {
368
0
  case DNS_RPZ_TYPE_QNAME:
369
0
    tgt_set->qname = DNS_RPZ_ZBIT(rpz_num);
370
0
    tgt_set->ns = 0;
371
0
    break;
372
0
  case DNS_RPZ_TYPE_NSDNAME:
373
0
    tgt_set->qname = 0;
374
0
    tgt_set->ns = DNS_RPZ_ZBIT(rpz_num);
375
0
    break;
376
0
  default:
377
0
    UNREACHABLE();
378
0
  }
379
0
}
380
381
/*
382
 * Mark a node and all of its parents as having client-IP, IP, or NSIP data
383
 */
384
static void
385
0
set_sum_pair(dns_rpz_cidr_node_t *cnode) {
386
0
  dns_rpz_addr_zbits_t sum;
387
388
0
  do {
389
0
    dns_rpz_cidr_node_t *child = cnode->child[0];
390
0
    sum = cnode->set;
391
392
0
    if (child != NULL) {
393
0
      sum.client_ip |= child->sum.client_ip;
394
0
      sum.ip |= child->sum.ip;
395
0
      sum.nsip |= child->sum.nsip;
396
0
    }
397
398
0
    child = cnode->child[1];
399
0
    if (child != NULL) {
400
0
      sum.client_ip |= child->sum.client_ip;
401
0
      sum.ip |= child->sum.ip;
402
0
      sum.nsip |= child->sum.nsip;
403
0
    }
404
405
0
    if (cnode->sum.client_ip == sum.client_ip &&
406
0
        cnode->sum.ip == sum.ip && cnode->sum.nsip == sum.nsip)
407
0
    {
408
0
      break;
409
0
    }
410
0
    cnode->sum = sum;
411
0
    cnode = cnode->parent;
412
0
  } while (cnode != NULL);
413
0
}
414
415
/* Caller must hold rpzs->maint_lock */
416
static void
417
0
fix_qname_skip_recurse(dns_rpz_zones_t *rpzs) {
418
0
  dns_rpz_zbits_t mask;
419
420
  /*
421
   * qname_wait_recurse and qname_skip_recurse are used to
422
   * implement the "qname-wait-recurse" config option.
423
   *
424
   * When "qname-wait-recurse" is yes, no processing happens without
425
   * recursion. In this case, qname_wait_recurse is true, and
426
   * qname_skip_recurse (a bit field indicating which policy zones
427
   * can be processed without recursion) is set to all 0's by
428
   * fix_qname_skip_recurse().
429
   *
430
   * When "qname-wait-recurse" is no, qname_skip_recurse may be
431
   * set to a non-zero value by fix_qname_skip_recurse(). The mask
432
   * has to have bits set for the policy zones for which
433
   * processing may continue without recursion, and bits cleared
434
   * for the rest.
435
   *
436
   * (1) The ARM says:
437
   *
438
   *   The "qname-wait-recurse no" option overrides that default
439
   *   behavior when recursion cannot change a non-error
440
   *   response. The option does not affect QNAME or client-IP
441
   *   triggers in policy zones listed after other zones
442
   *   containing IP, NSIP and NSDNAME triggers, because those may
443
   *   depend on the A, AAAA, and NS records that would be found
444
   *   during recursive resolution.
445
   *
446
   * Let's consider the following:
447
   *
448
   *     zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 |
449
   *        rpzs->have.nsdname |
450
   *        rpzs->have.nsipv4 | rpzs->have.nsipv6);
451
   *
452
   * zbits_req now contains bits set for zones which require
453
   * recursion.
454
   *
455
   * But going by the description in the ARM, if the first policy
456
   * zone requires recursion, then all zones after that (higher
457
   * order bits) have to wait as well.  If the Nth zone requires
458
   * recursion, then (N+1)th zone onwards all need to wait.
459
   *
460
   * So mapping this, examples:
461
   *
462
   * zbits_req = 0b000  mask = 0xffffffff (no zones have to wait for
463
   *           recursion)
464
   * zbits_req = 0b001  mask = 0x00000000 (all zones have to wait)
465
   * zbits_req = 0b010  mask = 0x00000001 (the first zone doesn't have to
466
   *           wait, second zone onwards need
467
   *           to wait)
468
   * zbits_req = 0b011  mask = 0x00000000 (all zones have to wait)
469
   * zbits_req = 0b100  mask = 0x00000011 (the 1st and 2nd zones don't
470
   *           have to wait, third zone
471
   *           onwards need to wait)
472
   *
473
   * More generally, we have to count the number of trailing 0
474
   * bits in zbits_req and only these can be processed without
475
   * recursion. All the rest need to wait.
476
   *
477
   * (2) The ARM says that "qname-wait-recurse no" option
478
   * overrides the default behavior when recursion cannot change a
479
   * non-error response. So, in the order of listing of policy
480
   * zones, within the first policy zone where recursion may be
481
   * required, we should first allow CLIENT-IP and QNAME policy
482
   * records to be attempted without recursion.
483
   */
484
485
  /*
486
   * Get a mask covering all policy zones that are not subordinate to
487
   * other policy zones containing triggers that require that the
488
   * qname be resolved before they can be checked.
489
   */
490
0
  rpzs->have.client_ip = rpzs->have.client_ipv4 | rpzs->have.client_ipv6;
491
0
  rpzs->have.ip = rpzs->have.ipv4 | rpzs->have.ipv6;
492
0
  rpzs->have.nsip = rpzs->have.nsipv4 | rpzs->have.nsipv6;
493
494
0
  if (rpzs->p.qname_wait_recurse) {
495
0
    mask = 0;
496
0
  } else {
497
0
    dns_rpz_zbits_t zbits_req;
498
0
    dns_rpz_zbits_t zbits_notreq;
499
0
    dns_rpz_zbits_t mask2;
500
0
    dns_rpz_zbits_t req_mask;
501
502
    /*
503
     * Get the masks of zones with policies that
504
     * do/don't require recursion
505
     */
506
507
0
    zbits_req = (rpzs->have.ipv4 | rpzs->have.ipv6 |
508
0
           rpzs->have.nsdname | rpzs->have.nsipv4 |
509
0
           rpzs->have.nsipv6);
510
0
    zbits_notreq = (rpzs->have.client_ip | rpzs->have.qname);
511
512
0
    if (zbits_req == 0) {
513
0
      mask = DNS_RPZ_ALL_ZBITS;
514
0
      goto set;
515
0
    }
516
517
    /*
518
     * req_mask is a mask covering used bits in
519
     * zbits_req. (For instance, 0b1 => 0b1, 0b101 => 0b111,
520
     * 0b11010101 => 0b11111111).
521
     */
522
0
    req_mask = zbits_req;
523
0
    req_mask |= req_mask >> 1;
524
0
    req_mask |= req_mask >> 2;
525
0
    req_mask |= req_mask >> 4;
526
0
    req_mask |= req_mask >> 8;
527
0
    req_mask |= req_mask >> 16;
528
0
    req_mask |= req_mask >> 32;
529
530
    /*
531
     * There's no point in skipping recursion for a later
532
     * zone if it is required in a previous zone.
533
     */
534
0
    if ((zbits_notreq & req_mask) == 0) {
535
0
      mask = 0;
536
0
      goto set;
537
0
    }
538
539
    /*
540
     * This bit arithmetic creates a mask of zones in which
541
     * it is okay to skip recursion. After the first zone
542
     * that has to wait for recursion, all the others have
543
     * to wait as well, so we want to create a mask in which
544
     * all the trailing zeroes in zbits_req are are 1, and
545
     * more significant bits are 0. (For instance,
546
     * 0x0700 => 0x00ff, 0x0007 => 0x0000)
547
     */
548
0
    mask = ~(zbits_req | ((~zbits_req) + 1));
549
550
    /*
551
     * As mentioned in (2) above, the zone corresponding to
552
     * the least significant zero could have its CLIENT-IP
553
     * and QNAME policies checked before recursion, if it
554
     * has any of those policies.  So if it does, we
555
     * can set its 0 to 1.
556
     *
557
     * Locate the least significant 0 bit in the mask (for
558
     * instance, 0xff => 0x100)...
559
     */
560
0
    mask2 = (mask << 1) & ~mask;
561
562
    /*
563
     * Also set the bit for zone 0, because if it's in
564
     * zbits_notreq then it's definitely okay to attempt to
565
     * skip recursion for zone 0...
566
     */
567
0
    mask2 |= 1;
568
569
    /* Clear any bits *not* in zbits_notreq... */
570
0
    mask2 &= zbits_notreq;
571
572
    /* And merge the result into the skip-recursion mask */
573
0
    mask |= mask2;
574
0
  }
575
576
0
set:
577
0
  isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ, DNS_LOGMODULE_RBTDB,
578
0
          DNS_RPZ_DEBUG_QUIET,
579
0
          "computed RPZ qname_skip_recurse mask=0x%" PRIx64,
580
0
          (uint64_t)mask);
581
0
  rpzs->have.qname_skip_recurse = mask;
582
0
}
583
584
static void
585
adj_trigger_cnt(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
586
    const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix,
587
0
    bool inc) {
588
0
  dns_rpz_trigger_counter_t *cnt = NULL;
589
0
  dns_rpz_zbits_t *have = NULL;
590
591
0
  switch (rpz_type) {
592
0
  case DNS_RPZ_TYPE_CLIENT_IP:
593
0
    REQUIRE(tgt_ip != NULL);
594
0
    if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) {
595
0
      cnt = &rpz->rpzs->triggers[rpz->num].client_ipv4;
596
0
      have = &rpz->rpzs->have.client_ipv4;
597
0
    } else {
598
0
      cnt = &rpz->rpzs->triggers[rpz->num].client_ipv6;
599
0
      have = &rpz->rpzs->have.client_ipv6;
600
0
    }
601
0
    break;
602
0
  case DNS_RPZ_TYPE_QNAME:
603
0
    cnt = &rpz->rpzs->triggers[rpz->num].qname;
604
0
    have = &rpz->rpzs->have.qname;
605
0
    break;
606
0
  case DNS_RPZ_TYPE_IP:
607
0
    REQUIRE(tgt_ip != NULL);
608
0
    if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) {
609
0
      cnt = &rpz->rpzs->triggers[rpz->num].ipv4;
610
0
      have = &rpz->rpzs->have.ipv4;
611
0
    } else {
612
0
      cnt = &rpz->rpzs->triggers[rpz->num].ipv6;
613
0
      have = &rpz->rpzs->have.ipv6;
614
0
    }
615
0
    break;
616
0
  case DNS_RPZ_TYPE_NSDNAME:
617
0
    cnt = &rpz->rpzs->triggers[rpz->num].nsdname;
618
0
    have = &rpz->rpzs->have.nsdname;
619
0
    break;
620
0
  case DNS_RPZ_TYPE_NSIP:
621
0
    REQUIRE(tgt_ip != NULL);
622
0
    if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) {
623
0
      cnt = &rpz->rpzs->triggers[rpz->num].nsipv4;
624
0
      have = &rpz->rpzs->have.nsipv4;
625
0
    } else {
626
0
      cnt = &rpz->rpzs->triggers[rpz->num].nsipv6;
627
0
      have = &rpz->rpzs->have.nsipv6;
628
0
    }
629
0
    break;
630
0
  default:
631
0
    UNREACHABLE();
632
0
  }
633
634
0
  if (inc) {
635
0
    if (++*cnt == 1U) {
636
0
      *have |= DNS_RPZ_ZBIT(rpz->num);
637
0
      fix_qname_skip_recurse(rpz->rpzs);
638
0
    }
639
0
  } else {
640
0
    REQUIRE(*cnt != 0U);
641
0
    if (--*cnt == 0U) {
642
0
      *have &= ~DNS_RPZ_ZBIT(rpz->num);
643
0
      fix_qname_skip_recurse(rpz->rpzs);
644
0
    }
645
0
  }
646
0
}
647
648
static dns_rpz_cidr_node_t *
649
new_node(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *ip,
650
0
   dns_rpz_prefix_t prefix, const dns_rpz_cidr_node_t *child) {
651
0
  dns_rpz_cidr_node_t *node = NULL;
652
0
  int i, words, wlen;
653
654
0
  node = isc_mem_get(rpzs->mctx, sizeof(*node));
655
0
  *node = (dns_rpz_cidr_node_t){
656
0
    .prefix = prefix,
657
0
  };
658
659
0
  if (child != NULL) {
660
0
    node->sum = child->sum;
661
0
  }
662
663
0
  words = prefix / DNS_RPZ_CIDR_WORD_BITS;
664
0
  wlen = prefix % DNS_RPZ_CIDR_WORD_BITS;
665
0
  i = 0;
666
0
  while (i < words) {
667
0
    node->ip.w[i] = ip->w[i];
668
0
    ++i;
669
0
  }
670
0
  if (wlen != 0) {
671
0
    node->ip.w[i] = ip->w[i] & DNS_RPZ_WORD_MASK(wlen);
672
0
    ++i;
673
0
  }
674
0
  while (i < DNS_RPZ_CIDR_WORDS) {
675
0
    node->ip.w[i++] = 0;
676
0
  }
677
678
0
  return (node);
679
0
}
680
681
static void
682
0
badname(int level, const dns_name_t *name, const char *str1, const char *str2) {
683
  /*
684
   * bin/tests/system/rpz/tests.sh looks for "invalid rpz".
685
   */
686
0
  if (level < DNS_RPZ_DEBUG_QUIET && isc_log_wouldlog(dns_lctx, level)) {
687
0
    char namebuf[DNS_NAME_FORMATSIZE];
688
0
    dns_name_format(name, namebuf, sizeof(namebuf));
689
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
690
0
            DNS_LOGMODULE_RBTDB, level,
691
0
            "invalid rpz IP address \"%s\"%s%s", namebuf,
692
0
            str1, str2);
693
0
  }
694
0
}
695
696
/*
697
 * Convert an IP address from radix tree binary (host byte order) to
698
 * to its canonical response policy domain name without the origin of the
699
 * policy zone.
700
 *
701
 * Generate a name for an IPv6 address that fits RFC 5952, except that our
702
 * reversed format requires that when the length of the consecutive 16-bit
703
 * 0 fields are equal (e.g., 1.0.0.1.0.0.db8.2001 corresponding to
704
 * 2001:db8:0:0:1:0:0:1), we shorted the last instead of the first
705
 * (e.g., 1.0.0.1.zz.db8.2001 corresponding to 2001:db8::1:0:0:1).
706
 */
707
static isc_result_t
708
ip2name(const dns_rpz_cidr_key_t *tgt_ip, dns_rpz_prefix_t tgt_prefix,
709
0
  const dns_name_t *base_name, dns_name_t *ip_name) {
710
#ifndef INET6_ADDRSTRLEN
711
#define INET6_ADDRSTRLEN 46
712
#endif /* ifndef INET6_ADDRSTRLEN */
713
0
  char str[1 + 8 + 1 + INET6_ADDRSTRLEN + 1];
714
0
  isc_buffer_t buffer;
715
0
  isc_result_t result;
716
0
  int len;
717
718
0
  if (KEY_IS_IPV4(tgt_prefix, tgt_ip)) {
719
0
    len = snprintf(str, sizeof(str), "%u.%u.%u.%u.%u",
720
0
             tgt_prefix - 96U, tgt_ip->w[3] & 0xffU,
721
0
             (tgt_ip->w[3] >> 8) & 0xffU,
722
0
             (tgt_ip->w[3] >> 16) & 0xffU,
723
0
             (tgt_ip->w[3] >> 24) & 0xffU);
724
0
    if (len < 0 || (size_t)len >= sizeof(str)) {
725
0
      return (ISC_R_FAILURE);
726
0
    }
727
0
  } else {
728
0
    int w[DNS_RPZ_CIDR_WORDS * 2];
729
0
    int best_first, best_len, cur_first, cur_len;
730
731
0
    len = snprintf(str, sizeof(str), "%d", tgt_prefix);
732
0
    if (len < 0 || (size_t)len >= sizeof(str)) {
733
0
      return (ISC_R_FAILURE);
734
0
    }
735
736
0
    for (int n = 0; n < DNS_RPZ_CIDR_WORDS; n++) {
737
0
      w[n * 2 + 1] =
738
0
        ((tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - n] >> 16) &
739
0
         0xffff);
740
0
      w[n * 2] = tgt_ip->w[DNS_RPZ_CIDR_WORDS - 1 - n] &
741
0
           0xffff;
742
0
    }
743
    /*
744
     * Find the start and length of the first longest sequence
745
     * of zeros in the address.
746
     */
747
0
    best_first = -1;
748
0
    best_len = 0;
749
0
    cur_first = -1;
750
0
    cur_len = 0;
751
0
    for (int n = 0; n <= 7; ++n) {
752
0
      if (w[n] != 0) {
753
0
        cur_len = 0;
754
0
        cur_first = -1;
755
0
      } else {
756
0
        ++cur_len;
757
0
        if (cur_first < 0) {
758
0
          cur_first = n;
759
0
        } else if (cur_len >= best_len) {
760
0
          best_first = cur_first;
761
0
          best_len = cur_len;
762
0
        }
763
0
      }
764
0
    }
765
766
0
    for (int n = 0; n <= 7; ++n) {
767
0
      int i;
768
769
0
      INSIST(len > 0 && (size_t)len < sizeof(str));
770
0
      if (n == best_first) {
771
0
        i = snprintf(str + len, sizeof(str) - len,
772
0
               ".zz");
773
0
        n += best_len - 1;
774
0
      } else {
775
0
        i = snprintf(str + len, sizeof(str) - len,
776
0
               ".%x", w[n]);
777
0
      }
778
0
      if (i < 0 || (size_t)i >= (size_t)(sizeof(str) - len)) {
779
0
        return (ISC_R_FAILURE);
780
0
      }
781
0
      len += i;
782
0
    }
783
0
  }
784
785
0
  isc_buffer_init(&buffer, str, sizeof(str));
786
0
  isc_buffer_add(&buffer, len);
787
0
  result = dns_name_fromtext(ip_name, &buffer, base_name, 0, NULL);
788
0
  return (result);
789
0
}
790
791
/*
792
 * Determine the type of a name in a response policy zone.
793
 */
794
static dns_rpz_type_t
795
type_from_name(const dns_rpz_zones_t *rpzs, dns_rpz_zone_t *rpz,
796
0
         const dns_name_t *name) {
797
0
  if (dns_name_issubdomain(name, &rpz->ip)) {
798
0
    return (DNS_RPZ_TYPE_IP);
799
0
  }
800
801
0
  if (dns_name_issubdomain(name, &rpz->client_ip)) {
802
0
    return (DNS_RPZ_TYPE_CLIENT_IP);
803
0
  }
804
805
0
  if ((rpzs->p.nsip_on & DNS_RPZ_ZBIT(rpz->num)) != 0 &&
806
0
      dns_name_issubdomain(name, &rpz->nsip))
807
0
  {
808
0
    return (DNS_RPZ_TYPE_NSIP);
809
0
  }
810
811
0
  if ((rpzs->p.nsdname_on & DNS_RPZ_ZBIT(rpz->num)) != 0 &&
812
0
      dns_name_issubdomain(name, &rpz->nsdname))
813
0
  {
814
0
    return (DNS_RPZ_TYPE_NSDNAME);
815
0
  }
816
817
0
  return (DNS_RPZ_TYPE_QNAME);
818
0
}
819
820
/*
821
 * Convert an IP address from canonical response policy domain name form
822
 * to radix tree binary (host byte order) for adding or deleting IP or NSIP
823
 * data.
824
 */
825
static isc_result_t
826
name2ipkey(int log_level, dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
827
     const dns_name_t *src_name, dns_rpz_cidr_key_t *tgt_ip,
828
0
     dns_rpz_prefix_t *tgt_prefix, dns_rpz_addr_zbits_t *new_set) {
829
0
  char ip_str[DNS_NAME_FORMATSIZE];
830
0
  dns_offsets_t ip_name_offsets;
831
0
  dns_fixedname_t ip_name2f;
832
0
  dns_name_t ip_name;
833
0
  const char *prefix_str = NULL, *cp = NULL, *end = NULL;
834
0
  char *cp2;
835
0
  int ip_labels;
836
0
  dns_rpz_prefix_t prefix;
837
0
  unsigned long prefix_num, l;
838
0
  isc_result_t result;
839
0
  int i;
840
841
0
  REQUIRE(rpz != NULL);
842
0
  REQUIRE(rpz->rpzs != NULL && rpz->num < rpz->rpzs->p.num_zones);
843
844
0
  make_addr_set(new_set, DNS_RPZ_ZBIT(rpz->num), rpz_type);
845
846
0
  ip_labels = dns_name_countlabels(src_name);
847
0
  if (rpz_type == DNS_RPZ_TYPE_QNAME) {
848
0
    ip_labels -= dns_name_countlabels(&rpz->origin);
849
0
  } else {
850
0
    ip_labels -= dns_name_countlabels(&rpz->nsdname);
851
0
  }
852
0
  if (ip_labels < 2) {
853
0
    badname(log_level, src_name, "; too short", "");
854
0
    return (ISC_R_FAILURE);
855
0
  }
856
0
  dns_name_init(&ip_name, ip_name_offsets);
857
0
  dns_name_getlabelsequence(src_name, 0, ip_labels, &ip_name);
858
859
  /*
860
   * Get text for the IP address
861
   */
862
0
  dns_name_format(&ip_name, ip_str, sizeof(ip_str));
863
0
  end = &ip_str[strlen(ip_str) + 1];
864
0
  prefix_str = ip_str;
865
866
0
  prefix_num = strtoul(prefix_str, &cp2, 10);
867
0
  if (*cp2 != '.') {
868
0
    badname(log_level, src_name, "; invalid leading prefix length",
869
0
      "");
870
0
    return (ISC_R_FAILURE);
871
0
  }
872
  /*
873
   * Patch in trailing nul character to print just the length
874
   * label (for various cases below).
875
   */
876
0
  *cp2 = '\0';
877
0
  if (prefix_num < 1U || prefix_num > 128U) {
878
0
    badname(log_level, src_name, "; invalid prefix length of ",
879
0
      prefix_str);
880
0
    return (ISC_R_FAILURE);
881
0
  }
882
0
  cp = cp2 + 1;
883
884
0
  if (--ip_labels == 4 && !strchr(cp, 'z')) {
885
    /*
886
     * Convert an IPv4 address
887
     * from the form "prefix.z.y.x.w"
888
     */
889
0
    if (prefix_num > 32U) {
890
0
      badname(log_level, src_name,
891
0
        "; invalid IPv4 prefix length of ", prefix_str);
892
0
      return (ISC_R_FAILURE);
893
0
    }
894
0
    prefix_num += 96;
895
0
    *tgt_prefix = (dns_rpz_prefix_t)prefix_num;
896
0
    tgt_ip->w[0] = 0;
897
0
    tgt_ip->w[1] = 0;
898
0
    tgt_ip->w[2] = ADDR_V4MAPPED;
899
0
    tgt_ip->w[3] = 0;
900
0
    for (i = 0; i < 32; i += 8) {
901
0
      l = strtoul(cp, &cp2, 10);
902
0
      if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) {
903
0
        if (*cp2 == '.') {
904
0
          *cp2 = '\0';
905
0
        }
906
0
        badname(log_level, src_name,
907
0
          "; invalid IPv4 octet ", cp);
908
0
        return (ISC_R_FAILURE);
909
0
      }
910
0
      tgt_ip->w[3] |= l << i;
911
0
      cp = cp2 + 1;
912
0
    }
913
0
  } else {
914
    /*
915
     * Convert a text IPv6 address.
916
     */
917
0
    *tgt_prefix = (dns_rpz_prefix_t)prefix_num;
918
0
    for (i = 0; ip_labels > 0 && i < DNS_RPZ_CIDR_WORDS * 2;
919
0
         ip_labels--)
920
0
    {
921
0
      if (cp[0] == 'z' && cp[1] == 'z' &&
922
0
          (cp[2] == '.' || cp[2] == '\0') && i <= 6)
923
0
      {
924
0
        do {
925
0
          if ((i & 1) == 0) {
926
0
            tgt_ip->w[3 - i / 2] = 0;
927
0
          }
928
0
          ++i;
929
0
        } while (ip_labels + i <= 8);
930
0
        cp += 3;
931
0
      } else {
932
0
        l = strtoul(cp, &cp2, 16);
933
0
        if (l > 0xffffu ||
934
0
            (*cp2 != '.' && *cp2 != '\0'))
935
0
        {
936
0
          if (*cp2 == '.') {
937
0
            *cp2 = '\0';
938
0
          }
939
0
          badname(log_level, src_name,
940
0
            "; invalid IPv6 word ", cp);
941
0
          return (ISC_R_FAILURE);
942
0
        }
943
0
        if ((i & 1) == 0) {
944
0
          tgt_ip->w[3 - i / 2] = l;
945
0
        } else {
946
0
          tgt_ip->w[3 - i / 2] |= l << 16;
947
0
        }
948
0
        i++;
949
0
        cp = cp2 + 1;
950
0
      }
951
0
    }
952
0
  }
953
0
  if (cp != end) {
954
0
    badname(log_level, src_name, "", "");
955
0
    return (ISC_R_FAILURE);
956
0
  }
957
958
  /*
959
   * Check for 1s after the prefix length.
960
   */
961
0
  prefix = (dns_rpz_prefix_t)prefix_num;
962
0
  while (prefix < DNS_RPZ_CIDR_KEY_BITS) {
963
0
    dns_rpz_cidr_word_t aword;
964
965
0
    i = prefix % DNS_RPZ_CIDR_WORD_BITS;
966
0
    aword = tgt_ip->w[prefix / DNS_RPZ_CIDR_WORD_BITS];
967
0
    if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) {
968
0
      badname(log_level, src_name,
969
0
        "; too small prefix length of ", prefix_str);
970
0
      return (ISC_R_FAILURE);
971
0
    }
972
0
    prefix -= i;
973
0
    prefix += DNS_RPZ_CIDR_WORD_BITS;
974
0
  }
975
976
  /*
977
   * Complain about bad names but be generous and accept them.
978
   */
979
0
  if (log_level < DNS_RPZ_DEBUG_QUIET &&
980
0
      isc_log_wouldlog(dns_lctx, log_level))
981
0
  {
982
    /*
983
     * Convert the address back to a canonical domain name
984
     * to ensure that the original name is in canonical form.
985
     */
986
0
    dns_name_t *ip_name2 = dns_fixedname_initname(&ip_name2f);
987
0
    result = ip2name(tgt_ip, (dns_rpz_prefix_t)prefix_num, NULL,
988
0
         ip_name2);
989
0
    if (result != ISC_R_SUCCESS ||
990
0
        !dns_name_equal(&ip_name, ip_name2))
991
0
    {
992
0
      char ip2_str[DNS_NAME_FORMATSIZE];
993
0
      dns_name_format(ip_name2, ip2_str, sizeof(ip2_str));
994
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
995
0
              DNS_LOGMODULE_RBTDB, log_level,
996
0
              "rpz IP address \"%s\""
997
0
              " is not the canonical \"%s\"",
998
0
              ip_str, ip2_str);
999
0
    }
1000
0
  }
1001
1002
0
  return (ISC_R_SUCCESS);
1003
0
}
1004
1005
/*
1006
 * Get trigger name and data bits for adding or deleting summary NSDNAME
1007
 * or QNAME data.
1008
 */
1009
static void
1010
name2data(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
1011
    const dns_name_t *src_name, dns_name_t *trig_name,
1012
0
    dns_rpz_nm_data_t *new_data) {
1013
0
  dns_offsets_t tmp_name_offsets;
1014
0
  dns_name_t tmp_name;
1015
0
  unsigned int prefix_len, n;
1016
1017
0
  REQUIRE(rpz != NULL);
1018
0
  REQUIRE(rpz->rpzs != NULL && rpz->num < rpz->rpzs->p.num_zones);
1019
1020
  /*
1021
   * Handle wildcards by putting only the parent into the
1022
   * summary RBT.  The summary database only causes a check of the
1023
   * real policy zone where wildcards will be handled.
1024
   */
1025
0
  if (dns_name_iswildcard(src_name)) {
1026
0
    prefix_len = 1;
1027
0
    memset(&new_data->set, 0, sizeof(new_data->set));
1028
0
    make_nm_set(&new_data->wild, rpz->num, rpz_type);
1029
0
  } else {
1030
0
    prefix_len = 0;
1031
0
    make_nm_set(&new_data->set, rpz->num, rpz_type);
1032
0
    memset(&new_data->wild, 0, sizeof(new_data->wild));
1033
0
  }
1034
1035
0
  dns_name_init(&tmp_name, tmp_name_offsets);
1036
0
  n = dns_name_countlabels(src_name);
1037
0
  n -= prefix_len;
1038
0
  if (rpz_type == DNS_RPZ_TYPE_QNAME) {
1039
0
    n -= dns_name_countlabels(&rpz->origin);
1040
0
  } else {
1041
0
    n -= dns_name_countlabels(&rpz->nsdname);
1042
0
  }
1043
0
  dns_name_getlabelsequence(src_name, prefix_len, n, &tmp_name);
1044
0
  (void)dns_name_concatenate(&tmp_name, dns_rootname, trig_name, NULL);
1045
0
}
1046
1047
#ifndef HAVE_BUILTIN_CLZ
1048
/**
1049
 * \brief Count Leading Zeros: Find the location of the left-most set
1050
 * bit.
1051
 */
1052
static unsigned int
1053
clz(dns_rpz_cidr_word_t w) {
1054
  unsigned int bit;
1055
1056
  bit = DNS_RPZ_CIDR_WORD_BITS - 1;
1057
1058
  if ((w & 0xffff0000) != 0) {
1059
    w >>= 16;
1060
    bit -= 16;
1061
  }
1062
1063
  if ((w & 0xff00) != 0) {
1064
    w >>= 8;
1065
    bit -= 8;
1066
  }
1067
1068
  if ((w & 0xf0) != 0) {
1069
    w >>= 4;
1070
    bit -= 4;
1071
  }
1072
1073
  if ((w & 0xc) != 0) {
1074
    w >>= 2;
1075
    bit -= 2;
1076
  }
1077
1078
  if ((w & 2) != 0) {
1079
    --bit;
1080
  }
1081
1082
  return (bit);
1083
}
1084
#endif /* ifndef HAVE_BUILTIN_CLZ */
1085
1086
/*
1087
 * Find the first differing bit in two keys (IP addresses).
1088
 */
1089
static int
1090
diff_keys(const dns_rpz_cidr_key_t *key1, dns_rpz_prefix_t prefix1,
1091
0
    const dns_rpz_cidr_key_t *key2, dns_rpz_prefix_t prefix2) {
1092
0
  dns_rpz_cidr_word_t delta;
1093
0
  dns_rpz_prefix_t maxbit, bit;
1094
0
  int i;
1095
1096
0
  bit = 0;
1097
0
  maxbit = ISC_MIN(prefix1, prefix2);
1098
1099
  /*
1100
   * find the first differing words
1101
   */
1102
0
  for (i = 0; bit < maxbit; i++, bit += DNS_RPZ_CIDR_WORD_BITS) {
1103
0
    delta = key1->w[i] ^ key2->w[i];
1104
0
    if (delta != 0) {
1105
0
#ifdef HAVE_BUILTIN_CLZ
1106
0
      bit += __builtin_clz(delta);
1107
#else  /* ifdef HAVE_BUILTIN_CLZ */
1108
      bit += clz(delta);
1109
#endif /* ifdef HAVE_BUILTIN_CLZ */
1110
0
      break;
1111
0
    }
1112
0
  }
1113
0
  return (ISC_MIN(bit, maxbit));
1114
0
}
1115
1116
/*
1117
 * Given a hit while searching the radix trees,
1118
 * clear all bits for higher numbered zones.
1119
 */
1120
static dns_rpz_zbits_t
1121
0
trim_zbits(dns_rpz_zbits_t zbits, dns_rpz_zbits_t found) {
1122
0
  dns_rpz_zbits_t x;
1123
1124
  /*
1125
   * Isolate the first or smallest numbered hit bit.
1126
   * Make a mask of that bit and all smaller numbered bits.
1127
   */
1128
0
  x = zbits & found;
1129
0
  x &= (~x + 1);
1130
0
  x = (x << 1) - 1;
1131
0
  zbits &= x;
1132
0
  return (zbits);
1133
0
}
1134
1135
/*
1136
 * Search a radix tree for an IP address for ordinary lookup
1137
 *  or for a CIDR block adding or deleting an entry
1138
 *
1139
 * Return ISC_R_SUCCESS, DNS_R_PARTIALMATCH, ISC_R_NOTFOUND,
1140
 *      and *found=longest match node
1141
 *  or with create==true, ISC_R_EXISTS or ISC_R_NOMEMORY
1142
 */
1143
static isc_result_t
1144
search(dns_rpz_zones_t *rpzs, const dns_rpz_cidr_key_t *tgt_ip,
1145
       dns_rpz_prefix_t tgt_prefix, const dns_rpz_addr_zbits_t *tgt_set,
1146
0
       bool create, dns_rpz_cidr_node_t **found) {
1147
0
  dns_rpz_cidr_node_t *cur = NULL, *parent = NULL, *child = NULL;
1148
0
  dns_rpz_cidr_node_t *new_parent = NULL, *sibling = NULL;
1149
0
  dns_rpz_addr_zbits_t set;
1150
0
  int cur_num, child_num;
1151
0
  isc_result_t find_result;
1152
1153
0
  set = *tgt_set;
1154
0
  find_result = ISC_R_NOTFOUND;
1155
0
  *found = NULL;
1156
0
  cur = rpzs->cidr;
1157
0
  parent = NULL;
1158
0
  cur_num = 0;
1159
0
  for (;;) {
1160
0
    dns_rpz_prefix_t dbit;
1161
0
    if (cur == NULL) {
1162
      /*
1163
       * No child so we cannot go down.
1164
       * Quit with whatever we already found
1165
       * or add the target as a child of the current parent.
1166
       */
1167
0
      if (!create) {
1168
0
        return (find_result);
1169
0
      }
1170
0
      child = new_node(rpzs, tgt_ip, tgt_prefix, NULL);
1171
0
      if (child == NULL) {
1172
0
        return (ISC_R_NOMEMORY);
1173
0
      }
1174
0
      if (parent == NULL) {
1175
0
        rpzs->cidr = child;
1176
0
      } else {
1177
0
        parent->child[cur_num] = child;
1178
0
      }
1179
0
      child->parent = parent;
1180
0
      child->set.client_ip |= tgt_set->client_ip;
1181
0
      child->set.ip |= tgt_set->ip;
1182
0
      child->set.nsip |= tgt_set->nsip;
1183
0
      set_sum_pair(child);
1184
0
      *found = child;
1185
0
      return (ISC_R_SUCCESS);
1186
0
    }
1187
1188
0
    if ((cur->sum.client_ip & set.client_ip) == 0 &&
1189
0
        (cur->sum.ip & set.ip) == 0 &&
1190
0
        (cur->sum.nsip & set.nsip) == 0)
1191
0
    {
1192
      /*
1193
       * This node has no relevant data
1194
       * and is in none of the target trees.
1195
       * Pretend it does not exist if we are not adding.
1196
       *
1197
       * If we are adding, continue down to eventually add
1198
       * a node and mark/put this node in the correct tree.
1199
       */
1200
0
      if (!create) {
1201
0
        return (find_result);
1202
0
      }
1203
0
    }
1204
1205
0
    dbit = diff_keys(tgt_ip, tgt_prefix, &cur->ip, cur->prefix);
1206
    /*
1207
     * dbit <= tgt_prefix and dbit <= cur->prefix always.
1208
     * We are finished searching if we matched all of the target.
1209
     */
1210
0
    if (dbit == tgt_prefix) {
1211
0
      if (tgt_prefix == cur->prefix) {
1212
        /*
1213
         * The node's key matches the target exactly.
1214
         */
1215
0
        if ((cur->set.client_ip & set.client_ip) != 0 ||
1216
0
            (cur->set.ip & set.ip) != 0 ||
1217
0
            (cur->set.nsip & set.nsip) != 0)
1218
0
        {
1219
          /*
1220
           * It is the answer if it has data.
1221
           */
1222
0
          *found = cur;
1223
0
          if (create) {
1224
0
            find_result = ISC_R_EXISTS;
1225
0
          } else {
1226
0
            find_result = ISC_R_SUCCESS;
1227
0
          }
1228
0
        } else if (create) {
1229
          /*
1230
           * The node lacked relevant data,
1231
           * but will have it now.
1232
           */
1233
0
          cur->set.client_ip |=
1234
0
            tgt_set->client_ip;
1235
0
          cur->set.ip |= tgt_set->ip;
1236
0
          cur->set.nsip |= tgt_set->nsip;
1237
0
          set_sum_pair(cur);
1238
0
          *found = cur;
1239
0
          find_result = ISC_R_SUCCESS;
1240
0
        }
1241
0
        return (find_result);
1242
0
      }
1243
1244
      /*
1245
       * We know tgt_prefix < cur->prefix which means that
1246
       * the target is shorter than the current node.
1247
       * Add the target as the current node's parent.
1248
       */
1249
0
      if (!create) {
1250
0
        return (find_result);
1251
0
      }
1252
1253
0
      new_parent = new_node(rpzs, tgt_ip, tgt_prefix, cur);
1254
0
      if (new_parent == NULL) {
1255
0
        return (ISC_R_NOMEMORY);
1256
0
      }
1257
0
      new_parent->parent = parent;
1258
0
      if (parent == NULL) {
1259
0
        rpzs->cidr = new_parent;
1260
0
      } else {
1261
0
        parent->child[cur_num] = new_parent;
1262
0
      }
1263
0
      child_num = DNS_RPZ_IP_BIT(&cur->ip, tgt_prefix);
1264
0
      new_parent->child[child_num] = cur;
1265
0
      cur->parent = new_parent;
1266
0
      new_parent->set = *tgt_set;
1267
0
      set_sum_pair(new_parent);
1268
0
      *found = new_parent;
1269
0
      return (ISC_R_SUCCESS);
1270
0
    }
1271
1272
0
    if (dbit == cur->prefix) {
1273
0
      if ((cur->set.client_ip & set.client_ip) != 0 ||
1274
0
          (cur->set.ip & set.ip) != 0 ||
1275
0
          (cur->set.nsip & set.nsip) != 0)
1276
0
      {
1277
        /*
1278
         * We have a partial match between of all of the
1279
         * current node but only part of the target.
1280
         * Continue searching for other hits in the
1281
         * same or lower numbered trees.
1282
         */
1283
0
        find_result = DNS_R_PARTIALMATCH;
1284
0
        *found = cur;
1285
0
        set.client_ip = trim_zbits(set.client_ip,
1286
0
                 cur->set.client_ip);
1287
0
        set.ip = trim_zbits(set.ip, cur->set.ip);
1288
0
        set.nsip = trim_zbits(set.nsip, cur->set.nsip);
1289
0
      }
1290
0
      parent = cur;
1291
0
      cur_num = DNS_RPZ_IP_BIT(tgt_ip, dbit);
1292
0
      cur = cur->child[cur_num];
1293
0
      continue;
1294
0
    }
1295
1296
    /*
1297
     * dbit < tgt_prefix and dbit < cur->prefix,
1298
     * so we failed to match both the target and the current node.
1299
     * Insert a fork of a parent above the current node and
1300
     * add the target as a sibling of the current node
1301
     */
1302
0
    if (!create) {
1303
0
      return (find_result);
1304
0
    }
1305
1306
0
    sibling = new_node(rpzs, tgt_ip, tgt_prefix, NULL);
1307
0
    if (sibling == NULL) {
1308
0
      return (ISC_R_NOMEMORY);
1309
0
    }
1310
0
    new_parent = new_node(rpzs, tgt_ip, dbit, cur);
1311
0
    if (new_parent == NULL) {
1312
0
      isc_mem_put(rpzs->mctx, sibling, sizeof(*sibling));
1313
0
      return (ISC_R_NOMEMORY);
1314
0
    }
1315
0
    new_parent->parent = parent;
1316
0
    if (parent == NULL) {
1317
0
      rpzs->cidr = new_parent;
1318
0
    } else {
1319
0
      parent->child[cur_num] = new_parent;
1320
0
    }
1321
0
    child_num = DNS_RPZ_IP_BIT(tgt_ip, dbit);
1322
0
    new_parent->child[child_num] = sibling;
1323
0
    new_parent->child[1 - child_num] = cur;
1324
0
    cur->parent = new_parent;
1325
0
    sibling->parent = new_parent;
1326
0
    sibling->set = *tgt_set;
1327
0
    set_sum_pair(sibling);
1328
0
    *found = sibling;
1329
0
    return (ISC_R_SUCCESS);
1330
0
  }
1331
0
}
1332
1333
/*
1334
 * Add an IP address to the radix tree.
1335
 */
1336
static isc_result_t
1337
add_cidr(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
1338
0
   const dns_name_t *src_name) {
1339
0
  dns_rpz_cidr_key_t tgt_ip;
1340
0
  dns_rpz_prefix_t tgt_prefix;
1341
0
  dns_rpz_addr_zbits_t set;
1342
0
  dns_rpz_cidr_node_t *found = NULL;
1343
0
  isc_result_t result;
1344
1345
0
  result = name2ipkey(DNS_RPZ_ERROR_LEVEL, rpz, rpz_type, src_name,
1346
0
          &tgt_ip, &tgt_prefix, &set);
1347
  /*
1348
   * Log complaints about bad owner names but let the zone load.
1349
   */
1350
0
  if (result != ISC_R_SUCCESS) {
1351
0
    return (ISC_R_SUCCESS);
1352
0
  }
1353
1354
0
  result = search(rpz->rpzs, &tgt_ip, tgt_prefix, &set, true, &found);
1355
0
  if (result != ISC_R_SUCCESS) {
1356
0
    char namebuf[DNS_NAME_FORMATSIZE];
1357
1358
    /*
1359
     * Do not worry if the radix tree already exists,
1360
     * because diff_apply() likes to add nodes before deleting.
1361
     */
1362
0
    if (result == ISC_R_EXISTS) {
1363
0
      return (ISC_R_SUCCESS);
1364
0
    }
1365
1366
    /*
1367
     * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
1368
     */
1369
0
    dns_name_format(src_name, namebuf, sizeof(namebuf));
1370
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
1371
0
            DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
1372
0
            "rpz add_cidr(%s) failed: %s", namebuf,
1373
0
            isc_result_totext(result));
1374
0
    return (result);
1375
0
  }
1376
1377
0
  adj_trigger_cnt(rpz, rpz_type, &tgt_ip, tgt_prefix, true);
1378
0
  return (result);
1379
0
}
1380
1381
static isc_result_t
1382
add_nm(dns_rpz_zones_t *rpzs, dns_name_t *trig_name,
1383
0
       const dns_rpz_nm_data_t *new_data) {
1384
0
  dns_rbtnode_t *nmnode = NULL;
1385
0
  dns_rpz_nm_data_t *nm_data = NULL;
1386
0
  isc_result_t result;
1387
1388
0
  nmnode = NULL;
1389
0
  result = dns_rbt_addnode(rpzs->rbt, trig_name, &nmnode);
1390
0
  switch (result) {
1391
0
  case ISC_R_SUCCESS:
1392
0
  case ISC_R_EXISTS:
1393
0
    nm_data = nmnode->data;
1394
0
    if (nm_data == NULL) {
1395
0
      nm_data = isc_mem_get(rpzs->mctx, sizeof(*nm_data));
1396
0
      *nm_data = *new_data;
1397
0
      nmnode->data = nm_data;
1398
0
      return (ISC_R_SUCCESS);
1399
0
    }
1400
0
    break;
1401
0
  default:
1402
0
    return (result);
1403
0
  }
1404
1405
  /*
1406
   * Do not count bits that are already present
1407
   */
1408
0
  if ((nm_data->set.qname & new_data->set.qname) != 0 ||
1409
0
      (nm_data->set.ns & new_data->set.ns) != 0 ||
1410
0
      (nm_data->wild.qname & new_data->wild.qname) != 0 ||
1411
0
      (nm_data->wild.ns & new_data->wild.ns) != 0)
1412
0
  {
1413
0
    return (ISC_R_EXISTS);
1414
0
  }
1415
1416
0
  nm_data->set.qname |= new_data->set.qname;
1417
0
  nm_data->set.ns |= new_data->set.ns;
1418
0
  nm_data->wild.qname |= new_data->wild.qname;
1419
0
  nm_data->wild.ns |= new_data->wild.ns;
1420
0
  return (ISC_R_SUCCESS);
1421
0
}
1422
1423
static isc_result_t
1424
add_name(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
1425
0
   const dns_name_t *src_name) {
1426
0
  dns_rpz_nm_data_t new_data;
1427
0
  dns_fixedname_t trig_namef;
1428
0
  dns_name_t *trig_name = NULL;
1429
0
  isc_result_t result;
1430
1431
  /*
1432
   * We need a summary database of names even with 1 policy zone,
1433
   * because wildcard triggers are handled differently.
1434
   */
1435
1436
0
  trig_name = dns_fixedname_initname(&trig_namef);
1437
0
  name2data(rpz, rpz_type, src_name, trig_name, &new_data);
1438
1439
0
  result = add_nm(rpz->rpzs, trig_name, &new_data);
1440
1441
  /*
1442
   * Do not worry if the node already exists,
1443
   * because diff_apply() likes to add nodes before deleting.
1444
   */
1445
0
  if (result == ISC_R_EXISTS) {
1446
0
    return (ISC_R_SUCCESS);
1447
0
  }
1448
0
  if (result == ISC_R_SUCCESS) {
1449
0
    adj_trigger_cnt(rpz, rpz_type, NULL, 0, true);
1450
0
  }
1451
0
  return (result);
1452
0
}
1453
1454
/*
1455
 * Callback to free the data for a node in the summary RBT database.
1456
 */
1457
static void
1458
0
rpz_node_deleter(void *nm_data, void *mctx) {
1459
0
  isc_mem_put(mctx, nm_data, sizeof(dns_rpz_nm_data_t));
1460
0
}
1461
1462
/*
1463
 * Get ready for a new set of policy zones for a view.
1464
 */
1465
isc_result_t
1466
dns_rpz_new_zones(isc_mem_t *mctx, isc_loopmgr_t *loopmgr, char *rps_cstr,
1467
0
      size_t rps_cstr_size, dns_rpz_zones_t **rpzsp) {
1468
0
  dns_rpz_zones_t *rpzs = NULL;
1469
0
  isc_result_t result = ISC_R_SUCCESS;
1470
1471
0
  REQUIRE(rpzsp != NULL && *rpzsp == NULL);
1472
1473
0
  rpzs = isc_mem_get(mctx, sizeof(*rpzs));
1474
0
  *rpzs = (dns_rpz_zones_t){
1475
0
    .rps_cstr = rps_cstr,
1476
0
    .rps_cstr_size = rps_cstr_size,
1477
0
    .loopmgr = loopmgr,
1478
0
    .magic = DNS_RPZ_ZONES_MAGIC,
1479
0
  };
1480
1481
0
  isc_rwlock_init(&rpzs->search_lock);
1482
0
  isc_mutex_init(&rpzs->maint_lock);
1483
0
  isc_refcount_init(&rpzs->references, 1);
1484
1485
#ifdef USE_DNSRPS
1486
  if (rps_cstr != NULL) {
1487
    result = dns_dnsrps_view_init(rpzs, rps_cstr);
1488
    if (result != ISC_R_SUCCESS) {
1489
      goto cleanup_rbt;
1490
    }
1491
  }
1492
#else  /* ifdef USE_DNSRPS */
1493
0
  INSIST(!rpzs->p.dnsrps_enabled);
1494
0
#endif /* ifdef USE_DNSRPS */
1495
0
  if (!rpzs->p.dnsrps_enabled) {
1496
0
    result = dns_rbt_create(mctx, rpz_node_deleter, mctx,
1497
0
          &rpzs->rbt);
1498
0
  }
1499
1500
0
  if (result != ISC_R_SUCCESS) {
1501
0
    goto cleanup_rbt;
1502
0
  }
1503
1504
0
  isc_mem_attach(mctx, &rpzs->mctx);
1505
1506
0
  *rpzsp = rpzs;
1507
0
  return (ISC_R_SUCCESS);
1508
1509
0
cleanup_rbt:
1510
0
  isc_refcount_decrementz(&rpzs->references);
1511
0
  isc_refcount_destroy(&rpzs->references);
1512
0
  isc_mutex_destroy(&rpzs->maint_lock);
1513
0
  isc_rwlock_destroy(&rpzs->search_lock);
1514
0
  isc_mem_put(mctx, rpzs, sizeof(*rpzs));
1515
1516
0
  return (result);
1517
0
}
1518
1519
isc_result_t
1520
0
dns_rpz_new_zone(dns_rpz_zones_t *rpzs, dns_rpz_zone_t **rpzp) {
1521
0
  isc_result_t result;
1522
0
  dns_rpz_zone_t *rpz = NULL;
1523
1524
0
  REQUIRE(DNS_RPZ_ZONES_VALID(rpzs));
1525
0
  REQUIRE(rpzp != NULL && *rpzp == NULL);
1526
1527
0
  if (rpzs->p.num_zones >= DNS_RPZ_MAX_ZONES) {
1528
0
    return (ISC_R_NOSPACE);
1529
0
  }
1530
1531
0
  result = dns__rpz_shuttingdown(rpzs);
1532
0
  if (result != ISC_R_SUCCESS) {
1533
0
    return (result);
1534
0
  }
1535
1536
0
  rpz = isc_mem_get(rpzs->mctx, sizeof(*rpz));
1537
0
  *rpz = (dns_rpz_zone_t){
1538
0
    .addsoa = true,
1539
0
    .magic = DNS_RPZ_ZONE_MAGIC,
1540
0
    .rpzs = rpzs,
1541
0
  };
1542
1543
  /*
1544
   * This will never be used, but costs us nothing and
1545
   * simplifies update_from_db().
1546
   */
1547
1548
0
  isc_ht_init(&rpz->nodes, rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
1549
1550
0
  dns_name_init(&rpz->origin, NULL);
1551
0
  dns_name_init(&rpz->client_ip, NULL);
1552
0
  dns_name_init(&rpz->ip, NULL);
1553
0
  dns_name_init(&rpz->nsdname, NULL);
1554
0
  dns_name_init(&rpz->nsip, NULL);
1555
0
  dns_name_init(&rpz->passthru, NULL);
1556
0
  dns_name_init(&rpz->drop, NULL);
1557
0
  dns_name_init(&rpz->tcp_only, NULL);
1558
0
  dns_name_init(&rpz->cname, NULL);
1559
1560
0
  isc_time_settoepoch(&rpz->lastupdated);
1561
1562
0
  rpz->num = rpzs->p.num_zones++;
1563
0
  rpzs->zones[rpz->num] = rpz;
1564
1565
0
  *rpzp = rpz;
1566
1567
0
  return (ISC_R_SUCCESS);
1568
0
}
1569
1570
isc_result_t
1571
0
dns_rpz_dbupdate_callback(dns_db_t *db, void *fn_arg) {
1572
0
  dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)fn_arg;
1573
0
  isc_result_t result = ISC_R_SUCCESS;
1574
1575
0
  REQUIRE(DNS_DB_VALID(db));
1576
0
  REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
1577
1578
0
  LOCK(&rpz->rpzs->maint_lock);
1579
1580
0
  if (rpz->rpzs->shuttingdown) {
1581
0
    result = ISC_R_SHUTTINGDOWN;
1582
0
    goto unlock;
1583
0
  }
1584
1585
  /* New zone came as AXFR */
1586
0
  if (rpz->db != NULL && rpz->db != db) {
1587
    /* We need to clean up the old DB */
1588
0
    if (rpz->dbversion != NULL) {
1589
0
      dns_db_closeversion(rpz->db, &rpz->dbversion, false);
1590
0
    }
1591
0
    dns_db_updatenotify_unregister(rpz->db,
1592
0
                 dns_rpz_dbupdate_callback, rpz);
1593
0
    dns_db_detach(&rpz->db);
1594
0
  }
1595
1596
0
  if (rpz->db == NULL) {
1597
0
    RUNTIME_CHECK(rpz->dbversion == NULL);
1598
0
    dns_db_attach(db, &rpz->db);
1599
0
  }
1600
1601
0
  if (!rpz->updatepending && !rpz->updaterunning) {
1602
0
    rpz->updatepending = true;
1603
1604
0
    dns_db_currentversion(rpz->db, &rpz->dbversion);
1605
0
    dns__rpz_timer_start(rpz);
1606
0
  } else {
1607
0
    char dname[DNS_NAME_FORMATSIZE];
1608
0
    rpz->updatepending = true;
1609
1610
0
    dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE);
1611
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1612
0
            DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3),
1613
0
            "rpz: %s: update already queued or running",
1614
0
            dname);
1615
0
    if (rpz->dbversion != NULL) {
1616
0
      dns_db_closeversion(rpz->db, &rpz->dbversion, false);
1617
0
    }
1618
0
    dns_db_currentversion(rpz->db, &rpz->dbversion);
1619
0
  }
1620
1621
0
unlock:
1622
0
  UNLOCK(&rpz->rpzs->maint_lock);
1623
1624
0
  return (result);
1625
0
}
1626
1627
static void
1628
0
dns__rpz_timer_start(dns_rpz_zone_t *rpz) {
1629
0
  uint64_t tdiff;
1630
0
  isc_interval_t interval;
1631
0
  isc_time_t now;
1632
1633
0
  REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
1634
1635
0
  now = isc_time_now();
1636
0
  tdiff = isc_time_microdiff(&now, &rpz->lastupdated) / 1000000;
1637
0
  if (tdiff < rpz->min_update_interval) {
1638
0
    uint64_t defer = rpz->min_update_interval - tdiff;
1639
0
    char dname[DNS_NAME_FORMATSIZE];
1640
1641
0
    dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE);
1642
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1643
0
            DNS_LOGMODULE_MASTER, ISC_LOG_INFO,
1644
0
            "rpz: %s: new zone version came "
1645
0
            "too soon, deferring update for "
1646
0
            "%" PRIu64 " seconds",
1647
0
            dname, defer);
1648
0
    isc_interval_set(&interval, (unsigned int)defer, 0);
1649
0
  } else {
1650
0
    isc_interval_set(&interval, 0, 0);
1651
0
  }
1652
1653
0
  rpz->loop = isc_loop_current(rpz->rpzs->loopmgr);
1654
1655
0
  isc_timer_create(rpz->loop, dns__rpz_timer_cb, rpz, &rpz->updatetimer);
1656
0
  isc_timer_start(rpz->updatetimer, isc_timertype_once, &interval);
1657
0
}
1658
1659
static void
1660
0
dns__rpz_timer_stop(void *arg) {
1661
0
  dns_rpz_zone_t *rpz = arg;
1662
0
  REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
1663
1664
0
  isc_timer_stop(rpz->updatetimer);
1665
0
  isc_timer_destroy(&rpz->updatetimer);
1666
0
  rpz->loop = NULL;
1667
1668
0
  dns_rpz_unref_rpzs(rpz->rpzs);
1669
0
}
1670
1671
static void
1672
0
update_rpz_done_cb(void *data) {
1673
0
  dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)data;
1674
0
  char dname[DNS_NAME_FORMATSIZE];
1675
1676
0
  REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
1677
1678
0
  LOCK(&rpz->rpzs->maint_lock);
1679
0
  rpz->updaterunning = false;
1680
1681
0
  dns_name_format(&rpz->origin, dname, DNS_NAME_FORMATSIZE);
1682
1683
0
  if (rpz->updatepending && !rpz->rpzs->shuttingdown) {
1684
    /* Restart the timer */
1685
0
    dns__rpz_timer_start(rpz);
1686
0
  }
1687
1688
0
  dns_db_closeversion(rpz->updb, &rpz->updbversion, false);
1689
0
  dns_db_detach(&rpz->updb);
1690
1691
0
  UNLOCK(&rpz->rpzs->maint_lock);
1692
1693
0
  isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
1694
0
          ISC_LOG_INFO, "rpz: %s: reload done: %s", dname,
1695
0
          isc_result_totext(rpz->updateresult));
1696
1697
0
  dns_rpz_unref_rpzs(rpz->rpzs);
1698
0
}
1699
1700
static isc_result_t
1701
0
update_nodes(dns_rpz_zone_t *rpz, isc_ht_t *newnodes) {
1702
0
  isc_result_t result;
1703
0
  dns_dbiterator_t *updbit = NULL;
1704
0
  dns_name_t *name = NULL;
1705
0
  dns_fixedname_t fixname;
1706
0
  char domain[DNS_NAME_FORMATSIZE];
1707
1708
0
  dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
1709
1710
0
  name = dns_fixedname_initname(&fixname);
1711
1712
0
  result = dns_db_createiterator(rpz->updb, DNS_DB_NONSEC3, &updbit);
1713
0
  if (result != ISC_R_SUCCESS) {
1714
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1715
0
            DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1716
0
            "rpz: %s: failed to create DB iterator - %s",
1717
0
            domain, isc_result_totext(result));
1718
0
    return (result);
1719
0
  }
1720
1721
0
  result = dns_dbiterator_first(updbit);
1722
0
  if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
1723
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1724
0
            DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1725
0
            "rpz: %s: failed to get db iterator - %s", domain,
1726
0
            isc_result_totext(result));
1727
0
    goto cleanup;
1728
0
  }
1729
1730
0
  while (result == ISC_R_SUCCESS) {
1731
0
    char namebuf[DNS_NAME_FORMATSIZE];
1732
0
    dns_rdatasetiter_t *rdsiter = NULL;
1733
0
    dns_dbnode_t *node = NULL;
1734
1735
0
    result = dns__rpz_shuttingdown(rpz->rpzs);
1736
0
    if (result != ISC_R_SUCCESS) {
1737
0
      goto cleanup;
1738
0
    }
1739
1740
0
    result = dns_dbiterator_current(updbit, &node, name);
1741
0
    if (result != ISC_R_SUCCESS) {
1742
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1743
0
              DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1744
0
              "rpz: %s: failed to get dbiterator - %s",
1745
0
              domain, isc_result_totext(result));
1746
0
      goto cleanup;
1747
0
    }
1748
1749
0
    result = dns_dbiterator_pause(updbit);
1750
0
    RUNTIME_CHECK(result == ISC_R_SUCCESS);
1751
1752
0
    result = dns_db_allrdatasets(rpz->updb, node, rpz->updbversion,
1753
0
               0, 0, &rdsiter);
1754
0
    if (result != ISC_R_SUCCESS) {
1755
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1756
0
              DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1757
0
              "rpz: %s: failed to fetch "
1758
0
              "rrdatasets - %s",
1759
0
              domain, isc_result_totext(result));
1760
0
      dns_db_detachnode(rpz->updb, &node);
1761
0
      goto cleanup;
1762
0
    }
1763
1764
0
    result = dns_rdatasetiter_first(rdsiter);
1765
1766
0
    dns_rdatasetiter_destroy(&rdsiter);
1767
0
    dns_db_detachnode(rpz->updb, &node);
1768
1769
0
    if (result != ISC_R_SUCCESS) { /* skip empty non-terminal */
1770
0
      if (result != ISC_R_NOMORE) {
1771
0
        isc_log_write(
1772
0
          dns_lctx, DNS_LOGCATEGORY_GENERAL,
1773
0
          DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1774
0
          "rpz: %s: error %s while creating "
1775
0
          "rdatasetiter",
1776
0
          domain, isc_result_totext(result));
1777
0
      }
1778
0
      goto next;
1779
0
    }
1780
1781
0
    dns_name_downcase(name, name, NULL);
1782
1783
    /* Add entry to the new nodes table */
1784
0
    result = isc_ht_add(newnodes, name->ndata, name->length, rpz);
1785
0
    if (result != ISC_R_SUCCESS) {
1786
0
      dns_name_format(name, namebuf, sizeof(namebuf));
1787
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1788
0
              DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1789
0
              "rpz: %s, adding node %s to HT error %s",
1790
0
              domain, namebuf,
1791
0
              isc_result_totext(result));
1792
0
      goto next;
1793
0
    }
1794
1795
    /* Does the entry exist in the old nodes table? */
1796
0
    result = isc_ht_find(rpz->nodes, name->ndata, name->length,
1797
0
             NULL);
1798
0
    if (result == ISC_R_SUCCESS) { /* found */
1799
0
      isc_ht_delete(rpz->nodes, name->ndata, name->length);
1800
0
      goto next;
1801
0
    }
1802
1803
    /*
1804
     * Only the single rpz updates are serialized, so we need to
1805
     * lock here because we can be processing more updates to
1806
     * different rpz zones at the same time
1807
     */
1808
0
    LOCK(&rpz->rpzs->maint_lock);
1809
0
    result = rpz_add(rpz, name);
1810
0
    UNLOCK(&rpz->rpzs->maint_lock);
1811
1812
0
    if (result != ISC_R_SUCCESS) {
1813
0
      dns_name_format(name, namebuf, sizeof(namebuf));
1814
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1815
0
              DNS_LOGMODULE_MASTER, ISC_LOG_ERROR,
1816
0
              "rpz: %s: adding node %s "
1817
0
              "to RPZ error %s",
1818
0
              domain, namebuf,
1819
0
              isc_result_totext(result));
1820
0
    } else if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
1821
0
      dns_name_format(name, namebuf, sizeof(namebuf));
1822
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
1823
0
              DNS_LOGMODULE_MASTER, ISC_LOG_DEBUG(3),
1824
0
              "rpz: %s: adding node %s", domain,
1825
0
              namebuf);
1826
0
    }
1827
1828
0
  next:
1829
0
    result = dns_dbiterator_next(updbit);
1830
0
  }
1831
0
  INSIST(result != ISC_R_SUCCESS);
1832
0
  if (result == ISC_R_NOMORE) {
1833
0
    result = ISC_R_SUCCESS;
1834
0
  }
1835
1836
0
cleanup:
1837
0
  dns_dbiterator_destroy(&updbit);
1838
1839
0
  return (result);
1840
0
}
1841
1842
static isc_result_t
1843
0
cleanup_nodes(dns_rpz_zone_t *rpz) {
1844
0
  isc_result_t result;
1845
0
  isc_ht_iter_t *iter = NULL;
1846
0
  dns_name_t *name = NULL;
1847
0
  dns_fixedname_t fixname;
1848
1849
0
  name = dns_fixedname_initname(&fixname);
1850
1851
0
  isc_ht_iter_create(rpz->nodes, &iter);
1852
1853
0
  for (result = isc_ht_iter_first(iter); result == ISC_R_SUCCESS;
1854
0
       result = isc_ht_iter_delcurrent_next(iter))
1855
0
  {
1856
0
    isc_region_t region;
1857
0
    unsigned char *key = NULL;
1858
0
    size_t keysize;
1859
1860
0
    result = dns__rpz_shuttingdown(rpz->rpzs);
1861
0
    if (result != ISC_R_SUCCESS) {
1862
0
      break;
1863
0
    }
1864
1865
0
    isc_ht_iter_currentkey(iter, &key, &keysize);
1866
0
    region.base = key;
1867
0
    region.length = (unsigned int)keysize;
1868
0
    dns_name_fromregion(name, &region);
1869
1870
0
    LOCK(&rpz->rpzs->maint_lock);
1871
0
    rpz_del(rpz, name);
1872
0
    UNLOCK(&rpz->rpzs->maint_lock);
1873
0
  }
1874
0
  INSIST(result != ISC_R_SUCCESS);
1875
0
  if (result == ISC_R_NOMORE) {
1876
0
    result = ISC_R_SUCCESS;
1877
0
  }
1878
1879
0
  isc_ht_iter_destroy(&iter);
1880
1881
0
  return (result);
1882
0
}
1883
1884
static isc_result_t
1885
0
dns__rpz_shuttingdown(dns_rpz_zones_t *rpzs) {
1886
0
  bool shuttingdown = false;
1887
1888
0
  LOCK(&rpzs->maint_lock);
1889
0
  shuttingdown = rpzs->shuttingdown;
1890
0
  UNLOCK(&rpzs->maint_lock);
1891
1892
0
  if (shuttingdown) {
1893
0
    return (ISC_R_SHUTTINGDOWN);
1894
0
  }
1895
1896
0
  return (ISC_R_SUCCESS);
1897
0
}
1898
1899
static void
1900
0
update_rpz_cb(void *data) {
1901
0
  dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)data;
1902
0
  isc_result_t result = ISC_R_SUCCESS;
1903
0
  isc_ht_t *newnodes = NULL;
1904
1905
0
  REQUIRE(rpz->nodes != NULL);
1906
1907
0
  result = dns__rpz_shuttingdown(rpz->rpzs);
1908
0
  if (result != ISC_R_SUCCESS) {
1909
0
    goto shuttingdown;
1910
0
  }
1911
1912
0
  isc_ht_init(&newnodes, rpz->rpzs->mctx, 1, ISC_HT_CASE_SENSITIVE);
1913
1914
0
  result = update_nodes(rpz, newnodes);
1915
0
  if (result != ISC_R_SUCCESS) {
1916
0
    goto cleanup;
1917
0
  }
1918
1919
0
  result = cleanup_nodes(rpz);
1920
0
  if (result != ISC_R_SUCCESS) {
1921
0
    goto cleanup;
1922
0
  }
1923
1924
  /* Finalize the update */
1925
0
  ISC_SWAP(rpz->nodes, newnodes);
1926
1927
0
cleanup:
1928
0
  isc_ht_destroy(&newnodes);
1929
1930
0
shuttingdown:
1931
0
  rpz->updateresult = result;
1932
0
}
1933
1934
static void
1935
0
dns__rpz_timer_cb(void *arg) {
1936
0
  char domain[DNS_NAME_FORMATSIZE];
1937
0
  dns_rpz_zone_t *rpz = (dns_rpz_zone_t *)arg;
1938
1939
0
  REQUIRE(DNS_RPZ_ZONE_VALID(rpz));
1940
0
  REQUIRE(DNS_DB_VALID(rpz->db));
1941
0
  REQUIRE(rpz->updb == NULL);
1942
0
  REQUIRE(rpz->updbversion == NULL);
1943
1944
0
  LOCK(&rpz->rpzs->maint_lock);
1945
1946
0
  if (rpz->rpzs->shuttingdown) {
1947
0
    goto unlock;
1948
0
  }
1949
1950
0
  rpz->updatepending = false;
1951
0
  rpz->updaterunning = true;
1952
0
  rpz->updateresult = ISC_R_UNSET;
1953
1954
0
  dns_db_attach(rpz->db, &rpz->updb);
1955
0
  INSIST(rpz->dbversion != NULL);
1956
0
  rpz->updbversion = rpz->dbversion;
1957
0
  rpz->dbversion = NULL;
1958
1959
0
  dns_name_format(&rpz->origin, domain, DNS_NAME_FORMATSIZE);
1960
0
  isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_MASTER,
1961
0
          ISC_LOG_INFO, "rpz: %s: reload start", domain);
1962
1963
0
  dns_rpz_ref_rpzs(rpz->rpzs);
1964
0
  isc_work_enqueue(rpz->loop, update_rpz_cb, update_rpz_done_cb, rpz);
1965
1966
0
  isc_timer_destroy(&rpz->updatetimer);
1967
0
  rpz->loop = NULL;
1968
1969
0
  rpz->lastupdated = isc_time_now();
1970
0
unlock:
1971
0
  UNLOCK(&rpz->rpzs->maint_lock);
1972
0
}
1973
1974
/*
1975
 * Free the radix tree of a response policy database.
1976
 */
1977
static void
1978
0
cidr_free(dns_rpz_zones_t *rpzs) {
1979
0
  dns_rpz_cidr_node_t *cur = NULL, *child = NULL, *parent = NULL;
1980
1981
0
  cur = rpzs->cidr;
1982
0
  while (cur != NULL) {
1983
    /* Depth first. */
1984
0
    child = cur->child[0];
1985
0
    if (child != NULL) {
1986
0
      cur = child;
1987
0
      continue;
1988
0
    }
1989
0
    child = cur->child[1];
1990
0
    if (child != NULL) {
1991
0
      cur = child;
1992
0
      continue;
1993
0
    }
1994
1995
    /* Delete this leaf and go up. */
1996
0
    parent = cur->parent;
1997
0
    if (parent == NULL) {
1998
0
      rpzs->cidr = NULL;
1999
0
    } else {
2000
0
      parent->child[parent->child[1] == cur] = NULL;
2001
0
    }
2002
0
    isc_mem_put(rpzs->mctx, cur, sizeof(*cur));
2003
0
    cur = parent;
2004
0
  }
2005
0
}
2006
2007
static void
2008
0
dns__rpz_shutdown(dns_rpz_zone_t *rpz) {
2009
  /* maint_lock must be locked */
2010
0
  if (rpz->updatetimer != NULL) {
2011
    /* Don't wait for timer to trigger for shutdown */
2012
0
    INSIST(rpz->loop != NULL);
2013
2014
0
    dns_rpz_ref_rpzs(rpz->rpzs);
2015
0
    isc_async_run(rpz->loop, dns__rpz_timer_stop, rpz);
2016
0
  }
2017
0
}
2018
2019
static void
2020
0
dns_rpz_zone_destroy(dns_rpz_zone_t **rpzp) {
2021
0
  dns_rpz_zone_t *rpz = NULL;
2022
0
  dns_rpz_zones_t *rpzs;
2023
2024
0
  rpz = *rpzp;
2025
0
  *rpzp = NULL;
2026
2027
0
  rpzs = rpz->rpzs;
2028
0
  rpz->rpzs = NULL;
2029
2030
0
  if (dns_name_dynamic(&rpz->origin)) {
2031
0
    dns_name_free(&rpz->origin, rpzs->mctx);
2032
0
  }
2033
0
  if (dns_name_dynamic(&rpz->client_ip)) {
2034
0
    dns_name_free(&rpz->client_ip, rpzs->mctx);
2035
0
  }
2036
0
  if (dns_name_dynamic(&rpz->ip)) {
2037
0
    dns_name_free(&rpz->ip, rpzs->mctx);
2038
0
  }
2039
0
  if (dns_name_dynamic(&rpz->nsdname)) {
2040
0
    dns_name_free(&rpz->nsdname, rpzs->mctx);
2041
0
  }
2042
0
  if (dns_name_dynamic(&rpz->nsip)) {
2043
0
    dns_name_free(&rpz->nsip, rpzs->mctx);
2044
0
  }
2045
0
  if (dns_name_dynamic(&rpz->passthru)) {
2046
0
    dns_name_free(&rpz->passthru, rpzs->mctx);
2047
0
  }
2048
0
  if (dns_name_dynamic(&rpz->drop)) {
2049
0
    dns_name_free(&rpz->drop, rpzs->mctx);
2050
0
  }
2051
0
  if (dns_name_dynamic(&rpz->tcp_only)) {
2052
0
    dns_name_free(&rpz->tcp_only, rpzs->mctx);
2053
0
  }
2054
0
  if (dns_name_dynamic(&rpz->cname)) {
2055
0
    dns_name_free(&rpz->cname, rpzs->mctx);
2056
0
  }
2057
0
  if (rpz->db != NULL) {
2058
0
    if (rpz->dbversion != NULL) {
2059
0
      dns_db_closeversion(rpz->db, &rpz->dbversion, false);
2060
0
    }
2061
0
    dns_db_updatenotify_unregister(rpz->db,
2062
0
                 dns_rpz_dbupdate_callback, rpz);
2063
0
    dns_db_detach(&rpz->db);
2064
0
  }
2065
0
  INSIST(!rpz->updaterunning);
2066
2067
0
  isc_ht_destroy(&rpz->nodes);
2068
2069
0
  isc_mem_put(rpzs->mctx, rpz, sizeof(*rpz));
2070
0
}
2071
2072
static void
2073
0
dns__rpz_zones_destroy(dns_rpz_zones_t *rpzs) {
2074
0
  REQUIRE(rpzs->shuttingdown);
2075
2076
0
  isc_refcount_destroy(&rpzs->references);
2077
2078
0
  for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num)
2079
0
  {
2080
0
    if (rpzs->zones[rpz_num] == NULL) {
2081
0
      continue;
2082
0
    }
2083
2084
0
    dns_rpz_zone_destroy(&rpzs->zones[rpz_num]);
2085
0
  }
2086
2087
0
  if (rpzs->rps_cstr_size != 0) {
2088
#ifdef USE_DNSRPS
2089
    librpz->client_detach(&rpzs->rps_client);
2090
#endif /* ifdef USE_DNSRPS */
2091
0
    isc_mem_put(rpzs->mctx, rpzs->rps_cstr, rpzs->rps_cstr_size);
2092
0
  }
2093
2094
0
  cidr_free(rpzs);
2095
0
  if (rpzs->rbt != NULL) {
2096
0
    dns_rbt_destroy(&rpzs->rbt);
2097
0
  }
2098
0
  isc_mutex_destroy(&rpzs->maint_lock);
2099
0
  isc_rwlock_destroy(&rpzs->search_lock);
2100
0
  isc_mem_putanddetach(&rpzs->mctx, rpzs, sizeof(*rpzs));
2101
0
}
2102
2103
void
2104
0
dns_rpz_zones_shutdown(dns_rpz_zones_t *rpzs) {
2105
0
  REQUIRE(DNS_RPZ_ZONES_VALID(rpzs));
2106
  /*
2107
   * Forget the last of the view's rpz machinery when shutting down.
2108
   */
2109
2110
0
  LOCK(&rpzs->maint_lock);
2111
0
  if (rpzs->shuttingdown) {
2112
0
    UNLOCK(&rpzs->maint_lock);
2113
0
    return;
2114
0
  }
2115
2116
0
  rpzs->shuttingdown = true;
2117
2118
0
  for (dns_rpz_num_t rpz_num = 0; rpz_num < DNS_RPZ_MAX_ZONES; ++rpz_num)
2119
0
  {
2120
0
    if (rpzs->zones[rpz_num] == NULL) {
2121
0
      continue;
2122
0
    }
2123
2124
0
    dns__rpz_shutdown(rpzs->zones[rpz_num]);
2125
0
  }
2126
0
  UNLOCK(&rpzs->maint_lock);
2127
0
}
2128
2129
#ifdef DNS_RPZ_TRACE
2130
ISC_REFCOUNT_TRACE_IMPL(dns_rpz_zones, dns__rpz_zones_destroy);
2131
#else
2132
ISC_REFCOUNT_IMPL(dns_rpz_zones, dns__rpz_zones_destroy);
2133
#endif
2134
2135
/*
2136
 * Add an IP address to the radix tree or a name to the summary database.
2137
 */
2138
static isc_result_t
2139
0
rpz_add(dns_rpz_zone_t *rpz, const dns_name_t *src_name) {
2140
0
  dns_rpz_type_t rpz_type;
2141
0
  isc_result_t result = ISC_R_FAILURE;
2142
0
  dns_rpz_zones_t *rpzs = NULL;
2143
0
  dns_rpz_num_t rpz_num;
2144
2145
0
  REQUIRE(rpz != NULL);
2146
2147
0
  rpzs = rpz->rpzs;
2148
0
  rpz_num = rpz->num;
2149
2150
0
  REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
2151
2152
0
  RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2153
2154
0
  rpz_type = type_from_name(rpzs, rpz, src_name);
2155
2156
0
  switch (rpz_type) {
2157
0
  case DNS_RPZ_TYPE_QNAME:
2158
0
  case DNS_RPZ_TYPE_NSDNAME:
2159
0
    result = add_name(rpz, rpz_type, src_name);
2160
0
    break;
2161
0
  case DNS_RPZ_TYPE_CLIENT_IP:
2162
0
  case DNS_RPZ_TYPE_IP:
2163
0
  case DNS_RPZ_TYPE_NSIP:
2164
0
    result = add_cidr(rpz, rpz_type, src_name);
2165
0
    break;
2166
0
  case DNS_RPZ_TYPE_BAD:
2167
0
    break;
2168
0
  }
2169
0
  RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2170
2171
0
  return (result);
2172
0
}
2173
2174
/*
2175
 * Remove an IP address from the radix tree.
2176
 */
2177
static void
2178
del_cidr(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
2179
0
   const dns_name_t *src_name) {
2180
0
  isc_result_t result;
2181
0
  dns_rpz_cidr_key_t tgt_ip;
2182
0
  dns_rpz_prefix_t tgt_prefix;
2183
0
  dns_rpz_addr_zbits_t tgt_set;
2184
0
  dns_rpz_cidr_node_t *tgt = NULL, *parent = NULL, *child = NULL;
2185
2186
  /*
2187
   * Do not worry about invalid rpz IP address names.  If we
2188
   * are here, then something relevant was added and so was
2189
   * valid.  Invalid names here are usually internal RBTDB nodes.
2190
   */
2191
0
  result = name2ipkey(DNS_RPZ_DEBUG_QUIET, rpz, rpz_type, src_name,
2192
0
          &tgt_ip, &tgt_prefix, &tgt_set);
2193
0
  if (result != ISC_R_SUCCESS) {
2194
0
    return;
2195
0
  }
2196
2197
0
  result = search(rpz->rpzs, &tgt_ip, tgt_prefix, &tgt_set, false, &tgt);
2198
0
  if (result != ISC_R_SUCCESS) {
2199
0
    INSIST(result == ISC_R_NOTFOUND ||
2200
0
           result == DNS_R_PARTIALMATCH);
2201
    /*
2202
     * Do not worry about missing summary RBT nodes that probably
2203
     * correspond to RBTDB nodes that were implicit RBT nodes
2204
     * that were later added for (often empty) wildcards
2205
     * and then to the RBTDB deferred cleanup list.
2206
     */
2207
0
    return;
2208
0
  }
2209
2210
  /*
2211
   * Mark the node and its parents to reflect the deleted IP address.
2212
   * Do not count bits that are already clear for internal RBTDB nodes.
2213
   */
2214
0
  tgt_set.client_ip &= tgt->set.client_ip;
2215
0
  tgt_set.ip &= tgt->set.ip;
2216
0
  tgt_set.nsip &= tgt->set.nsip;
2217
0
  tgt->set.client_ip &= ~tgt_set.client_ip;
2218
0
  tgt->set.ip &= ~tgt_set.ip;
2219
0
  tgt->set.nsip &= ~tgt_set.nsip;
2220
0
  set_sum_pair(tgt);
2221
2222
0
  adj_trigger_cnt(rpz, rpz_type, &tgt_ip, tgt_prefix, false);
2223
2224
  /*
2225
   * We might need to delete 2 nodes.
2226
   */
2227
0
  do {
2228
    /*
2229
     * The node is now useless if it has no data of its own
2230
     * and 0 or 1 children.  We are finished if it is not
2231
     * useless.
2232
     */
2233
0
    if ((child = tgt->child[0]) != NULL) {
2234
0
      if (tgt->child[1] != NULL) {
2235
0
        break;
2236
0
      }
2237
0
    } else {
2238
0
      child = tgt->child[1];
2239
0
    }
2240
0
    if (tgt->set.client_ip != 0 || tgt->set.ip != 0 ||
2241
0
        tgt->set.nsip != 0)
2242
0
    {
2243
0
      break;
2244
0
    }
2245
2246
    /*
2247
     * Replace the pointer to this node in the parent with
2248
     * the remaining child or NULL.
2249
     */
2250
0
    parent = tgt->parent;
2251
0
    if (parent == NULL) {
2252
0
      rpz->rpzs->cidr = child;
2253
0
    } else {
2254
0
      parent->child[parent->child[1] == tgt] = child;
2255
0
    }
2256
2257
    /*
2258
     * If the child exists fix up its parent pointer.
2259
     */
2260
0
    if (child != NULL) {
2261
0
      child->parent = parent;
2262
0
    }
2263
0
    isc_mem_put(rpz->rpzs->mctx, tgt, sizeof(*tgt));
2264
2265
0
    tgt = parent;
2266
0
  } while (tgt != NULL);
2267
0
}
2268
2269
static void
2270
del_name(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
2271
0
   const dns_name_t *src_name) {
2272
0
  char namebuf[DNS_NAME_FORMATSIZE];
2273
0
  dns_fixedname_t trig_namef;
2274
0
  dns_name_t *trig_name = NULL;
2275
0
  dns_rbtnode_t *nmnode = NULL;
2276
0
  dns_rpz_nm_data_t *nm_data = NULL;
2277
0
  dns_rpz_nm_data_t del_data;
2278
0
  isc_result_t result;
2279
0
  bool exists;
2280
2281
  /*
2282
   * We need a summary database of names even with 1 policy zone,
2283
   * because wildcard triggers are handled differently.
2284
   */
2285
2286
0
  trig_name = dns_fixedname_initname(&trig_namef);
2287
0
  name2data(rpz, rpz_type, src_name, trig_name, &del_data);
2288
2289
0
  nmnode = NULL;
2290
0
  result = dns_rbt_findnode(rpz->rpzs->rbt, trig_name, NULL, &nmnode,
2291
0
          NULL, 0, NULL, NULL);
2292
0
  if (result != ISC_R_SUCCESS) {
2293
    /*
2294
     * Do not worry about missing summary RBT nodes that probably
2295
     * correspond to RBTDB nodes that were implicit RBT nodes
2296
     * that were later added for (often empty) wildcards
2297
     * and then to the RBTDB deferred cleanup list.
2298
     */
2299
0
    if (result == ISC_R_NOTFOUND || result == DNS_R_PARTIALMATCH) {
2300
0
      return;
2301
0
    }
2302
0
    dns_name_format(src_name, namebuf, sizeof(namebuf));
2303
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2304
0
            DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2305
0
            "rpz del_name(%s) node search failed: %s",
2306
0
            namebuf, isc_result_totext(result));
2307
0
    return;
2308
0
  }
2309
2310
0
  nm_data = nmnode->data;
2311
0
  INSIST(nm_data != NULL);
2312
2313
  /*
2314
   * Do not count bits that next existed for RBT nodes that would we
2315
   * would not have found in a summary for a single RBTDB tree.
2316
   */
2317
0
  del_data.set.qname &= nm_data->set.qname;
2318
0
  del_data.set.ns &= nm_data->set.ns;
2319
0
  del_data.wild.qname &= nm_data->wild.qname;
2320
0
  del_data.wild.ns &= nm_data->wild.ns;
2321
2322
0
  exists = (del_data.set.qname != 0 || del_data.set.ns != 0 ||
2323
0
      del_data.wild.qname != 0 || del_data.wild.ns != 0);
2324
2325
0
  nm_data->set.qname &= ~del_data.set.qname;
2326
0
  nm_data->set.ns &= ~del_data.set.ns;
2327
0
  nm_data->wild.qname &= ~del_data.wild.qname;
2328
0
  nm_data->wild.ns &= ~del_data.wild.ns;
2329
2330
0
  if (nm_data->set.qname == 0 && nm_data->set.ns == 0 &&
2331
0
      nm_data->wild.qname == 0 && nm_data->wild.ns == 0)
2332
0
  {
2333
0
    result = dns_rbt_deletenode(rpz->rpzs->rbt, nmnode, false);
2334
0
    if (result != ISC_R_SUCCESS) {
2335
      /*
2336
       * bin/tests/system/rpz/tests.sh looks for
2337
       * "rpz.*failed".
2338
       */
2339
0
      dns_name_format(src_name, namebuf, sizeof(namebuf));
2340
0
      isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2341
0
              DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2342
0
              "rpz del_name(%s) node delete "
2343
0
              "failed: %s",
2344
0
              namebuf, isc_result_totext(result));
2345
0
    }
2346
0
  }
2347
2348
0
  if (exists) {
2349
0
    adj_trigger_cnt(rpz, rpz_type, NULL, 0, false);
2350
0
  }
2351
0
}
2352
2353
/*
2354
 * Remove an IP address from the radix tree or a name from the summary database.
2355
 */
2356
static void
2357
0
rpz_del(dns_rpz_zone_t *rpz, const dns_name_t *src_name) {
2358
0
  dns_rpz_type_t rpz_type;
2359
0
  dns_rpz_zones_t *rpzs = NULL;
2360
0
  dns_rpz_num_t rpz_num;
2361
2362
0
  REQUIRE(rpz != NULL);
2363
2364
0
  rpzs = rpz->rpzs;
2365
0
  rpz_num = rpz->num;
2366
2367
0
  REQUIRE(rpzs != NULL && rpz_num < rpzs->p.num_zones);
2368
2369
0
  RWLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2370
2371
0
  rpz_type = type_from_name(rpzs, rpz, src_name);
2372
2373
0
  switch (rpz_type) {
2374
0
  case DNS_RPZ_TYPE_QNAME:
2375
0
  case DNS_RPZ_TYPE_NSDNAME:
2376
0
    del_name(rpz, rpz_type, src_name);
2377
0
    break;
2378
0
  case DNS_RPZ_TYPE_CLIENT_IP:
2379
0
  case DNS_RPZ_TYPE_IP:
2380
0
  case DNS_RPZ_TYPE_NSIP:
2381
0
    del_cidr(rpz, rpz_type, src_name);
2382
0
    break;
2383
0
  case DNS_RPZ_TYPE_BAD:
2384
0
    break;
2385
0
  }
2386
2387
0
  RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_write);
2388
0
}
2389
2390
/*
2391
 * Search the summary radix tree to get a relative owner name in a
2392
 * policy zone relevant to a triggering IP address.
2393
 *  rpz_type and zbits limit the search for IP address netaddr
2394
 *  return the policy zone's number or DNS_RPZ_INVALID_NUM
2395
 *  ip_name is the relative owner name found and
2396
 *  *prefixp is its prefix length.
2397
 */
2398
dns_rpz_num_t
2399
dns_rpz_find_ip(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
2400
    dns_rpz_zbits_t zbits, const isc_netaddr_t *netaddr,
2401
0
    dns_name_t *ip_name, dns_rpz_prefix_t *prefixp) {
2402
0
  dns_rpz_cidr_key_t tgt_ip;
2403
0
  dns_rpz_addr_zbits_t tgt_set;
2404
0
  dns_rpz_cidr_node_t *found = NULL;
2405
0
  isc_result_t result;
2406
0
  dns_rpz_num_t rpz_num = 0;
2407
0
  dns_rpz_have_t have;
2408
0
  int i;
2409
2410
0
  RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2411
0
  have = rpzs->have;
2412
0
  RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2413
2414
  /*
2415
   * Convert IP address to CIDR tree key.
2416
   */
2417
0
  if (netaddr->family == AF_INET) {
2418
0
    tgt_ip.w[0] = 0;
2419
0
    tgt_ip.w[1] = 0;
2420
0
    tgt_ip.w[2] = ADDR_V4MAPPED;
2421
0
    tgt_ip.w[3] = ntohl(netaddr->type.in.s_addr);
2422
0
    switch (rpz_type) {
2423
0
    case DNS_RPZ_TYPE_CLIENT_IP:
2424
0
      zbits &= have.client_ipv4;
2425
0
      break;
2426
0
    case DNS_RPZ_TYPE_IP:
2427
0
      zbits &= have.ipv4;
2428
0
      break;
2429
0
    case DNS_RPZ_TYPE_NSIP:
2430
0
      zbits &= have.nsipv4;
2431
0
      break;
2432
0
    default:
2433
0
      UNREACHABLE();
2434
0
      break;
2435
0
    }
2436
0
  } else if (netaddr->family == AF_INET6) {
2437
0
    dns_rpz_cidr_key_t src_ip6;
2438
2439
    /*
2440
     * Given the int aligned struct in_addr member of netaddr->type
2441
     * one could cast netaddr->type.in6 to dns_rpz_cidr_key_t *,
2442
     * but some people object.
2443
     */
2444
0
    memmove(src_ip6.w, &netaddr->type.in6, sizeof(src_ip6.w));
2445
0
    for (i = 0; i < 4; i++) {
2446
0
      tgt_ip.w[i] = ntohl(src_ip6.w[i]);
2447
0
    }
2448
0
    switch (rpz_type) {
2449
0
    case DNS_RPZ_TYPE_CLIENT_IP:
2450
0
      zbits &= have.client_ipv6;
2451
0
      break;
2452
0
    case DNS_RPZ_TYPE_IP:
2453
0
      zbits &= have.ipv6;
2454
0
      break;
2455
0
    case DNS_RPZ_TYPE_NSIP:
2456
0
      zbits &= have.nsipv6;
2457
0
      break;
2458
0
    default:
2459
0
      UNREACHABLE();
2460
0
      break;
2461
0
    }
2462
0
  } else {
2463
0
    return (DNS_RPZ_INVALID_NUM);
2464
0
  }
2465
2466
0
  if (zbits == 0) {
2467
0
    return (DNS_RPZ_INVALID_NUM);
2468
0
  }
2469
0
  make_addr_set(&tgt_set, zbits, rpz_type);
2470
2471
0
  RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2472
0
  result = search(rpzs, &tgt_ip, 128, &tgt_set, false, &found);
2473
0
  if (result == ISC_R_NOTFOUND) {
2474
    /*
2475
     * There are no eligible zones for this IP address.
2476
     */
2477
0
    RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2478
0
    return (DNS_RPZ_INVALID_NUM);
2479
0
  }
2480
2481
  /*
2482
   * Construct the trigger name for the longest matching trigger
2483
   * in the first eligible zone with a match.
2484
   */
2485
0
  *prefixp = found->prefix;
2486
0
  switch (rpz_type) {
2487
0
  case DNS_RPZ_TYPE_CLIENT_IP:
2488
0
    rpz_num = zbit_to_num(found->set.client_ip & tgt_set.client_ip);
2489
0
    break;
2490
0
  case DNS_RPZ_TYPE_IP:
2491
0
    rpz_num = zbit_to_num(found->set.ip & tgt_set.ip);
2492
0
    break;
2493
0
  case DNS_RPZ_TYPE_NSIP:
2494
0
    rpz_num = zbit_to_num(found->set.nsip & tgt_set.nsip);
2495
0
    break;
2496
0
  default:
2497
0
    UNREACHABLE();
2498
0
  }
2499
0
  result = ip2name(&found->ip, found->prefix, dns_rootname, ip_name);
2500
0
  RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2501
0
  if (result != ISC_R_SUCCESS) {
2502
    /*
2503
     * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2504
     */
2505
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2506
0
            DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2507
0
            "rpz ip2name() failed: %s",
2508
0
            isc_result_totext(result));
2509
0
    return (DNS_RPZ_INVALID_NUM);
2510
0
  }
2511
0
  return (rpz_num);
2512
0
}
2513
2514
/*
2515
 * Search the summary radix tree for policy zones with triggers matching
2516
 * a name.
2517
 */
2518
dns_rpz_zbits_t
2519
dns_rpz_find_name(dns_rpz_zones_t *rpzs, dns_rpz_type_t rpz_type,
2520
0
      dns_rpz_zbits_t zbits, dns_name_t *trig_name) {
2521
0
  char namebuf[DNS_NAME_FORMATSIZE];
2522
0
  dns_rbtnode_t *nmnode = NULL;
2523
0
  const dns_rpz_nm_data_t *nm_data = NULL;
2524
0
  dns_rpz_zbits_t found_zbits;
2525
0
  dns_rbtnodechain_t chain;
2526
0
  isc_result_t result;
2527
0
  int i;
2528
2529
0
  if (zbits == 0) {
2530
0
    return (0);
2531
0
  }
2532
2533
0
  found_zbits = 0;
2534
2535
0
  dns_rbtnodechain_init(&chain);
2536
2537
0
  RWLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2538
2539
0
  nmnode = NULL;
2540
0
  result = dns_rbt_findnode(rpzs->rbt, trig_name, NULL, &nmnode, &chain,
2541
0
          DNS_RBTFIND_EMPTYDATA, NULL, NULL);
2542
2543
0
  switch (result) {
2544
0
  case ISC_R_SUCCESS:
2545
0
    nm_data = nmnode->data;
2546
0
    if (nm_data != NULL) {
2547
0
      if (rpz_type == DNS_RPZ_TYPE_QNAME) {
2548
0
        found_zbits = nm_data->set.qname;
2549
0
      } else {
2550
0
        found_zbits = nm_data->set.ns;
2551
0
      }
2552
0
    }
2553
0
    FALLTHROUGH;
2554
2555
0
  case DNS_R_PARTIALMATCH:
2556
0
    i = chain.level_matches;
2557
0
    nmnode = chain.levels[chain.level_matches];
2558
2559
    /*
2560
     * Whenever an exact match is found by dns_rbt_findnode(),
2561
     * the highest level node in the chain will not be put into
2562
     * chain->levels[] array, but instead the chain->end
2563
     * pointer will be adjusted to point to that node.
2564
     *
2565
     * Suppose we have the following entries in a rpz zone:
2566
     *   example.com     CNAME rpz-passthru.
2567
     *   *.example.com   CNAME rpz-passthru.
2568
     *
2569
     * A query for www.example.com would result in the
2570
     * following chain object returned by dns_rbt_findnode():
2571
     *   chain->level_count = 2
2572
     *   chain->level_matches = 2
2573
     *   chain->levels[0] = .
2574
     *   chain->levels[1] = example.com
2575
     *   chain->levels[2] = NULL
2576
     *   chain->end = www
2577
     *
2578
     * Since exact matches only care for testing rpz set bits,
2579
     * we need to test for rpz wild bits through iterating the
2580
     * nodechain, and that includes testing the rpz wild bits
2581
     * in the highest level node found. In the case of an exact
2582
     * match, chain->levels[chain->level_matches] will be NULL,
2583
     * to address that we must use chain->end as the start
2584
     * point, then iterate over the remaining levels in the
2585
     * chain.
2586
     */
2587
0
    if (nmnode == NULL) {
2588
0
      --i;
2589
0
      nmnode = chain.end;
2590
0
    }
2591
2592
0
    while (nmnode != NULL) {
2593
0
      nm_data = nmnode->data;
2594
0
      if (nm_data != NULL) {
2595
0
        if (rpz_type == DNS_RPZ_TYPE_QNAME) {
2596
0
          found_zbits |= nm_data->wild.qname;
2597
0
        } else {
2598
0
          found_zbits |= nm_data->wild.ns;
2599
0
        }
2600
0
      }
2601
2602
0
      if (i >= 0) {
2603
0
        nmnode = chain.levels[i];
2604
0
        --i;
2605
0
      } else {
2606
0
        break;
2607
0
      }
2608
0
    }
2609
0
    break;
2610
2611
0
  case ISC_R_NOTFOUND:
2612
0
    break;
2613
2614
0
  default:
2615
    /*
2616
     * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
2617
     */
2618
0
    dns_name_format(trig_name, namebuf, sizeof(namebuf));
2619
0
    isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
2620
0
            DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
2621
0
            "dns_rpz_find_name(%s) failed: %s", namebuf,
2622
0
            isc_result_totext(result));
2623
0
    break;
2624
0
  }
2625
2626
0
  RWUNLOCK(&rpzs->search_lock, isc_rwlocktype_read);
2627
2628
0
  dns_rbtnodechain_invalidate(&chain);
2629
2630
0
  return (zbits & found_zbits);
2631
0
}
2632
2633
/*
2634
 * Translate CNAME rdata to a QNAME response policy action.
2635
 */
2636
dns_rpz_policy_t
2637
dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
2638
0
         dns_name_t *selfname) {
2639
0
  dns_rdata_t rdata = DNS_RDATA_INIT;
2640
0
  dns_rdata_cname_t cname;
2641
0
  isc_result_t result;
2642
2643
0
  result = dns_rdataset_first(rdataset);
2644
0
  INSIST(result == ISC_R_SUCCESS);
2645
0
  dns_rdataset_current(rdataset, &rdata);
2646
0
  result = dns_rdata_tostruct(&rdata, &cname, NULL);
2647
0
  INSIST(result == ISC_R_SUCCESS);
2648
0
  dns_rdata_reset(&rdata);
2649
2650
  /*
2651
   * CNAME . means NXDOMAIN
2652
   */
2653
0
  if (dns_name_equal(&cname.cname, dns_rootname)) {
2654
0
    return (DNS_RPZ_POLICY_NXDOMAIN);
2655
0
  }
2656
2657
0
  if (dns_name_iswildcard(&cname.cname)) {
2658
    /*
2659
     * CNAME *. means NODATA
2660
     */
2661
0
    if (dns_name_countlabels(&cname.cname) == 2) {
2662
0
      return (DNS_RPZ_POLICY_NODATA);
2663
0
    }
2664
2665
    /*
2666
     * A qname of www.evil.com and a policy of
2667
     *  *.evil.com    CNAME   *.garden.net
2668
     * gives a result of
2669
     *  evil.com    CNAME   evil.com.garden.net
2670
     */
2671
0
    if (dns_name_countlabels(&cname.cname) > 2) {
2672
0
      return (DNS_RPZ_POLICY_WILDCNAME);
2673
0
    }
2674
0
  }
2675
2676
  /*
2677
   * CNAME rpz-tcp-only. means "send truncated UDP responses."
2678
   */
2679
0
  if (dns_name_equal(&cname.cname, &rpz->tcp_only)) {
2680
0
    return (DNS_RPZ_POLICY_TCP_ONLY);
2681
0
  }
2682
2683
  /*
2684
   * CNAME rpz-drop. means "do not respond."
2685
   */
2686
0
  if (dns_name_equal(&cname.cname, &rpz->drop)) {
2687
0
    return (DNS_RPZ_POLICY_DROP);
2688
0
  }
2689
2690
  /*
2691
   * CNAME rpz-passthru. means "do not rewrite."
2692
   */
2693
0
  if (dns_name_equal(&cname.cname, &rpz->passthru)) {
2694
0
    return (DNS_RPZ_POLICY_PASSTHRU);
2695
0
  }
2696
2697
  /*
2698
   * 128.1.0.127.rpz-ip CNAME  128.1.0.0.127. is obsolete PASSTHRU
2699
   */
2700
0
  if (selfname != NULL && dns_name_equal(&cname.cname, selfname)) {
2701
0
    return (DNS_RPZ_POLICY_PASSTHRU);
2702
0
  }
2703
2704
  /*
2705
   * Any other rdata gives a response consisting of the rdata.
2706
   */
2707
0
  return (DNS_RPZ_POLICY_RECORD);
2708
0
}