1 1.1 christos /* $NetBSD: order.c,v 1.1 2024/02/18 20:57:33 christos Exp $ */ 2 1.1 christos 3 1.1 christos /* 4 1.1 christos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 1.1 christos * 6 1.1 christos * SPDX-License-Identifier: MPL-2.0 7 1.1 christos * 8 1.1 christos * This Source Code Form is subject to the terms of the Mozilla Public 9 1.1 christos * License, v. 2.0. If a copy of the MPL was not distributed with this 10 1.1 christos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 1.1 christos * 12 1.1 christos * See the COPYRIGHT file distributed with this work for additional 13 1.1 christos * information regarding copyright ownership. 14 1.1 christos */ 15 1.1 christos 16 1.1 christos /*! \file */ 17 1.1 christos 18 1.1 christos #include <stdbool.h> 19 1.1 christos 20 1.1 christos #include <isc/magic.h> 21 1.1 christos #include <isc/mem.h> 22 1.1 christos #include <isc/refcount.h> 23 1.1 christos #include <isc/types.h> 24 1.1 christos #include <isc/util.h> 25 1.1 christos 26 1.1 christos #include <dns/fixedname.h> 27 1.1 christos #include <dns/name.h> 28 1.1 christos #include <dns/order.h> 29 1.1 christos #include <dns/rdataset.h> 30 1.1 christos #include <dns/types.h> 31 1.1 christos 32 1.1 christos typedef struct dns_order_ent dns_order_ent_t; 33 1.1 christos struct dns_order_ent { 34 1.1 christos dns_fixedname_t name; 35 1.1 christos dns_rdataclass_t rdclass; 36 1.1 christos dns_rdatatype_t rdtype; 37 1.1 christos unsigned int mode; 38 1.1 christos ISC_LINK(dns_order_ent_t) link; 39 1.1 christos }; 40 1.1 christos 41 1.1 christos struct dns_order { 42 1.1 christos unsigned int magic; 43 1.1 christos isc_refcount_t references; 44 1.1 christos ISC_LIST(dns_order_ent_t) ents; 45 1.1 christos isc_mem_t *mctx; 46 1.1 christos }; 47 1.1 christos 48 1.1 christos #define DNS_ORDER_MAGIC ISC_MAGIC('O', 'r', 'd', 'r') 49 1.1 christos #define DNS_ORDER_VALID(order) ISC_MAGIC_VALID(order, DNS_ORDER_MAGIC) 50 1.1 christos 51 1.1 christos isc_result_t 52 1.1 christos dns_order_create(isc_mem_t *mctx, dns_order_t **orderp) { 53 1.1 christos dns_order_t *order; 54 1.1 christos 55 1.1 christos REQUIRE(orderp != NULL && *orderp == NULL); 56 1.1 christos 57 1.1 christos order = isc_mem_get(mctx, sizeof(*order)); 58 1.1 christos 59 1.1 christos ISC_LIST_INIT(order->ents); 60 1.1 christos 61 1.1 christos /* Implicit attach. */ 62 1.1 christos isc_refcount_init(&order->references, 1); 63 1.1 christos 64 1.1 christos order->mctx = NULL; 65 1.1 christos isc_mem_attach(mctx, &order->mctx); 66 1.1 christos order->magic = DNS_ORDER_MAGIC; 67 1.1 christos *orderp = order; 68 1.1 christos return (ISC_R_SUCCESS); 69 1.1 christos } 70 1.1 christos 71 1.1 christos isc_result_t 72 1.1 christos dns_order_add(dns_order_t *order, const dns_name_t *name, 73 1.1 christos dns_rdatatype_t rdtype, dns_rdataclass_t rdclass, 74 1.1 christos unsigned int mode) { 75 1.1 christos dns_order_ent_t *ent; 76 1.1 christos 77 1.1 christos REQUIRE(DNS_ORDER_VALID(order)); 78 1.1 christos REQUIRE(mode == DNS_RDATASETATTR_RANDOMIZE || 79 1.1 christos mode == DNS_RDATASETATTR_FIXEDORDER || 80 1.1 christos mode == DNS_RDATASETATTR_CYCLIC || 81 1.1 christos mode == DNS_RDATASETATTR_NONE); 82 1.1 christos 83 1.1 christos ent = isc_mem_get(order->mctx, sizeof(*ent)); 84 1.1 christos 85 1.1 christos dns_fixedname_init(&ent->name); 86 1.1 christos dns_name_copynf(name, dns_fixedname_name(&ent->name)); 87 1.1 christos ent->rdtype = rdtype; 88 1.1 christos ent->rdclass = rdclass; 89 1.1 christos ent->mode = mode; 90 1.1 christos ISC_LINK_INIT(ent, link); 91 1.1 christos ISC_LIST_INITANDAPPEND(order->ents, ent, link); 92 1.1 christos return (ISC_R_SUCCESS); 93 1.1 christos } 94 1.1 christos 95 1.1 christos static bool 96 1.1 christos match(const dns_name_t *name1, const dns_name_t *name2) { 97 1.1 christos if (dns_name_iswildcard(name2)) { 98 1.1 christos return (dns_name_matcheswildcard(name1, name2)); 99 1.1 christos } 100 1.1 christos return (dns_name_equal(name1, name2)); 101 1.1 christos } 102 1.1 christos 103 1.1 christos unsigned int 104 1.1 christos dns_order_find(dns_order_t *order, const dns_name_t *name, 105 1.1 christos dns_rdatatype_t rdtype, dns_rdataclass_t rdclass) { 106 1.1 christos dns_order_ent_t *ent; 107 1.1 christos REQUIRE(DNS_ORDER_VALID(order)); 108 1.1 christos 109 1.1 christos for (ent = ISC_LIST_HEAD(order->ents); ent != NULL; 110 1.1 christos ent = ISC_LIST_NEXT(ent, link)) 111 1.1 christos { 112 1.1 christos if (ent->rdtype != rdtype && ent->rdtype != dns_rdatatype_any) { 113 1.1 christos continue; 114 1.1 christos } 115 1.1 christos if (ent->rdclass != rdclass && 116 1.1 christos ent->rdclass != dns_rdataclass_any) 117 1.1 christos { 118 1.1 christos continue; 119 1.1 christos } 120 1.1 christos if (match(name, dns_fixedname_name(&ent->name))) { 121 1.1 christos return (ent->mode); 122 1.1 christos } 123 1.1 christos } 124 1.1 christos return (DNS_RDATASETATTR_NONE); 125 1.1 christos } 126 1.1 christos 127 1.1 christos void 128 1.1 christos dns_order_attach(dns_order_t *source, dns_order_t **target) { 129 1.1 christos REQUIRE(DNS_ORDER_VALID(source)); 130 1.1 christos REQUIRE(target != NULL && *target == NULL); 131 1.1 christos isc_refcount_increment(&source->references); 132 1.1 christos *target = source; 133 1.1 christos } 134 1.1 christos 135 1.1 christos void 136 1.1 christos dns_order_detach(dns_order_t **orderp) { 137 1.1 christos REQUIRE(orderp != NULL && DNS_ORDER_VALID(*orderp)); 138 1.1 christos dns_order_t *order; 139 1.1 christos order = *orderp; 140 1.1 christos *orderp = NULL; 141 1.1 christos 142 1.1 christos if (isc_refcount_decrement(&order->references) == 1) { 143 1.1 christos isc_refcount_destroy(&order->references); 144 1.1 christos order->magic = 0; 145 1.1 christos dns_order_ent_t *ent; 146 1.1 christos while ((ent = ISC_LIST_HEAD(order->ents)) != NULL) { 147 1.1 christos ISC_LIST_UNLINK(order->ents, ent, link); 148 1.1 christos isc_mem_put(order->mctx, ent, sizeof(*ent)); 149 1.1 christos } 150 1.1 christos isc_mem_putanddetach(&order->mctx, order, sizeof(*order)); 151 1.1 christos } 152 1.1 christos } 153