Coverage Report

Created: 2025-11-24 06:17

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