1*bcda20f6Schristos /* $NetBSD: remote.c,v 1.2 2025/01/26 16:25:24 christos Exp $ */ 29689912eSchristos 39689912eSchristos /* 49689912eSchristos * Copyright (C) Internet Systems Consortium, Inc. ("ISC") 59689912eSchristos * 69689912eSchristos * SPDX-License-Identifier: MPL-2.0 79689912eSchristos * 89689912eSchristos * This Source Code Form is subject to the terms of the Mozilla Public 99689912eSchristos * License, v. 2.0. If a copy of the MPL was not distributed with this 109689912eSchristos * file, you can obtain one at https://mozilla.org/MPL/2.0/. 119689912eSchristos * 129689912eSchristos * See the COPYRIGHT file distributed with this work for additional 139689912eSchristos * information regarding copyright ownership. 149689912eSchristos */ 159689912eSchristos 169689912eSchristos /*! \file */ 179689912eSchristos 189689912eSchristos #include <stdbool.h> 199689912eSchristos #include <string.h> 209689912eSchristos 219689912eSchristos #include <isc/result.h> 229689912eSchristos #include <isc/sockaddr.h> 239689912eSchristos #include <isc/types.h> 249689912eSchristos #include <isc/util.h> 259689912eSchristos 269689912eSchristos #include <dns/name.h> 279689912eSchristos #include <dns/remote.h> 289689912eSchristos #include <dns/types.h> 299689912eSchristos 309689912eSchristos isc_sockaddr_t * 319689912eSchristos dns_remote_addresses(dns_remote_t *remote) { 329689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 339689912eSchristos return remote->addresses; 349689912eSchristos } 359689912eSchristos 369689912eSchristos isc_sockaddr_t * 379689912eSchristos dns_remote_sources(dns_remote_t *remote) { 389689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 399689912eSchristos return remote->sources; 409689912eSchristos } 419689912eSchristos 429689912eSchristos unsigned int 439689912eSchristos dns_remote_count(dns_remote_t *remote) { 449689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 459689912eSchristos return remote->addrcnt; 469689912eSchristos } 479689912eSchristos 489689912eSchristos dns_name_t ** 499689912eSchristos dns_remote_keynames(dns_remote_t *remote) { 509689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 519689912eSchristos return remote->keynames; 529689912eSchristos } 539689912eSchristos 549689912eSchristos dns_name_t ** 559689912eSchristos dns_remote_tlsnames(dns_remote_t *remote) { 569689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 579689912eSchristos return remote->tlsnames; 589689912eSchristos } 599689912eSchristos 609689912eSchristos void 619689912eSchristos dns_remote_init(dns_remote_t *remote, unsigned int count, 629689912eSchristos const isc_sockaddr_t *addrs, const isc_sockaddr_t *srcs, 639689912eSchristos dns_name_t **keynames, dns_name_t **tlsnames, bool mark, 649689912eSchristos isc_mem_t *mctx) { 659689912eSchristos unsigned int i; 669689912eSchristos 679689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 689689912eSchristos REQUIRE(count == 0 || addrs != NULL); 699689912eSchristos 709689912eSchristos if (keynames != NULL || tlsnames != NULL) { 719689912eSchristos REQUIRE(count != 0); 729689912eSchristos } 739689912eSchristos 749689912eSchristos remote->mctx = mctx; 759689912eSchristos 769689912eSchristos if (addrs != NULL) { 779689912eSchristos remote->addresses = isc_mem_cget(mctx, count, 789689912eSchristos sizeof(isc_sockaddr_t)); 799689912eSchristos memmove(remote->addresses, addrs, 809689912eSchristos count * sizeof(isc_sockaddr_t)); 819689912eSchristos } else { 829689912eSchristos remote->addresses = NULL; 839689912eSchristos } 849689912eSchristos 859689912eSchristos if (srcs != NULL) { 869689912eSchristos remote->sources = isc_mem_cget(mctx, count, 879689912eSchristos sizeof(isc_sockaddr_t)); 889689912eSchristos memmove(remote->sources, srcs, count * sizeof(isc_sockaddr_t)); 899689912eSchristos } else { 909689912eSchristos remote->sources = NULL; 919689912eSchristos } 929689912eSchristos 939689912eSchristos if (keynames != NULL) { 949689912eSchristos remote->keynames = isc_mem_cget(mctx, count, 959689912eSchristos sizeof(keynames[0])); 969689912eSchristos for (i = 0; i < count; i++) { 979689912eSchristos remote->keynames[i] = NULL; 989689912eSchristos } 999689912eSchristos for (i = 0; i < count; i++) { 1009689912eSchristos if (keynames[i] != NULL) { 1019689912eSchristos remote->keynames[i] = 1029689912eSchristos isc_mem_get(mctx, sizeof(dns_name_t)); 1039689912eSchristos dns_name_init(remote->keynames[i], NULL); 1049689912eSchristos dns_name_dup(keynames[i], mctx, 1059689912eSchristos remote->keynames[i]); 1069689912eSchristos } 1079689912eSchristos } 1089689912eSchristos } else { 1099689912eSchristos remote->keynames = NULL; 1109689912eSchristos } 1119689912eSchristos 1129689912eSchristos if (tlsnames != NULL) { 1139689912eSchristos remote->tlsnames = isc_mem_cget(mctx, count, 1149689912eSchristos sizeof(tlsnames[0])); 1159689912eSchristos for (i = 0; i < count; i++) { 1169689912eSchristos remote->tlsnames[i] = NULL; 1179689912eSchristos } 1189689912eSchristos for (i = 0; i < count; i++) { 1199689912eSchristos if (tlsnames[i] != NULL) { 1209689912eSchristos remote->tlsnames[i] = 1219689912eSchristos isc_mem_get(mctx, sizeof(dns_name_t)); 1229689912eSchristos dns_name_init(remote->tlsnames[i], NULL); 1239689912eSchristos dns_name_dup(tlsnames[i], mctx, 1249689912eSchristos remote->tlsnames[i]); 1259689912eSchristos } 1269689912eSchristos } 1279689912eSchristos } else { 1289689912eSchristos remote->tlsnames = NULL; 1299689912eSchristos } 1309689912eSchristos 1319689912eSchristos if (mark) { 1329689912eSchristos remote->ok = isc_mem_cget(mctx, count, sizeof(bool)); 1339689912eSchristos for (i = 0; i < count; i++) { 1349689912eSchristos remote->ok[i] = false; 1359689912eSchristos } 1369689912eSchristos } else { 1379689912eSchristos remote->ok = NULL; 1389689912eSchristos } 1399689912eSchristos 1409689912eSchristos remote->addrcnt = count; 1419689912eSchristos remote->curraddr = 0; 1429689912eSchristos } 1439689912eSchristos 1449689912eSchristos static bool 1459689912eSchristos same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist, 1469689912eSchristos uint32_t count) { 1479689912eSchristos unsigned int i; 1489689912eSchristos 1499689912eSchristos if (oldlist == NULL && newlist == NULL) { 1509689912eSchristos return true; 1519689912eSchristos } 1529689912eSchristos if (oldlist == NULL || newlist == NULL) { 1539689912eSchristos return false; 1549689912eSchristos } 1559689912eSchristos 1569689912eSchristos for (i = 0; i < count; i++) { 1579689912eSchristos if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) { 1589689912eSchristos return false; 1599689912eSchristos } 1609689912eSchristos } 1619689912eSchristos return true; 1629689912eSchristos } 1639689912eSchristos 1649689912eSchristos static bool 1659689912eSchristos same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist, 1669689912eSchristos uint32_t count) { 1679689912eSchristos unsigned int i; 1689689912eSchristos 1699689912eSchristos if (oldlist == NULL && newlist == NULL) { 1709689912eSchristos return true; 1719689912eSchristos } 1729689912eSchristos if (oldlist == NULL || newlist == NULL) { 1739689912eSchristos return false; 1749689912eSchristos } 1759689912eSchristos 1769689912eSchristos for (i = 0; i < count; i++) { 1779689912eSchristos if (oldlist[i] == NULL && newlist[i] == NULL) { 1789689912eSchristos continue; 1799689912eSchristos } 1809689912eSchristos if (oldlist[i] == NULL || newlist[i] == NULL || 1819689912eSchristos !dns_name_equal(oldlist[i], newlist[i])) 1829689912eSchristos { 1839689912eSchristos return false; 1849689912eSchristos } 1859689912eSchristos } 1869689912eSchristos return true; 1879689912eSchristos } 1889689912eSchristos 1899689912eSchristos void 1909689912eSchristos dns_remote_clear(dns_remote_t *remote) { 1919689912eSchristos unsigned int count; 1929689912eSchristos isc_mem_t *mctx; 1939689912eSchristos 1949689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 1959689912eSchristos 1969689912eSchristos count = remote->addrcnt; 1979689912eSchristos mctx = remote->mctx; 1989689912eSchristos 1999689912eSchristos if (mctx == NULL) { 2009689912eSchristos return; 2019689912eSchristos } 2029689912eSchristos 2039689912eSchristos if (remote->ok != NULL) { 2049689912eSchristos isc_mem_cput(mctx, remote->ok, count, sizeof(bool)); 2059689912eSchristos remote->ok = NULL; 2069689912eSchristos } 2079689912eSchristos 2089689912eSchristos if (remote->addresses != NULL) { 2099689912eSchristos isc_mem_cput(mctx, remote->addresses, count, 2109689912eSchristos sizeof(isc_sockaddr_t)); 2119689912eSchristos remote->addresses = NULL; 2129689912eSchristos } 2139689912eSchristos 2149689912eSchristos if (remote->sources != NULL) { 2159689912eSchristos isc_mem_cput(mctx, remote->sources, count, 2169689912eSchristos sizeof(isc_sockaddr_t)); 2179689912eSchristos remote->sources = NULL; 2189689912eSchristos } 2199689912eSchristos 2209689912eSchristos if (remote->keynames != NULL) { 2219689912eSchristos unsigned int i; 2229689912eSchristos for (i = 0; i < count; i++) { 2239689912eSchristos if (remote->keynames[i] != NULL) { 2249689912eSchristos dns_name_free(remote->keynames[i], mctx); 2259689912eSchristos isc_mem_put(mctx, remote->keynames[i], 2269689912eSchristos sizeof(dns_name_t)); 2279689912eSchristos remote->keynames[i] = NULL; 2289689912eSchristos } 2299689912eSchristos } 2309689912eSchristos isc_mem_cput(mctx, remote->keynames, count, 2319689912eSchristos sizeof(dns_name_t *)); 2329689912eSchristos remote->keynames = NULL; 2339689912eSchristos } 2349689912eSchristos 2359689912eSchristos if (remote->tlsnames != NULL) { 2369689912eSchristos unsigned int i; 2379689912eSchristos for (i = 0; i < count; i++) { 2389689912eSchristos if (remote->tlsnames[i] != NULL) { 2399689912eSchristos dns_name_free(remote->tlsnames[i], mctx); 2409689912eSchristos isc_mem_put(mctx, remote->tlsnames[i], 2419689912eSchristos sizeof(dns_name_t)); 2429689912eSchristos remote->tlsnames[i] = NULL; 2439689912eSchristos } 2449689912eSchristos } 2459689912eSchristos isc_mem_cput(mctx, remote->tlsnames, count, 2469689912eSchristos sizeof(dns_name_t *)); 2479689912eSchristos remote->tlsnames = NULL; 2489689912eSchristos } 2499689912eSchristos 2509689912eSchristos remote->curraddr = 0; 2519689912eSchristos remote->addrcnt = 0; 2529689912eSchristos remote->mctx = NULL; 2539689912eSchristos } 2549689912eSchristos 2559689912eSchristos bool 2569689912eSchristos dns_remote_equal(dns_remote_t *a, dns_remote_t *b) { 2579689912eSchristos REQUIRE(DNS_REMOTE_VALID(a)); 2589689912eSchristos REQUIRE(DNS_REMOTE_VALID(b)); 2599689912eSchristos 2609689912eSchristos if (a->addrcnt != b->addrcnt) { 2619689912eSchristos return false; 2629689912eSchristos } 2639689912eSchristos 2649689912eSchristos if (!same_addrs(a->addresses, b->addresses, a->addrcnt)) { 2659689912eSchristos return false; 2669689912eSchristos } 2679689912eSchristos if (!same_names(a->keynames, b->keynames, a->addrcnt)) { 2689689912eSchristos return false; 2699689912eSchristos } 2709689912eSchristos if (!same_names(a->tlsnames, b->tlsnames, a->addrcnt)) { 2719689912eSchristos return false; 2729689912eSchristos } 2739689912eSchristos 2749689912eSchristos return true; 2759689912eSchristos } 2769689912eSchristos 2779689912eSchristos void 2789689912eSchristos dns_remote_reset(dns_remote_t *remote, bool clear_ok) { 2799689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 2809689912eSchristos 2819689912eSchristos remote->curraddr = 0; 2829689912eSchristos 2839689912eSchristos if (clear_ok && remote->ok != NULL) { 2849689912eSchristos for (unsigned int i = 0; i < remote->addrcnt; i++) { 2859689912eSchristos remote->ok[i] = false; 2869689912eSchristos } 2879689912eSchristos } 2889689912eSchristos } 2899689912eSchristos 2909689912eSchristos isc_sockaddr_t 2919689912eSchristos dns_remote_curraddr(dns_remote_t *remote) { 2929689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 2939689912eSchristos REQUIRE(remote->addresses != NULL); 2949689912eSchristos REQUIRE(remote->curraddr < remote->addrcnt); 2959689912eSchristos 2969689912eSchristos return remote->addresses[remote->curraddr]; 2979689912eSchristos } 2989689912eSchristos 2999689912eSchristos isc_sockaddr_t 3009689912eSchristos dns_remote_addr(dns_remote_t *remote, unsigned int i) { 3019689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3029689912eSchristos REQUIRE(remote->addresses != NULL); 3039689912eSchristos REQUIRE(i < remote->addrcnt); 3049689912eSchristos 3059689912eSchristos return remote->addresses[i]; 3069689912eSchristos } 3079689912eSchristos 3089689912eSchristos isc_sockaddr_t 3099689912eSchristos dns_remote_sourceaddr(dns_remote_t *remote) { 3109689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3119689912eSchristos REQUIRE(remote->sources != NULL); 3129689912eSchristos REQUIRE(remote->curraddr < remote->addrcnt); 3139689912eSchristos 3149689912eSchristos return remote->sources[remote->curraddr]; 3159689912eSchristos } 3169689912eSchristos 3179689912eSchristos dns_name_t * 3189689912eSchristos dns_remote_keyname(dns_remote_t *remote) { 3199689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3209689912eSchristos 3219689912eSchristos if (remote->keynames == NULL) { 3229689912eSchristos return NULL; 3239689912eSchristos } 3249689912eSchristos if (remote->curraddr >= remote->addrcnt) { 3259689912eSchristos return NULL; 3269689912eSchristos } 3279689912eSchristos 3289689912eSchristos return remote->keynames[remote->curraddr]; 3299689912eSchristos } 3309689912eSchristos 3319689912eSchristos dns_name_t * 3329689912eSchristos dns_remote_tlsname(dns_remote_t *remote) { 3339689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3349689912eSchristos 3359689912eSchristos if (remote->tlsnames == NULL) { 3369689912eSchristos return NULL; 3379689912eSchristos } 3389689912eSchristos if (remote->curraddr >= remote->addrcnt) { 3399689912eSchristos return NULL; 3409689912eSchristos } 3419689912eSchristos 3429689912eSchristos return remote->tlsnames[remote->curraddr]; 3439689912eSchristos } 3449689912eSchristos 3459689912eSchristos void 3469689912eSchristos dns_remote_next(dns_remote_t *remote, bool skip_good) { 3479689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3489689912eSchristos 3499689912eSchristos skip_to_next: 3509689912eSchristos remote->curraddr++; 3519689912eSchristos 3529689912eSchristos if (remote->curraddr >= remote->addrcnt) { 3539689912eSchristos return; 3549689912eSchristos } 3559689912eSchristos 3569689912eSchristos if (skip_good && remote->ok != NULL && remote->ok[remote->curraddr]) { 3579689912eSchristos goto skip_to_next; 3589689912eSchristos } 3599689912eSchristos } 3609689912eSchristos 3619689912eSchristos bool 3629689912eSchristos dns_remote_done(dns_remote_t *remote) { 3639689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3649689912eSchristos 3659689912eSchristos return remote->curraddr >= remote->addrcnt; 3669689912eSchristos } 3679689912eSchristos 3689689912eSchristos void 3699689912eSchristos dns_remote_mark(dns_remote_t *remote, bool good) { 3709689912eSchristos REQUIRE(DNS_REMOTE_VALID(remote)); 3719689912eSchristos REQUIRE(remote->curraddr < remote->addrcnt); 3729689912eSchristos 3739689912eSchristos remote->ok[remote->curraddr] = good; 3749689912eSchristos } 375