002
2021-01-04
pjp
* Copyright (c) 2017-2021 Peter J. Philipp
003
2017-06-26
pjp
* All rights reserved.
005
2017-06-26
pjp
* Redistribution and use in source and binary forms, with or without
006
2017-06-26
pjp
* modification, are permitted provided that the following conditions
007
2017-06-26
pjp
* are met:
008
2017-06-26
pjp
* 1. Redistributions of source code must retain the above copyright
009
2017-06-26
pjp
* notice, this list of conditions and the following disclaimer.
010
2017-06-26
pjp
* 2. Redistributions in binary form must reproduce the above copyright
011
2017-06-26
pjp
* notice, this list of conditions and the following disclaimer in the
012
2017-06-26
pjp
* documentation and/or other materials provided with the distribution.
013
2017-06-26
pjp
* 3. The name of the author may not be used to endorse or promote products
014
2017-06-26
pjp
* derived from this software without specific prior written permission
016
2017-06-26
pjp
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
017
2017-06-26
pjp
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
018
2017-06-26
pjp
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
019
2017-06-26
pjp
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
020
2017-06-26
pjp
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
021
2017-06-26
pjp
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
022
2017-06-26
pjp
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
023
2017-06-26
pjp
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
024
2017-06-26
pjp
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
025
2017-06-26
pjp
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029
2019-06-06
pjp
#include <sys/types.h>
030
2019-06-06
pjp
#include <sys/socket.h>
032
2019-06-06
pjp
#include <netinet/in.h>
033
2019-06-06
pjp
#include <arpa/inet.h>
034
2019-06-06
pjp
#include <netdb.h>
036
2019-06-06
pjp
#include <stdio.h>
037
2019-06-06
pjp
#include <stdlib.h>
038
2019-06-06
pjp
#include <string.h>
039
2019-06-06
pjp
#include <errno.h>
040
2019-06-06
pjp
#include <time.h>
041
2020-07-06
pjp
#include <syslog.h>
043
2019-06-06
pjp
#ifdef __linux__
044
2019-06-06
pjp
#include <grp.h>
045
2019-06-06
pjp
#define __USE_BSD 1
046
2019-06-06
pjp
#include <endian.h>
047
2019-06-06
pjp
#include <bsd/stdlib.h>
048
2019-06-06
pjp
#include <bsd/string.h>
049
2019-06-06
pjp
#include <bsd/sys/queue.h>
050
2019-06-06
pjp
#define __unused
051
2019-06-06
pjp
#include <bsd/sys/tree.h>
052
2019-06-06
pjp
#include <bsd/sys/endian.h>
053
2019-06-06
pjp
#else /* not linux */
054
2019-06-06
pjp
#include <sys/queue.h>
055
2019-06-06
pjp
#include <sys/tree.h>
056
2019-06-06
pjp
#endif /* __linux__ */
059
2017-06-26
pjp
#include "ddd-dns.h"
060
2017-06-26
pjp
#include "ddd-db.h"
062
2020-07-15
pjp
struct rbtree * create_rr(ddDB *, char *, int, int, void *, uint32_t, uint16_t);
063
2019-02-15
pjp
struct rbtree * find_rrset(ddDB *db, char *name, int len);
064
2019-02-15
pjp
struct rrset * find_rr(struct rbtree *rbt, u_int16_t rrtype);
065
2019-02-15
pjp
int add_rr(struct rbtree *rbt, char *name, int len, u_int16_t rrtype, void *rdata);
066
2019-02-15
pjp
int display_rr(struct rrset *rrset);
067
2019-02-15
pjp
int rotate_rr(struct rrset *rrset);
068
2021-01-07
pjp
void flag_rr(struct rbtree *rbt, uint32_t flag);
069
2020-07-08
pjp
int expire_rr(ddDB *, char *, int, u_int16_t, time_t);
070
2020-07-08
pjp
int expire_db(ddDB *, int);
071
2021-01-04
pjp
void remove_rbt(struct rbtree *);
072
2021-01-05
pjp
uint32_t match_zoneglue(struct rbtree *rbt);
074
2019-02-18
pjp
extern void dolog(int, char *, ...);
076
2021-01-05
pjp
extern uint32_t zonenumber;
077
2019-02-15
pjp
extern char * convert_name(char *, int);
078
2019-02-19
pjp
int domaincmp(struct node *e1, struct node *e2);
083
2017-06-26
pjp
domaincmp(struct node *e1, struct node *e2)
085
2017-06-26
pjp
if (e1->len < e2->len)
086
2017-06-26
pjp
return -1;
087
2017-06-26
pjp
else if (e1->len > e2->len)
088
2017-06-26
pjp
return 1;
090
2017-06-26
pjp
return (memcmp(e1->domainname, e2->domainname, e1->len));
096
2017-06-26
pjp
dddbopen(void)
098
2017-06-26
pjp
ddDB *db;
100
2017-06-26
pjp
db = calloc(1, sizeof(ddDB));
101
2017-06-26
pjp
if (db == NULL) {
102
2017-06-26
pjp
errno = ENOMEM;
103
2017-06-26
pjp
return NULL;
106
2017-06-26
pjp
db->put = dddbput;
107
2017-06-26
pjp
db->get = dddbget;
108
2017-06-26
pjp
db->close = dddbclose;
109
2017-06-26
pjp
db->offset = 0;
111
2019-02-19
pjp
RB_INIT(&db->head);
113
2017-06-26
pjp
return (db);
117
2017-06-26
pjp
dddbput(ddDB *db, ddDBT *key, ddDBT *data)
119
2017-06-26
pjp
struct node find, *n, *res;
121
2017-06-26
pjp
strlcpy(find.domainname, key->data, sizeof(find.domainname));
122
2017-06-26
pjp
find.len = key->size;
124
2019-02-19
pjp
res = RB_FIND(domaintree, &db->head, &find);
125
2017-06-26
pjp
if (res == NULL) {
126
2017-06-26
pjp
/* does not exist, create it */
127
2017-06-26
pjp
n = calloc(sizeof(struct node), 1);
128
2017-06-26
pjp
if (n == NULL) {
129
2017-06-26
pjp
return -1;
131
2017-06-26
pjp
n->len = key->size;
132
2017-06-26
pjp
memcpy(n->domainname, key->data, n->len);
133
2020-07-08
pjp
n->data = data->data;
134
2017-06-26
pjp
n->datalen = data->size;
136
2019-02-19
pjp
RB_INSERT(domaintree, &db->head, n);
137
2017-06-26
pjp
} else {
138
2019-02-15
pjp
if (res->datalen != data->size)
139
2019-02-15
pjp
return -1;
141
2021-01-04
pjp
if (res->data != data->data) {
142
2021-01-04
pjp
remove_rbt((struct rbtree *)res->data);
145
2020-07-08
pjp
res->data = data->data;
146
2020-07-08
pjp
RB_REMOVE(domaintree, &db->head, res);
147
2020-07-08
pjp
RB_INSERT(domaintree, &db->head, res);
150
2017-06-26
pjp
return 0;
154
2017-06-26
pjp
dddbget(ddDB *db, ddDBT *key, ddDBT *data)
156
2017-06-26
pjp
struct node find, *res;
158
2019-02-18
pjp
memset(&find, 0, sizeof(struct node));
159
2017-06-26
pjp
strlcpy(find.domainname, key->data, sizeof(find.domainname));
160
2017-06-26
pjp
find.len = key->size;
162
2019-02-19
pjp
res = RB_FIND(domaintree, &db->head, &find);
163
2017-06-26
pjp
if (res == NULL) {
164
2017-06-26
pjp
return -1;
167
2017-06-26
pjp
data->size = res->datalen;
168
2017-06-26
pjp
data->data = res->data;
170
2017-06-26
pjp
return 0;
174
2017-06-26
pjp
dddbclose(ddDB *db)
176
2020-07-27
pjp
free (db);
177
2019-02-15
pjp
return 0;
180
2019-02-15
pjp
struct rbtree *
181
2020-07-15
pjp
create_rr(ddDB *db, char *name, int len, int type, void *rdata, uint32_t ttl, uint16_t rdlen)
183
2020-07-08
pjp
ddDBT key, data;
184
2019-02-15
pjp
struct rbtree *rbt = NULL;
185
2019-02-15
pjp
struct rrset *rrset = NULL;
186
2019-02-15
pjp
struct rr *myrr = NULL;
187
2019-02-15
pjp
char *humanname = NULL;
189
2019-02-15
pjp
rbt = find_rrset(db, name, len);
190
2019-02-15
pjp
if (rbt == NULL) {
191
2019-02-15
pjp
rbt = (struct rbtree *) calloc(1, sizeof(struct rbtree));
192
2019-02-15
pjp
if (! rbt) {
193
2019-02-15
pjp
perror("calloc");
194
2019-02-15
pjp
return NULL;
197
2019-02-15
pjp
strlcpy(rbt->zone, name, sizeof(rbt->zone));
198
2019-02-15
pjp
rbt->zonelen = len;
199
2019-02-15
pjp
humanname = convert_name(name, len);
200
2019-02-15
pjp
strlcpy(rbt->humanname, humanname, sizeof(rbt->humanname));
201
2019-11-11
pjp
rbt->flags &= ~RBT_DNSSEC; /* by default not dnssec'ed */
203
2019-02-15
pjp
TAILQ_INIT(&rbt->rrset_head);
205
2020-07-08
pjp
/* rb insert too */
206
2020-07-08
pjp
memset(&key, 0, sizeof(key));
207
2020-07-08
pjp
memset(&data, 0, sizeof(data));
209
2020-07-08
pjp
key.data = (char *)name;
210
2020-07-08
pjp
key.size = len;
212
2020-07-08
pjp
data.data = (void *)rbt;
213
2020-07-08
pjp
data.size = sizeof(struct rbtree);
215
2020-07-08
pjp
db->put(db, &key, &data);
218
2019-02-15
pjp
rrset = find_rr(rbt, type);
219
2019-02-15
pjp
if (rrset == NULL) {
220
2019-02-15
pjp
rrset = (struct rrset *)calloc(1, sizeof(struct rrset));
221
2019-02-15
pjp
if (! rrset){
222
2019-02-15
pjp
perror("calloc");
223
2019-02-15
pjp
return NULL;
226
2019-02-15
pjp
rrset->rrtype = type;
227
2020-05-07
pjp
if (type != DNS_TYPE_RRSIG)
228
2020-05-07
pjp
rrset->ttl = ttl;
230
2020-05-07
pjp
rrset->ttl = 0; /* fill in later */
232
2020-07-06
pjp
rrset->created = time(NULL);
234
2020-07-06
pjp
TAILQ_INIT(&rrset->rr_head);
235
2019-02-15
pjp
TAILQ_INSERT_TAIL(&rbt->rrset_head, rrset, entries);
237
2020-07-06
pjp
rrset->created = time(NULL);
239
2019-02-19
pjp
/* this sets up the RR */
241
2019-02-15
pjp
myrr = (struct rr *)calloc(1, sizeof(struct rr));
242
2019-02-15
pjp
if (! myrr) {
243
2019-02-15
pjp
perror("calloc");
244
2019-02-15
pjp
return NULL;
247
2020-07-08
pjp
switch (type) {
248
2020-07-08
pjp
case DNS_TYPE_A:
249
2020-07-08
pjp
myrr->rdata = (struct a *)rdata;
251
2020-07-08
pjp
default:
252
2020-07-08
pjp
myrr->rdata = rdata;
255
2019-02-15
pjp
myrr->changed = time(NULL);
256
2020-07-15
pjp
myrr->rdlen = rdlen;
257
2021-01-05
pjp
myrr->zonenumber = zonenumber - 1; /* needed for glued ns */
259
2020-07-06
pjp
rrset->ttl = ttl;
261
2020-05-07
pjp
if (type == DNS_TYPE_RRSIG) {
262
2020-05-07
pjp
struct rrsig *rrsig = (struct rrsig *)rdata;
263
2020-05-07
pjp
rrsig->ttl = ttl;
264
2020-07-06
pjp
rrsig->created = time(NULL);
267
2019-02-19
pjp
TAILQ_INSERT_TAIL(&rrset->rr_head, myrr, entries);
269
2019-02-15
pjp
return (rbt);
273
2019-02-15
pjp
struct rbtree *
274
2019-02-15
pjp
find_rrset(ddDB *db, char *name, int len)
276
2021-01-04
pjp
static ddDBT key, data;
278
2019-02-18
pjp
if (name == NULL || len == 0)
279
2019-02-18
pjp
return NULL;
281
2019-02-15
pjp
memset(&key, 0, sizeof(key));
282
2019-02-15
pjp
memset(&data, 0, sizeof(data));
284
2019-02-15
pjp
key.data = (char *)name;
285
2019-02-15
pjp
key.size = len;
287
2019-02-15
pjp
if (db->get(db, &key, &data) != 0) {
288
2019-02-15
pjp
return (NULL);
291
2020-07-08
pjp
return ((struct rbtree *)data.data);
296
2019-02-15
pjp
add_rr(struct rbtree *rbt, char *name, int len, u_int16_t rrtype, void *rdata)
298
2019-02-15
pjp
struct rrset *rp0, *rp;
299
2019-02-15
pjp
struct rr *rt;
301
2019-02-15
pjp
TAILQ_FOREACH_SAFE(rp, &rbt->rrset_head, entries, rp0) {
302
2019-02-15
pjp
if (rrtype == rp->rrtype)
306
2019-02-15
pjp
if (rp == NULL) {
307
2019-02-15
pjp
/* the rrset doesn't exist, create it */
308
2019-02-15
pjp
rp = (struct rrset *)calloc(1, sizeof(struct rrset));
309
2019-02-15
pjp
if (! rp) {
310
2019-02-15
pjp
perror("calloc");
311
2019-02-15
pjp
return -1;
314
2019-02-15
pjp
rp->rrtype = rrtype;
315
2020-05-07
pjp
rp->ttl = 86400;
316
2019-02-15
pjp
TAILQ_INIT(&rp->rr_head);
318
2019-02-15
pjp
TAILQ_INSERT_TAIL(&rbt->rrset_head, rp, entries);
321
2019-02-15
pjp
rt = calloc(1, sizeof(struct rr));
322
2019-02-15
pjp
if (rt == NULL) {
323
2019-02-15
pjp
perror("calloc");
324
2019-02-15
pjp
return -1;
327
2019-02-15
pjp
rt->changed = time(NULL);
328
2019-02-15
pjp
rt->rdata = rdata;
330
2019-02-15
pjp
TAILQ_INSERT_HEAD(&rp->rr_head, rt, entries);
332
2019-02-15
pjp
return 0;
336
2020-07-08
pjp
expire_rr(ddDB *db, char *name, int len, u_int16_t rrtype, time_t now)
338
2020-07-06
pjp
struct rbtree *rbt = NULL;
339
2020-07-06
pjp
struct rrset *rp;
340
2020-07-08
pjp
struct rr *rt1 = NULL, *rt2 = NULL;
341
2020-07-06
pjp
int count = 0;
343
2020-07-06
pjp
rbt = find_rrset(db, name, len);
344
2020-07-06
pjp
if (rbt == NULL) {
345
2020-07-06
pjp
return 0;
348
2020-07-06
pjp
rp = find_rr(rbt, rrtype);
349
2020-07-06
pjp
if (rp == NULL) {
350
2020-07-06
pjp
return 0;
353
2020-07-06
pjp
/* expire these */
354
2020-07-06
pjp
if (rrtype != DNS_TYPE_RRSIG) {
355
2020-07-10
pjp
if (difftime(now, rp->created) >= (double)rp->ttl) {
356
2020-07-06
pjp
count = 0;
358
2020-07-06
pjp
TAILQ_FOREACH_SAFE(rt1, &rp->rr_head, entries, rt2) {
359
2020-07-06
pjp
TAILQ_REMOVE(&rp->rr_head, rt1, entries);
360
2020-07-06
pjp
free(rt1->rdata);
361
2020-07-06
pjp
free(rt1);
362
2020-07-06
pjp
count++;
365
2020-07-08
pjp
TAILQ_REMOVE(&rbt->rrset_head, rp, entries);
366
2020-07-08
pjp
free(rp);
368
2020-07-06
pjp
return (count);
370
2020-07-06
pjp
} else {
371
2020-07-08
pjp
count = 0;
372
2020-07-08
pjp
TAILQ_FOREACH_SAFE(rt1, &rp->rr_head, entries, rt2) {
373
2020-07-08
pjp
struct rrsig *rrsig = (struct rrsig *)rt1->rdata;
374
2020-07-10
pjp
if (difftime(now, rrsig->created) >= (double)rrsig->ttl) {
375
2020-07-06
pjp
TAILQ_REMOVE(&rp->rr_head, rt1, entries);
376
2020-07-06
pjp
free(rt1->rdata);
377
2020-07-06
pjp
free(rt1);
378
2020-07-06
pjp
count++;
382
2020-07-08
pjp
if (TAILQ_EMPTY(&rp->rr_head)) {
383
2020-07-08
pjp
TAILQ_REMOVE(&rbt->rrset_head, rp, entries);
384
2020-07-08
pjp
free(rp);
387
2020-07-08
pjp
return (count);
390
2020-07-06
pjp
return 0;
394
2020-07-08
pjp
expire_db(ddDB *db, int all)
396
2020-07-08
pjp
struct node *walk, *walk0;
397
2020-07-08
pjp
struct rbtree *rbt = NULL;
398
2021-01-04
pjp
struct rrset *rp, *rp0, *rp2;
399
2021-01-04
pjp
struct rr *rt1 = NULL, *rt2 = NULL;
400
2020-07-08
pjp
int totalcount = 0, count = 0;
401
2020-07-08
pjp
time_t now;
403
2020-07-08
pjp
if (all == 0)
404
2020-07-08
pjp
now = time(NULL);
406
2020-07-08
pjp
#if __OpenBSD__
407
2020-07-10
pjp
now = 4000000000; /* Tue Oct 2 09:06:40 CEST 2096 hbdM */
410
2020-07-08
pjp
now = 2147483647;
413
2020-07-08
pjp
RB_FOREACH_SAFE(walk, domaintree, &db->head, walk0) {
414
2020-07-08
pjp
rbt = (struct rbtree *)walk->data;
415
2020-07-08
pjp
if (rbt == NULL)
416
2020-07-08
pjp
continue;
418
2020-07-08
pjp
TAILQ_FOREACH_SAFE(rp, &rbt->rrset_head, entries, rp0) {
419
2021-01-04
pjp
rp2 = find_rr(rbt, rp->rrtype);
420
2021-01-04
pjp
if (rp2 == NULL) {
421
2021-01-04
pjp
return 0;
423
2021-01-04
pjp
if (rp->rrtype != DNS_TYPE_RRSIG) {
424
2021-01-04
pjp
if (difftime(now, rp2->created) >= (double)rp2->ttl) {
425
2021-01-04
pjp
count = 0;
427
2021-01-04
pjp
TAILQ_FOREACH_SAFE(rt1, &rp2->rr_head, entries, rt2) {
428
2021-01-04
pjp
TAILQ_REMOVE(&rp2->rr_head, rt1, entries);
429
2021-01-04
pjp
free(rt1->rdata);
430
2021-01-04
pjp
free(rt1);
431
2021-01-04
pjp
count++;
434
2021-01-04
pjp
TAILQ_REMOVE(&rbt->rrset_head, rp2, entries);
435
2021-01-04
pjp
free(rp2);
437
2021-01-04
pjp
return (count);
439
2021-01-04
pjp
} else {
440
2021-01-04
pjp
count = 0;
441
2021-01-04
pjp
TAILQ_FOREACH_SAFE(rt1, &rp2->rr_head, entries, rt2) {
442
2021-01-04
pjp
struct rrsig *rrsig = (struct rrsig *)rt1->rdata;
443
2021-01-04
pjp
if (difftime(now, rrsig->created) >= (double)rrsig->ttl) {
444
2021-01-04
pjp
TAILQ_REMOVE(&rp2->rr_head, rt1, entries);
445
2021-01-04
pjp
free(rt1->rdata);
446
2021-01-04
pjp
free(rt1);
447
2021-01-04
pjp
count++;
451
2021-01-04
pjp
if (TAILQ_EMPTY(&rp2->rr_head)) {
452
2021-01-04
pjp
TAILQ_REMOVE(&rbt->rrset_head, rp, entries);
453
2021-01-04
pjp
free(rp2);
457
2020-07-08
pjp
totalcount += count;
460
2020-07-27
pjp
RB_REMOVE(domaintree, &db->head, walk);
461
2020-07-27
pjp
free(walk);
462
2021-01-04
pjp
free(rbt);
465
2020-07-08
pjp
return (totalcount);
468
2019-02-15
pjp
struct rrset *
469
2019-02-15
pjp
find_rr(struct rbtree *rbt, u_int16_t rrtype)
471
2019-11-02
pjp
struct rrset *rp = NULL, *rp0 = NULL;
473
2020-07-06
pjp
if (TAILQ_EMPTY(&rbt->rrset_head))
474
2020-07-06
pjp
return NULL;
476
2019-02-15
pjp
TAILQ_FOREACH_SAFE(rp, &rbt->rrset_head, entries, rp0) {
477
2019-02-15
pjp
if (rrtype == rp->rrtype)
481
2019-02-15
pjp
return (rp);
485
2021-01-07
pjp
flag_rr(struct rbtree *rbt, uint32_t flag)
487
2021-01-07
pjp
rbt->flags |= flag;
491
2019-02-15
pjp
display_rr(struct rrset *rrset)
493
2019-02-15
pjp
struct rr *rrp, *rrp0;
495
2019-02-15
pjp
TAILQ_FOREACH_SAFE(rrp, &rrset->rr_head, entries, rrp0) {
496
2020-01-14
pjp
#if __linux__
497
2020-05-07
pjp
printf("%ld:%u:%s\n", rrp->changed, rrset->ttl, (char *)rrp->rdata);
499
2020-05-07
pjp
printf("%lld:%u:%s\n", rrp->changed, rrset->ttl, (char *)rrp->rdata);
503
2019-02-15
pjp
return 0;
507
2019-02-15
pjp
rotate_rr(struct rrset *rrset)
509
2019-02-15
pjp
struct rr *rrp;
511
2019-02-15
pjp
rrp = TAILQ_LAST(&rrset->rr_head, rrh);
512
2019-02-15
pjp
if (rrp == NULL)
513
2019-02-15
pjp
return -1;
515
2019-02-15
pjp
TAILQ_REMOVE(&rrset->rr_head, rrp, entries);
516
2019-02-15
pjp
TAILQ_INSERT_HEAD(&rrset->rr_head, rrp, entries);
518
2021-01-04
pjp
return 0;
522
2021-01-04
pjp
remove_rbt(struct rbtree *rbt)
524
2021-01-04
pjp
struct rrset *rp = NULL, *rp0 = NULL, *rp2 = NULL;
525
2021-01-04
pjp
struct rr *rt1 = NULL, *rt2 = NULL;
527
2021-01-04
pjp
if (rbt == NULL)
530
2021-01-04
pjp
TAILQ_FOREACH_SAFE(rp, &rbt->rrset_head, entries, rp0) {
531
2021-01-04
pjp
rp2 = find_rr(rbt, rp->rrtype);
532
2021-01-04
pjp
if (rp2 == NULL) {
535
2021-01-04
pjp
if (rp->rrtype != DNS_TYPE_RRSIG) {
536
2021-01-04
pjp
TAILQ_FOREACH_SAFE(rt1, &rp2->rr_head, entries, rt2) {
537
2021-01-04
pjp
TAILQ_REMOVE(&rp2->rr_head, rt1, entries);
538
2021-01-04
pjp
free(rt1->rdata);
539
2021-01-04
pjp
free(rt1);
542
2021-01-04
pjp
TAILQ_REMOVE(&rbt->rrset_head, rp2, entries);
543
2021-01-04
pjp
free(rp2);
544
2021-01-04
pjp
} else {
545
2021-01-04
pjp
TAILQ_FOREACH_SAFE(rt1, &rp2->rr_head, entries, rt2) {
546
2021-01-04
pjp
TAILQ_REMOVE(&rp2->rr_head, rt1, entries);
547
2021-01-04
pjp
free(rt1->rdata);
548
2021-01-04
pjp
free(rt1);
550
2021-01-04
pjp
if (TAILQ_EMPTY(&rp2->rr_head)) {
551
2021-01-04
pjp
TAILQ_REMOVE(&rbt->rrset_head, rp, entries);
552
2021-01-04
pjp
free(rp2);
557
2021-01-04
pjp
free(rbt);
563
2021-01-05
pjp
* MATCH_ZONEGLUE - match if there is over 1 links to different zones inside
564
2021-01-05
pjp
* this rbt, this means that there is glue information
565
2021-01-05
pjp
* out there...
569
2021-01-05
pjp
match_zoneglue(struct rbtree *rbt)
571
2021-01-05
pjp
struct rrset *rrset = NULL;
572
2021-01-05
pjp
struct rr *rt1 = NULL;
573
2021-01-05
pjp
uint32_t lastzonenum = (uint32_t)-1;
575
2021-01-05
pjp
TAILQ_FOREACH(rrset, &rbt->rrset_head, entries) {
576
2021-01-05
pjp
if (rrset) {
577
2021-01-05
pjp
TAILQ_FOREACH(rt1, &rrset->rr_head, entries) {
578
2021-01-05
pjp
if (lastzonenum != (uint32_t)-1 &&
579
2021-01-05
pjp
lastzonenum != rt1->zonenumber)
580
2021-01-05
pjp
return 1;
581
2021-01-05
pjp
lastzonenum = rt1->zonenumber;
586
2021-01-05
pjp
return 0;