1 /* $NetBSD: order.c,v 1.4 2014/12/10 04:37:58 christos Exp $ */
4 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
5 * Copyright (C) 2002 Internet Software Consortium.
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17 * PERFORMANCE OF THIS SOFTWARE.
20 /* Id: order.c,v 1.10 2007/06/19 23:47:16 tbox Exp */
26 #include <isc/magic.h>
28 #include <isc/types.h>
30 #include <isc/refcount.h>
32 #include <dns/fixedname.h>
34 #include <dns/order.h>
35 #include <dns/rdataset.h>
36 #include <dns/types.h>
38 typedef struct dns_order_ent dns_order_ent_t
;
39 struct dns_order_ent
{
41 dns_rdataclass_t rdclass
;
42 dns_rdatatype_t rdtype
;
44 ISC_LINK(dns_order_ent_t
) link
;
49 isc_refcount_t references
;
50 ISC_LIST(dns_order_ent_t
) ents
;
54 #define DNS_ORDER_MAGIC ISC_MAGIC('O','r','d','r')
55 #define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC)
58 dns_order_create(isc_mem_t
*mctx
, dns_order_t
**orderp
) {
62 REQUIRE(orderp
!= NULL
&& *orderp
== NULL
);
64 order
= isc_mem_get(mctx
, sizeof(*order
));
66 return (ISC_R_NOMEMORY
);
68 ISC_LIST_INIT(order
->ents
);
70 /* Implicit attach. */
71 result
= isc_refcount_init(&order
->references
, 1);
72 if (result
!= ISC_R_SUCCESS
) {
73 isc_mem_put(mctx
, order
, sizeof(*order
));
78 isc_mem_attach(mctx
, &order
->mctx
);
79 order
->magic
= DNS_ORDER_MAGIC
;
81 return (ISC_R_SUCCESS
);
85 dns_order_add(dns_order_t
*order
, dns_name_t
*name
,
86 dns_rdatatype_t rdtype
, dns_rdataclass_t rdclass
,
91 REQUIRE(DNS_ORDER_VALID(order
));
92 REQUIRE(mode
== DNS_RDATASETATTR_RANDOMIZE
||
93 mode
== DNS_RDATASETATTR_FIXEDORDER
||
94 mode
== 0 /* DNS_RDATASETATTR_CYCLIC */ );
96 ent
= isc_mem_get(order
->mctx
, sizeof(*ent
));
98 return (ISC_R_NOMEMORY
);
100 dns_fixedname_init(&ent
->name
);
101 RUNTIME_CHECK(dns_name_copy(name
, dns_fixedname_name(&ent
->name
), NULL
)
103 ent
->rdtype
= rdtype
;
104 ent
->rdclass
= rdclass
;
106 ISC_LINK_INIT(ent
, link
);
107 ISC_LIST_INITANDAPPEND(order
->ents
, ent
, link
);
108 return (ISC_R_SUCCESS
);
111 static inline isc_boolean_t
112 match(dns_name_t
*name1
, dns_name_t
*name2
) {
114 if (dns_name_iswildcard(name2
))
115 return(dns_name_matcheswildcard(name1
, name2
));
116 return (dns_name_equal(name1
, name2
));
120 dns_order_find(dns_order_t
*order
, dns_name_t
*name
,
121 dns_rdatatype_t rdtype
, dns_rdataclass_t rdclass
)
123 dns_order_ent_t
*ent
;
124 REQUIRE(DNS_ORDER_VALID(order
));
126 for (ent
= ISC_LIST_HEAD(order
->ents
);
128 ent
= ISC_LIST_NEXT(ent
, link
)) {
129 if (ent
->rdtype
!= rdtype
&& ent
->rdtype
!= dns_rdatatype_any
)
131 if (ent
->rdclass
!= rdclass
&&
132 ent
->rdclass
!= dns_rdataclass_any
)
134 if (match(name
, dns_fixedname_name(&ent
->name
)))
141 dns_order_attach(dns_order_t
*source
, dns_order_t
**target
) {
142 REQUIRE(DNS_ORDER_VALID(source
));
143 REQUIRE(target
!= NULL
&& *target
== NULL
);
144 isc_refcount_increment(&source
->references
, NULL
);
149 dns_order_detach(dns_order_t
**orderp
) {
151 dns_order_ent_t
*ent
;
152 unsigned int references
;
154 REQUIRE(orderp
!= NULL
);
156 REQUIRE(DNS_ORDER_VALID(order
));
157 isc_refcount_decrement(&order
->references
, &references
);
163 while ((ent
= ISC_LIST_HEAD(order
->ents
)) != NULL
) {
164 ISC_LIST_UNLINK(order
->ents
, ent
, link
);
165 isc_mem_put(order
->mctx
, ent
, sizeof(*ent
));
167 isc_refcount_destroy(&order
->references
);
168 isc_mem_putanddetach(&order
->mctx
, order
, sizeof(*order
));