xref: /netbsd-src/external/mpl/bind/dist/lib/dns/ipkeylist.c (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
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