Coverage Report

Created: 2025-11-24 06:17

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