Coverage Report

Created: 2025-12-14 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/bind9/lib/dns/order.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 <stdbool.h>
17
18
#include <isc/magic.h>
19
#include <isc/mem.h>
20
#include <isc/refcount.h>
21
#include <isc/types.h>
22
#include <isc/util.h>
23
24
#include <dns/fixedname.h>
25
#include <dns/name.h>
26
#include <dns/order.h>
27
#include <dns/rdataset.h>
28
#include <dns/types.h>
29
30
typedef struct dns_order_ent dns_order_ent_t;
31
struct dns_order_ent {
32
  dns_fixedname_t name;
33
  dns_rdataclass_t rdclass;
34
  dns_rdatatype_t rdtype;
35
  dns_orderopt_t mode;
36
  ISC_LINK(dns_order_ent_t) link;
37
};
38
39
struct dns_order {
40
  unsigned int magic;
41
  isc_refcount_t references;
42
  ISC_LIST(dns_order_ent_t) ents;
43
  isc_mem_t *mctx;
44
};
45
46
2
#define DNS_ORDER_MAGIC        ISC_MAGIC('O', 'r', 'd', 'r')
47
#define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC)
48
49
void
50
2
dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) {
51
2
  dns_order_t *order = NULL;
52
53
2
  REQUIRE(orderp != NULL && *orderp == NULL);
54
55
2
  order = isc_mem_get(mctx, sizeof(*order));
56
2
  *order = (dns_order_t){
57
2
    .ents = ISC_LIST_INITIALIZER,
58
2
    .references = ISC_REFCOUNT_INITIALIZER(1),
59
2
    .magic = DNS_ORDER_MAGIC,
60
2
  };
61
62
2
  isc_mem_attach(mctx, &order->mctx);
63
2
  *orderp = order;
64
2
}
65
66
void
67
dns_order_add(dns_order_t *order, const dns_name_t *name,
68
        dns_rdatatype_t rdtype, dns_rdataclass_t rdclass,
69
0
        dns_orderopt_t mode) {
70
0
  dns_order_ent_t *ent = NULL;
71
72
0
  REQUIRE(DNS_ORDER_VALID(order));
73
74
0
  ent = isc_mem_get(order->mctx, sizeof(*ent));
75
0
  *ent = (dns_order_ent_t){
76
0
    .rdtype = rdtype,
77
0
    .rdclass = rdclass,
78
0
    .mode = mode,
79
0
    .link = ISC_LINK_INITIALIZER,
80
0
  };
81
82
0
  dns_fixedname_init(&ent->name);
83
0
  dns_name_copy(name, dns_fixedname_name(&ent->name));
84
85
0
  ISC_LIST_INITANDAPPEND(order->ents, ent, link);
86
0
}
87
88
static bool
89
0
match(const dns_name_t *name1, const dns_name_t *name2) {
90
0
  if (dns_name_iswildcard(name2)) {
91
0
    return dns_name_matcheswildcard(name1, name2);
92
0
  }
93
0
  return dns_name_equal(name1, name2);
94
0
}
95
96
dns_orderopt_t
97
dns_order_find(dns_order_t *order, const dns_name_t *name,
98
0
         dns_rdatatype_t rdtype, dns_rdataclass_t rdclass) {
99
0
  REQUIRE(DNS_ORDER_VALID(order));
100
101
0
  ISC_LIST_FOREACH(order->ents, ent, link) {
102
0
    if (ent->rdtype != rdtype && ent->rdtype != dns_rdatatype_any) {
103
0
      continue;
104
0
    }
105
0
    if (ent->rdclass != rdclass &&
106
0
        ent->rdclass != dns_rdataclass_any)
107
0
    {
108
0
      continue;
109
0
    }
110
0
    if (match(name, dns_fixedname_name(&ent->name))) {
111
0
      return ent->mode;
112
0
    }
113
0
  }
114
0
  return dns_order_none;
115
0
}
116
117
void
118
0
dns_order_attach(dns_order_t *source, dns_order_t **target) {
119
0
  REQUIRE(DNS_ORDER_VALID(source));
120
0
  REQUIRE(target != NULL && *target == NULL);
121
0
  isc_refcount_increment(&source->references);
122
0
  *target = source;
123
0
}
124
125
void
126
0
dns_order_detach(dns_order_t **orderp) {
127
0
  REQUIRE(orderp != NULL && DNS_ORDER_VALID(*orderp));
128
0
  dns_order_t *order = *orderp;
129
0
  *orderp = NULL;
130
131
0
  if (isc_refcount_decrement(&order->references) == 1) {
132
0
    isc_refcount_destroy(&order->references);
133
0
    order->magic = 0;
134
0
    ISC_LIST_FOREACH(order->ents, ent, link) {
135
0
      ISC_LIST_UNLINK(order->ents, ent, link);
136
0
      isc_mem_put(order->mctx, ent, sizeof(*ent));
137
0
    }
138
    isc_mem_putanddetach(&order->mctx, order, sizeof(*order));
139
0
  }
140
0
}