xref: /openbsd-src/usr.bin/dig/lib/dns/rdatalist.c (revision 12363972fc6bdf7ab1bc0d4a72bf988595389d5f)
1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16 
17 /* $Id: rdatalist.c,v 1.6 2022/06/26 09:43:39 florian Exp $ */
18 
19 /*! \file */
20 
21 #include <stddef.h>
22 
23 #include <isc/util.h>
24 
25 #include <dns/rdata.h>
26 #include <dns/rdatalist.h>
27 #include <dns/rdataset.h>
28 
29 #include "rdatalist_p.h"
30 
31 static dns_rdatasetmethods_t methods = {
32 	isc__rdatalist_disassociate,
33 	isc__rdatalist_first,
34 	isc__rdatalist_next,
35 	isc__rdatalist_current,
36 	isc__rdatalist_clone,
37 	isc__rdatalist_count,
38 };
39 
40 void
dns_rdatalist_init(dns_rdatalist_t * rdatalist)41 dns_rdatalist_init(dns_rdatalist_t *rdatalist) {
42 
43 	REQUIRE(rdatalist != NULL);
44 
45 	/*
46 	 * Initialize rdatalist.
47 	 */
48 
49 	rdatalist->rdclass = 0;
50 	rdatalist->type = 0;
51 	rdatalist->covers = 0;
52 	rdatalist->ttl = 0;
53 	ISC_LIST_INIT(rdatalist->rdata);
54 	ISC_LINK_INIT(rdatalist, link);
55 }
56 
57 isc_result_t
dns_rdatalist_tordataset(dns_rdatalist_t * rdatalist,dns_rdataset_t * rdataset)58 dns_rdatalist_tordataset(dns_rdatalist_t *rdatalist,
59 			 dns_rdataset_t *rdataset)
60 {
61 	/*
62 	 * Make 'rdataset' refer to the rdata in 'rdatalist'.
63 	 */
64 
65 	REQUIRE(rdatalist != NULL);
66 	REQUIRE(! dns_rdataset_isassociated(rdataset));
67 
68 	rdataset->methods = &methods;
69 	rdataset->rdclass = rdatalist->rdclass;
70 	rdataset->type = rdatalist->type;
71 	rdataset->covers = rdatalist->covers;
72 	rdataset->ttl = rdatalist->ttl;
73 	rdataset->private1 = rdatalist;
74 	rdataset->private2 = NULL;
75 
76 	return (ISC_R_SUCCESS);
77 }
78 
79 isc_result_t
dns_rdatalist_fromrdataset(dns_rdataset_t * rdataset,dns_rdatalist_t ** rdatalist)80 dns_rdatalist_fromrdataset(dns_rdataset_t *rdataset,
81 			   dns_rdatalist_t **rdatalist)
82 {
83 	REQUIRE(rdatalist != NULL && rdataset != NULL);
84 	*rdatalist = rdataset->private1;
85 
86 	return (ISC_R_SUCCESS);
87 }
88 
89 void
isc__rdatalist_disassociate(dns_rdataset_t * rdataset)90 isc__rdatalist_disassociate(dns_rdataset_t *rdataset) {
91 	UNUSED(rdataset);
92 }
93 
94 isc_result_t
isc__rdatalist_first(dns_rdataset_t * rdataset)95 isc__rdatalist_first(dns_rdataset_t *rdataset) {
96 	dns_rdatalist_t *rdatalist;
97 
98 	rdatalist = rdataset->private1;
99 	rdataset->private2 = ISC_LIST_HEAD(rdatalist->rdata);
100 
101 	if (rdataset->private2 == NULL)
102 		return (ISC_R_NOMORE);
103 
104 	return (ISC_R_SUCCESS);
105 }
106 
107 isc_result_t
isc__rdatalist_next(dns_rdataset_t * rdataset)108 isc__rdatalist_next(dns_rdataset_t *rdataset) {
109 	dns_rdata_t *rdata;
110 
111 	REQUIRE(rdataset != NULL);
112 
113 	rdata = rdataset->private2;
114 	if (rdata == NULL)
115 		return (ISC_R_NOMORE);
116 
117 	rdataset->private2 = ISC_LIST_NEXT(rdata, link);
118 
119 	if (rdataset->private2 == NULL)
120 		return (ISC_R_NOMORE);
121 
122 	return (ISC_R_SUCCESS);
123 }
124 
125 void
isc__rdatalist_current(dns_rdataset_t * rdataset,dns_rdata_t * rdata)126 isc__rdatalist_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata) {
127 	dns_rdata_t *list_rdata;
128 
129 	REQUIRE(rdataset != NULL);
130 
131 	list_rdata = rdataset->private2;
132 	INSIST(list_rdata != NULL);
133 
134 	dns_rdata_clone(list_rdata, rdata);
135 }
136 
137 void
isc__rdatalist_clone(dns_rdataset_t * source,dns_rdataset_t * target)138 isc__rdatalist_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
139 
140 	REQUIRE(source != NULL);
141 	REQUIRE(target != NULL);
142 
143 	*target = *source;
144 
145 	/*
146 	 * Reset iterator state.
147 	 */
148 	target->private2 = NULL;
149 }
150 
151 unsigned int
isc__rdatalist_count(dns_rdataset_t * rdataset)152 isc__rdatalist_count(dns_rdataset_t *rdataset) {
153 	dns_rdatalist_t *rdatalist;
154 	dns_rdata_t *rdata;
155 	unsigned int count;
156 
157 	REQUIRE(rdataset != NULL);
158 
159 	rdatalist = rdataset->private1;
160 
161 	count = 0;
162 	for (rdata = ISC_LIST_HEAD(rdatalist->rdata);
163 	     rdata != NULL;
164 	     rdata = ISC_LIST_NEXT(rdata, link))
165 		count++;
166 
167 	return (count);
168 }
169