2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2002 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: order.c,v 1.10 2007/06/19 23:47:16 tbox Exp $ */
24 #include <isc/magic.h>
26 #include <isc/types.h>
28 #include <isc/refcount.h>
30 #include <dns/fixedname.h>
32 #include <dns/order.h>
33 #include <dns/rdataset.h>
34 #include <dns/types.h>
36 typedef struct dns_order_ent dns_order_ent_t
;
37 struct dns_order_ent
{
39 dns_rdataclass_t rdclass
;
40 dns_rdatatype_t rdtype
;
42 ISC_LINK(dns_order_ent_t
) link
;
47 isc_refcount_t references
;
48 ISC_LIST(dns_order_ent_t
) ents
;
52 #define DNS_ORDER_MAGIC ISC_MAGIC('O','r','d','r')
53 #define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC)
56 dns_order_create(isc_mem_t
*mctx
, dns_order_t
**orderp
) {
60 REQUIRE(orderp
!= NULL
&& *orderp
== NULL
);
62 order
= isc_mem_get(mctx
, sizeof(*order
));
64 return (ISC_R_NOMEMORY
);
66 ISC_LIST_INIT(order
->ents
);
68 /* Implicit attach. */
69 result
= isc_refcount_init(&order
->references
, 1);
70 if (result
!= ISC_R_SUCCESS
) {
71 isc_mem_put(mctx
, order
, sizeof(*order
));
76 isc_mem_attach(mctx
, &order
->mctx
);
77 order
->magic
= DNS_ORDER_MAGIC
;
79 return (ISC_R_SUCCESS
);
83 dns_order_add(dns_order_t
*order
, dns_name_t
*name
,
84 dns_rdatatype_t rdtype
, dns_rdataclass_t rdclass
,
89 REQUIRE(DNS_ORDER_VALID(order
));
90 REQUIRE(mode
== DNS_RDATASETATTR_RANDOMIZE
||
91 mode
== DNS_RDATASETATTR_FIXEDORDER
||
92 mode
== 0 /* DNS_RDATASETATTR_CYCLIC */ );
94 ent
= isc_mem_get(order
->mctx
, sizeof(*ent
));
96 return (ISC_R_NOMEMORY
);
98 dns_fixedname_init(&ent
->name
);
99 RUNTIME_CHECK(dns_name_copy(name
, dns_fixedname_name(&ent
->name
), NULL
)
101 ent
->rdtype
= rdtype
;
102 ent
->rdclass
= rdclass
;
104 ISC_LINK_INIT(ent
, link
);
105 ISC_LIST_INITANDAPPEND(order
->ents
, ent
, link
);
106 return (ISC_R_SUCCESS
);
109 static inline isc_boolean_t
110 match(dns_name_t
*name1
, dns_name_t
*name2
) {
112 if (dns_name_iswildcard(name2
))
113 return(dns_name_matcheswildcard(name1
, name2
));
114 return (dns_name_equal(name1
, name2
));
118 dns_order_find(dns_order_t
*order
, dns_name_t
*name
,
119 dns_rdatatype_t rdtype
, dns_rdataclass_t rdclass
)
121 dns_order_ent_t
*ent
;
122 REQUIRE(DNS_ORDER_VALID(order
));
124 for (ent
= ISC_LIST_HEAD(order
->ents
);
126 ent
= ISC_LIST_NEXT(ent
, link
)) {
127 if (ent
->rdtype
!= rdtype
&& ent
->rdtype
!= dns_rdatatype_any
)
129 if (ent
->rdclass
!= rdclass
&&
130 ent
->rdclass
!= dns_rdataclass_any
)
132 if (match(name
, dns_fixedname_name(&ent
->name
)))
139 dns_order_attach(dns_order_t
*source
, dns_order_t
**target
) {
140 REQUIRE(DNS_ORDER_VALID(source
));
141 REQUIRE(target
!= NULL
&& *target
== NULL
);
142 isc_refcount_increment(&source
->references
, NULL
);
147 dns_order_detach(dns_order_t
**orderp
) {
149 dns_order_ent_t
*ent
;
150 unsigned int references
;
152 REQUIRE(orderp
!= NULL
);
154 REQUIRE(DNS_ORDER_VALID(order
));
155 isc_refcount_decrement(&order
->references
, &references
);
161 while ((ent
= ISC_LIST_HEAD(order
->ents
)) != NULL
) {
162 ISC_LIST_UNLINK(order
->ents
, ent
, link
);
163 isc_mem_put(order
->mctx
, ent
, sizeof(*ent
));
165 isc_refcount_destroy(&order
->references
);
166 isc_mem_putanddetach(&order
->mctx
, order
, sizeof(*order
));