1 /* $NetBSD: ipkeylist.c,v 1.4 2020/05/24 19:46:23 christos Exp $ */ 2 3 /* 4 * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 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 http://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 #include <inttypes.h> 15 #include <string.h> 16 17 #include <isc/mem.h> 18 #include <isc/sockaddr.h> 19 #include <isc/util.h> 20 21 #include <dns/ipkeylist.h> 22 #include <dns/name.h> 23 24 void 25 dns_ipkeylist_init(dns_ipkeylist_t *ipkl) { 26 ipkl->count = 0; 27 ipkl->allocated = 0; 28 ipkl->addrs = NULL; 29 ipkl->dscps = NULL; 30 ipkl->keys = NULL; 31 ipkl->labels = NULL; 32 } 33 34 void 35 dns_ipkeylist_clear(isc_mem_t *mctx, dns_ipkeylist_t *ipkl) { 36 uint32_t i; 37 38 REQUIRE(ipkl != NULL); 39 40 if (ipkl->allocated == 0) { 41 return; 42 } 43 44 if (ipkl->addrs != NULL) { 45 isc_mem_put(mctx, ipkl->addrs, 46 ipkl->allocated * sizeof(isc_sockaddr_t)); 47 } 48 49 if (ipkl->dscps != NULL) { 50 isc_mem_put(mctx, ipkl->dscps, 51 ipkl->allocated * sizeof(isc_dscp_t)); 52 } 53 54 if (ipkl->keys != NULL) { 55 for (i = 0; i < ipkl->allocated; i++) { 56 if (ipkl->keys[i] == NULL) { 57 continue; 58 } 59 if (dns_name_dynamic(ipkl->keys[i])) { 60 dns_name_free(ipkl->keys[i], mctx); 61 } 62 isc_mem_put(mctx, ipkl->keys[i], sizeof(dns_name_t)); 63 } 64 isc_mem_put(mctx, ipkl->keys, 65 ipkl->allocated * sizeof(dns_name_t *)); 66 } 67 68 if (ipkl->labels != NULL) { 69 for (i = 0; i < ipkl->allocated; i++) { 70 if (ipkl->labels[i] == NULL) { 71 continue; 72 } 73 if (dns_name_dynamic(ipkl->labels[i])) { 74 dns_name_free(ipkl->labels[i], mctx); 75 } 76 isc_mem_put(mctx, ipkl->labels[i], sizeof(dns_name_t)); 77 } 78 isc_mem_put(mctx, ipkl->labels, 79 ipkl->allocated * sizeof(dns_name_t *)); 80 } 81 82 dns_ipkeylist_init(ipkl); 83 } 84 85 isc_result_t 86 dns_ipkeylist_copy(isc_mem_t *mctx, const dns_ipkeylist_t *src, 87 dns_ipkeylist_t *dst) { 88 isc_result_t result = ISC_R_SUCCESS; 89 uint32_t i; 90 91 REQUIRE(dst != NULL); 92 /* dst might be preallocated, we don't care, but it must be empty */ 93 REQUIRE(dst->count == 0); 94 95 if (src->count == 0) { 96 return (ISC_R_SUCCESS); 97 } 98 99 result = dns_ipkeylist_resize(mctx, dst, src->count); 100 if (result != ISC_R_SUCCESS) { 101 return (result); 102 } 103 104 memmove(dst->addrs, src->addrs, src->count * sizeof(isc_sockaddr_t)); 105 106 if (src->dscps != NULL) { 107 memmove(dst->dscps, src->dscps, 108 src->count * sizeof(isc_dscp_t)); 109 } 110 111 if (src->keys != NULL) { 112 for (i = 0; i < src->count; i++) { 113 if (src->keys[i] != NULL) { 114 dst->keys[i] = isc_mem_get(mctx, 115 sizeof(dns_name_t)); 116 dns_name_init(dst->keys[i], NULL); 117 dns_name_dup(src->keys[i], mctx, dst->keys[i]); 118 } else { 119 dst->keys[i] = NULL; 120 } 121 } 122 } 123 124 if (src->labels != NULL) { 125 for (i = 0; i < src->count; i++) { 126 if (src->labels[i] != NULL) { 127 dst->labels[i] = 128 isc_mem_get(mctx, sizeof(dns_name_t)); 129 dns_name_init(dst->labels[i], NULL); 130 dns_name_dup(src->labels[i], mctx, 131 dst->labels[i]); 132 } else { 133 dst->labels[i] = NULL; 134 } 135 } 136 } 137 dst->count = src->count; 138 return (ISC_R_SUCCESS); 139 } 140 141 isc_result_t 142 dns_ipkeylist_resize(isc_mem_t *mctx, dns_ipkeylist_t *ipkl, unsigned int n) { 143 isc_sockaddr_t *addrs = NULL; 144 isc_dscp_t *dscps = NULL; 145 dns_name_t **keys = NULL; 146 dns_name_t **labels = NULL; 147 148 REQUIRE(ipkl != NULL); 149 REQUIRE(n > ipkl->count); 150 151 if (n <= ipkl->allocated) { 152 return (ISC_R_SUCCESS); 153 } 154 155 addrs = isc_mem_get(mctx, n * sizeof(isc_sockaddr_t)); 156 dscps = isc_mem_get(mctx, n * sizeof(isc_dscp_t)); 157 keys = isc_mem_get(mctx, n * sizeof(dns_name_t *)); 158 labels = isc_mem_get(mctx, n * sizeof(dns_name_t *)); 159 160 if (ipkl->addrs != NULL) { 161 memmove(addrs, ipkl->addrs, 162 ipkl->allocated * sizeof(isc_sockaddr_t)); 163 isc_mem_put(mctx, ipkl->addrs, 164 ipkl->allocated * sizeof(isc_sockaddr_t)); 165 } 166 ipkl->addrs = addrs; 167 memset(&ipkl->addrs[ipkl->allocated], 0, 168 (n - ipkl->allocated) * sizeof(isc_sockaddr_t)); 169 170 if (ipkl->dscps != NULL) { 171 memmove(dscps, ipkl->dscps, 172 ipkl->allocated * sizeof(isc_dscp_t)); 173 isc_mem_put(mctx, ipkl->dscps, 174 ipkl->allocated * sizeof(isc_dscp_t)); 175 } 176 ipkl->dscps = dscps; 177 memset(&ipkl->dscps[ipkl->allocated], 0, 178 (n - ipkl->allocated) * sizeof(isc_dscp_t)); 179 180 if (ipkl->keys) { 181 memmove(keys, ipkl->keys, 182 ipkl->allocated * sizeof(dns_name_t *)); 183 isc_mem_put(mctx, ipkl->keys, 184 ipkl->allocated * sizeof(dns_name_t *)); 185 } 186 ipkl->keys = keys; 187 memset(&ipkl->keys[ipkl->allocated], 0, 188 (n - ipkl->allocated) * sizeof(dns_name_t *)); 189 190 if (ipkl->labels != NULL) { 191 memmove(labels, ipkl->labels, 192 ipkl->allocated * sizeof(dns_name_t *)); 193 isc_mem_put(mctx, ipkl->labels, 194 ipkl->allocated * sizeof(dns_name_t *)); 195 } 196 ipkl->labels = labels; 197 memset(&ipkl->labels[ipkl->allocated], 0, 198 (n - ipkl->allocated) * sizeof(dns_name_t *)); 199 200 ipkl->allocated = n; 201 return (ISC_R_SUCCESS); 202 203 isc_mem_put(mctx, addrs, n * sizeof(isc_sockaddr_t)); 204 isc_mem_put(mctx, dscps, n * sizeof(isc_dscp_t)); 205 isc_mem_put(mctx, keys, n * sizeof(dns_name_t *)); 206 isc_mem_put(mctx, labels, n * sizeof(dns_name_t *)); 207 208 return (ISC_R_NOMEMORY); 209 } 210