1/* $NetBSD: ipkeylist.c,v 1.7 2024/02/21 22:52:06 christos Exp $ */ 2 3/* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 5 * 6 * SPDX-License-Identifier: MPL-2.0 7 * 8 * This Source Code Form is subject to the terms of the Mozilla Public 9 * License, v. 2.0. If a copy of the MPL was not distributed with this 10 * file, you can obtain one at https://mozilla.org/MPL/2.0/. 11 * 12 * See the COPYRIGHT file distributed with this work for additional 13 * information regarding copyright ownership. 14 */ 15 16#include <inttypes.h> 17#include <string.h> 18 19#include <isc/mem.h> 20#include <isc/sockaddr.h> 21#include <isc/util.h> 22 23#include <dns/ipkeylist.h> 24#include <dns/name.h> 25 26void 27dns_ipkeylist_init(dns_ipkeylist_t *ipkl) { 28 ipkl->count = 0; 29 ipkl->allocated = 0; 30 ipkl->addrs = NULL; 31 ipkl->keys = NULL; 32 ipkl->tlss = NULL; 33 ipkl->labels = NULL; 34} 35 36void 37dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) { 38 uint32_t i; 39 40 REQUIRE(ipkl != NULL); 41 42 if (ipkl->allocated == 0) { 43 return; 44 } 45 46 if (ipkl->addrs != NULL) { 47 isc_mem_put(mctx, ipkl->addrs, 48 ipkl->allocated * sizeof(isc_sockaddr_t)); 49 } 50 51 if (ipkl->keys != NULL) { 52 for (i = 0; i < ipkl->allocated; i++) { 53 if (ipkl->keys[i] == NULL) { 54 continue; 55 } 56 if (dns_name_dynamic(ipkl->keys[i])) { 57 dns_name_free(ipkl->keys[i], mctx); 58 } 59 isc_mem_put(mctx, ipkl->keys[i], sizeof(dns_name_t)); 60 } 61 isc_mem_put(mctx, ipkl->keys, 62 ipkl->allocated * sizeof(dns_name_t *)); 63 } 64 65 if (ipkl->tlss != NULL) { 66 for (i = 0; i < ipkl->allocated; i++) { 67 if (ipkl->tlss[i] == NULL) { 68 continue; 69 } 70 if (dns_name_dynamic(ipkl->tlss[i])) { 71 dns_name_free(ipkl->tlss[i], mctx); 72 } 73 isc_mem_put(mctx, ipkl->tlss[i], sizeof(dns_name_t)); 74 } 75 isc_mem_put(mctx, ipkl->tlss, 76 ipkl->allocated * sizeof(dns_name_t *)); 77 } 78 79 if (ipkl->labels != NULL) { 80 for (i = 0; i < ipkl->allocated; i++) { 81 if (ipkl->labels[i] == NULL) { 82 continue; 83 } 84 if (dns_name_dynamic(ipkl->labels[i])) { 85 dns_name_free(ipkl->labels[i], mctx); 86 } 87 isc_mem_put(mctx, ipkl->labels[i], sizeof(dns_name_t)); 88 } 89 isc_mem_put(mctx, ipkl->labels, 90 ipkl->allocated * sizeof(dns_name_t *)); 91 } 92 93 dns_ipkeylist_init(ipkl); 94} 95 96isc_result_t 97dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, 98 dns_ipkeylist_t *dst) { 99 isc_result_t result = ISC_R_SUCCESS; 100 uint32_t i; 101 102 REQUIRE(dst != NULL); 103 /* dst might be preallocated, we don't care, but it must be empty */ 104 REQUIRE(dst->count == 0); 105 106 if (src->count == 0) { 107 return (ISC_R_SUCCESS); 108 } 109 110 result = dns_ipkeylist_resize(mctx, dst, src->count); 111 if (result != ISC_R_SUCCESS) { 112 return (result); 113 } 114 115 memmove(dst->addrs, src->addrs, src->count * sizeof(isc_sockaddr_t)); 116 117 if (src->keys != NULL) { 118 for (i = 0; i < src->count; i++) { 119 if (src->keys[i] != NULL) { 120 dst->keys[i] = isc_mem_get(mctx, 121 sizeof(dns_name_t)); 122 dns_name_init(dst->keys[i], NULL); 123 dns_name_dup(src->keys[i], mctx, dst->keys[i]); 124 } else { 125 dst->keys[i] = NULL; 126 } 127 } 128 } 129 130 if (src->tlss != NULL) { 131 for (i = 0; i < src->count; i++) { 132 if (src->tlss[i] != NULL) { 133 dst->tlss[i] = isc_mem_get(mctx, 134 sizeof(dns_name_t)); 135 dns_name_init(dst->tlss[i], NULL); 136 dns_name_dup(src->tlss[i], mctx, dst->tlss[i]); 137 } else { 138 dst->tlss[i] = NULL; 139 } 140 } 141 } 142 143 if (src->labels != NULL) { 144 for (i = 0; i < src->count; i++) { 145 if (src->labels[i] != NULL) { 146 dst->labels[i] = 147 isc_mem_get(mctx, sizeof(dns_name_t)); 148 dns_name_init(dst->labels[i], NULL); 149 dns_name_dup(src->labels[i], mctx, 150 dst->labels[i]); 151 } else { 152 dst->labels[i] = NULL; 153 } 154 } 155 } 156 dst->count = src->count; 157 return (ISC_R_SUCCESS); 158} 159 160isc_result_t 161dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) { 162 isc_sockaddr_t *addrs = NULL; 163 dns_name_t **keys = NULL; 164 dns_name_t **tlss = NULL; 165 dns_name_t **labels = NULL; 166 167 REQUIRE(ipkl != NULL); 168 REQUIRE(n > ipkl->count); 169 170 if (n <= ipkl->allocated) { 171 return (ISC_R_SUCCESS); 172 } 173 174 addrs = isc_mem_get(mctx, n * sizeof(isc_sockaddr_t)); 175 keys = isc_mem_get(mctx, n * sizeof(dns_name_t *)); 176 tlss = isc_mem_get(mctx, n * sizeof(dns_name_t *)); 177 labels = isc_mem_get(mctx, n * sizeof(dns_name_t *)); 178 179 if (ipkl->addrs != NULL) { 180 memmove(addrs, ipkl->addrs, 181 ipkl->allocated * sizeof(isc_sockaddr_t)); 182 isc_mem_put(mctx, ipkl->addrs, 183 ipkl->allocated * sizeof(isc_sockaddr_t)); 184 } 185 ipkl->addrs = addrs; 186 memset(&ipkl->addrs[ipkl->allocated], 0, 187 (n - ipkl->allocated) * sizeof(isc_sockaddr_t)); 188 189 if (ipkl->keys) { 190 memmove(keys, ipkl->keys, 191 ipkl->allocated * sizeof(dns_name_t *)); 192 isc_mem_put(mctx, ipkl->keys, 193 ipkl->allocated * sizeof(dns_name_t *)); 194 } 195 ipkl->keys = keys; 196 memset(&ipkl->keys[ipkl->allocated], 0, 197 (n - ipkl->allocated) * sizeof(dns_name_t *)); 198 199 if (ipkl->tlss) { 200 memmove(tlss, ipkl->tlss, 201 ipkl->allocated * sizeof(dns_name_t *)); 202 isc_mem_put(mctx, ipkl->tlss, 203 ipkl->allocated * sizeof(dns_name_t *)); 204 } 205 ipkl->tlss = tlss; 206 memset(&ipkl->tlss[ipkl->allocated], 0, 207 (n - ipkl->allocated) * sizeof(dns_name_t *)); 208 209 if (ipkl->labels != NULL) { 210 memmove(labels, ipkl->labels, 211 ipkl->allocated * sizeof(dns_name_t *)); 212 isc_mem_put(mctx, ipkl->labels, 213 ipkl->allocated * sizeof(dns_name_t *)); 214 } 215 ipkl->labels = labels; 216 memset(&ipkl->labels[ipkl->allocated], 0, 217 (n - ipkl->allocated) * sizeof(dns_name_t *)); 218 219 ipkl->allocated = n; 220 return (ISC_R_SUCCESS); 221 222 isc_mem_put(mctx, addrs, n * sizeof(isc_sockaddr_t)); 223 isc_mem_put(mctx, tlss, n * sizeof(dns_name_t *)); 224 isc_mem_put(mctx, keys, n * sizeof(dns_name_t *)); 225 isc_mem_put(mctx, labels, n * sizeof(dns_name_t *)); 226 227 return (ISC_R_NOMEMORY); 228} 229