/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 | } |