Home | History | Annotate | Line # | Download | only in dns
      1 /*	$NetBSD: remote.c,v 1.2 2025/01/26 16:25:24 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 /*! \file */
     17 
     18 #include <stdbool.h>
     19 #include <string.h>
     20 
     21 #include <isc/result.h>
     22 #include <isc/sockaddr.h>
     23 #include <isc/types.h>
     24 #include <isc/util.h>
     25 
     26 #include <dns/name.h>
     27 #include <dns/remote.h>
     28 #include <dns/types.h>
     29 
     30 isc_sockaddr_t *
     31 dns_remote_addresses(dns_remote_t *remote) {
     32 	REQUIRE(DNS_REMOTE_VALID(remote));
     33 	return remote->addresses;
     34 }
     35 
     36 isc_sockaddr_t *
     37 dns_remote_sources(dns_remote_t *remote) {
     38 	REQUIRE(DNS_REMOTE_VALID(remote));
     39 	return remote->sources;
     40 }
     41 
     42 unsigned int
     43 dns_remote_count(dns_remote_t *remote) {
     44 	REQUIRE(DNS_REMOTE_VALID(remote));
     45 	return remote->addrcnt;
     46 }
     47 
     48 dns_name_t **
     49 dns_remote_keynames(dns_remote_t *remote) {
     50 	REQUIRE(DNS_REMOTE_VALID(remote));
     51 	return remote->keynames;
     52 }
     53 
     54 dns_name_t **
     55 dns_remote_tlsnames(dns_remote_t *remote) {
     56 	REQUIRE(DNS_REMOTE_VALID(remote));
     57 	return remote->tlsnames;
     58 }
     59 
     60 void
     61 dns_remote_init(dns_remote_t *remote, unsigned int count,
     62 		const isc_sockaddr_t *addrs, const isc_sockaddr_t *srcs,
     63 		dns_name_t **keynames, dns_name_t **tlsnames, bool mark,
     64 		isc_mem_t *mctx) {
     65 	unsigned int i;
     66 
     67 	REQUIRE(DNS_REMOTE_VALID(remote));
     68 	REQUIRE(count == 0 || addrs != NULL);
     69 
     70 	if (keynames != NULL || tlsnames != NULL) {
     71 		REQUIRE(count != 0);
     72 	}
     73 
     74 	remote->mctx = mctx;
     75 
     76 	if (addrs != NULL) {
     77 		remote->addresses = isc_mem_cget(mctx, count,
     78 						 sizeof(isc_sockaddr_t));
     79 		memmove(remote->addresses, addrs,
     80 			count * sizeof(isc_sockaddr_t));
     81 	} else {
     82 		remote->addresses = NULL;
     83 	}
     84 
     85 	if (srcs != NULL) {
     86 		remote->sources = isc_mem_cget(mctx, count,
     87 					       sizeof(isc_sockaddr_t));
     88 		memmove(remote->sources, srcs, count * sizeof(isc_sockaddr_t));
     89 	} else {
     90 		remote->sources = NULL;
     91 	}
     92 
     93 	if (keynames != NULL) {
     94 		remote->keynames = isc_mem_cget(mctx, count,
     95 						sizeof(keynames[0]));
     96 		for (i = 0; i < count; i++) {
     97 			remote->keynames[i] = NULL;
     98 		}
     99 		for (i = 0; i < count; i++) {
    100 			if (keynames[i] != NULL) {
    101 				remote->keynames[i] =
    102 					isc_mem_get(mctx, sizeof(dns_name_t));
    103 				dns_name_init(remote->keynames[i], NULL);
    104 				dns_name_dup(keynames[i], mctx,
    105 					     remote->keynames[i]);
    106 			}
    107 		}
    108 	} else {
    109 		remote->keynames = NULL;
    110 	}
    111 
    112 	if (tlsnames != NULL) {
    113 		remote->tlsnames = isc_mem_cget(mctx, count,
    114 						sizeof(tlsnames[0]));
    115 		for (i = 0; i < count; i++) {
    116 			remote->tlsnames[i] = NULL;
    117 		}
    118 		for (i = 0; i < count; i++) {
    119 			if (tlsnames[i] != NULL) {
    120 				remote->tlsnames[i] =
    121 					isc_mem_get(mctx, sizeof(dns_name_t));
    122 				dns_name_init(remote->tlsnames[i], NULL);
    123 				dns_name_dup(tlsnames[i], mctx,
    124 					     remote->tlsnames[i]);
    125 			}
    126 		}
    127 	} else {
    128 		remote->tlsnames = NULL;
    129 	}
    130 
    131 	if (mark) {
    132 		remote->ok = isc_mem_cget(mctx, count, sizeof(bool));
    133 		for (i = 0; i < count; i++) {
    134 			remote->ok[i] = false;
    135 		}
    136 	} else {
    137 		remote->ok = NULL;
    138 	}
    139 
    140 	remote->addrcnt = count;
    141 	remote->curraddr = 0;
    142 }
    143 
    144 static bool
    145 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
    146 	   uint32_t count) {
    147 	unsigned int i;
    148 
    149 	if (oldlist == NULL && newlist == NULL) {
    150 		return true;
    151 	}
    152 	if (oldlist == NULL || newlist == NULL) {
    153 		return false;
    154 	}
    155 
    156 	for (i = 0; i < count; i++) {
    157 		if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
    158 			return false;
    159 		}
    160 	}
    161 	return true;
    162 }
    163 
    164 static bool
    165 same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist,
    166 	   uint32_t count) {
    167 	unsigned int i;
    168 
    169 	if (oldlist == NULL && newlist == NULL) {
    170 		return true;
    171 	}
    172 	if (oldlist == NULL || newlist == NULL) {
    173 		return false;
    174 	}
    175 
    176 	for (i = 0; i < count; i++) {
    177 		if (oldlist[i] == NULL && newlist[i] == NULL) {
    178 			continue;
    179 		}
    180 		if (oldlist[i] == NULL || newlist[i] == NULL ||
    181 		    !dns_name_equal(oldlist[i], newlist[i]))
    182 		{
    183 			return false;
    184 		}
    185 	}
    186 	return true;
    187 }
    188 
    189 void
    190 dns_remote_clear(dns_remote_t *remote) {
    191 	unsigned int count;
    192 	isc_mem_t *mctx;
    193 
    194 	REQUIRE(DNS_REMOTE_VALID(remote));
    195 
    196 	count = remote->addrcnt;
    197 	mctx = remote->mctx;
    198 
    199 	if (mctx == NULL) {
    200 		return;
    201 	}
    202 
    203 	if (remote->ok != NULL) {
    204 		isc_mem_cput(mctx, remote->ok, count, sizeof(bool));
    205 		remote->ok = NULL;
    206 	}
    207 
    208 	if (remote->addresses != NULL) {
    209 		isc_mem_cput(mctx, remote->addresses, count,
    210 			     sizeof(isc_sockaddr_t));
    211 		remote->addresses = NULL;
    212 	}
    213 
    214 	if (remote->sources != NULL) {
    215 		isc_mem_cput(mctx, remote->sources, count,
    216 			     sizeof(isc_sockaddr_t));
    217 		remote->sources = NULL;
    218 	}
    219 
    220 	if (remote->keynames != NULL) {
    221 		unsigned int i;
    222 		for (i = 0; i < count; i++) {
    223 			if (remote->keynames[i] != NULL) {
    224 				dns_name_free(remote->keynames[i], mctx);
    225 				isc_mem_put(mctx, remote->keynames[i],
    226 					    sizeof(dns_name_t));
    227 				remote->keynames[i] = NULL;
    228 			}
    229 		}
    230 		isc_mem_cput(mctx, remote->keynames, count,
    231 			     sizeof(dns_name_t *));
    232 		remote->keynames = NULL;
    233 	}
    234 
    235 	if (remote->tlsnames != NULL) {
    236 		unsigned int i;
    237 		for (i = 0; i < count; i++) {
    238 			if (remote->tlsnames[i] != NULL) {
    239 				dns_name_free(remote->tlsnames[i], mctx);
    240 				isc_mem_put(mctx, remote->tlsnames[i],
    241 					    sizeof(dns_name_t));
    242 				remote->tlsnames[i] = NULL;
    243 			}
    244 		}
    245 		isc_mem_cput(mctx, remote->tlsnames, count,
    246 			     sizeof(dns_name_t *));
    247 		remote->tlsnames = NULL;
    248 	}
    249 
    250 	remote->curraddr = 0;
    251 	remote->addrcnt = 0;
    252 	remote->mctx = NULL;
    253 }
    254 
    255 bool
    256 dns_remote_equal(dns_remote_t *a, dns_remote_t *b) {
    257 	REQUIRE(DNS_REMOTE_VALID(a));
    258 	REQUIRE(DNS_REMOTE_VALID(b));
    259 
    260 	if (a->addrcnt != b->addrcnt) {
    261 		return false;
    262 	}
    263 
    264 	if (!same_addrs(a->addresses, b->addresses, a->addrcnt)) {
    265 		return false;
    266 	}
    267 	if (!same_names(a->keynames, b->keynames, a->addrcnt)) {
    268 		return false;
    269 	}
    270 	if (!same_names(a->tlsnames, b->tlsnames, a->addrcnt)) {
    271 		return false;
    272 	}
    273 
    274 	return true;
    275 }
    276 
    277 void
    278 dns_remote_reset(dns_remote_t *remote, bool clear_ok) {
    279 	REQUIRE(DNS_REMOTE_VALID(remote));
    280 
    281 	remote->curraddr = 0;
    282 
    283 	if (clear_ok && remote->ok != NULL) {
    284 		for (unsigned int i = 0; i < remote->addrcnt; i++) {
    285 			remote->ok[i] = false;
    286 		}
    287 	}
    288 }
    289 
    290 isc_sockaddr_t
    291 dns_remote_curraddr(dns_remote_t *remote) {
    292 	REQUIRE(DNS_REMOTE_VALID(remote));
    293 	REQUIRE(remote->addresses != NULL);
    294 	REQUIRE(remote->curraddr < remote->addrcnt);
    295 
    296 	return remote->addresses[remote->curraddr];
    297 }
    298 
    299 isc_sockaddr_t
    300 dns_remote_addr(dns_remote_t *remote, unsigned int i) {
    301 	REQUIRE(DNS_REMOTE_VALID(remote));
    302 	REQUIRE(remote->addresses != NULL);
    303 	REQUIRE(i < remote->addrcnt);
    304 
    305 	return remote->addresses[i];
    306 }
    307 
    308 isc_sockaddr_t
    309 dns_remote_sourceaddr(dns_remote_t *remote) {
    310 	REQUIRE(DNS_REMOTE_VALID(remote));
    311 	REQUIRE(remote->sources != NULL);
    312 	REQUIRE(remote->curraddr < remote->addrcnt);
    313 
    314 	return remote->sources[remote->curraddr];
    315 }
    316 
    317 dns_name_t *
    318 dns_remote_keyname(dns_remote_t *remote) {
    319 	REQUIRE(DNS_REMOTE_VALID(remote));
    320 
    321 	if (remote->keynames == NULL) {
    322 		return NULL;
    323 	}
    324 	if (remote->curraddr >= remote->addrcnt) {
    325 		return NULL;
    326 	}
    327 
    328 	return remote->keynames[remote->curraddr];
    329 }
    330 
    331 dns_name_t *
    332 dns_remote_tlsname(dns_remote_t *remote) {
    333 	REQUIRE(DNS_REMOTE_VALID(remote));
    334 
    335 	if (remote->tlsnames == NULL) {
    336 		return NULL;
    337 	}
    338 	if (remote->curraddr >= remote->addrcnt) {
    339 		return NULL;
    340 	}
    341 
    342 	return remote->tlsnames[remote->curraddr];
    343 }
    344 
    345 void
    346 dns_remote_next(dns_remote_t *remote, bool skip_good) {
    347 	REQUIRE(DNS_REMOTE_VALID(remote));
    348 
    349 skip_to_next:
    350 	remote->curraddr++;
    351 
    352 	if (remote->curraddr >= remote->addrcnt) {
    353 		return;
    354 	}
    355 
    356 	if (skip_good && remote->ok != NULL && remote->ok[remote->curraddr]) {
    357 		goto skip_to_next;
    358 	}
    359 }
    360 
    361 bool
    362 dns_remote_done(dns_remote_t *remote) {
    363 	REQUIRE(DNS_REMOTE_VALID(remote));
    364 
    365 	return remote->curraddr >= remote->addrcnt;
    366 }
    367 
    368 void
    369 dns_remote_mark(dns_remote_t *remote, bool good) {
    370 	REQUIRE(DNS_REMOTE_VALID(remote));
    371 	REQUIRE(remote->curraddr < remote->addrcnt);
    372 
    373 	remote->ok[remote->curraddr] = good;
    374 }
    375