/src/bind9/lib/dns/rdata/generic/txt_16.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 | | #ifndef RDATA_GENERIC_TXT_16_C |
15 | | #define RDATA_GENERIC_TXT_16_C |
16 | | |
17 | 21.2k | #define RRTYPE_TXT_ATTRIBUTES (0) |
18 | | |
19 | | static isc_result_t |
20 | 289k | generic_fromtext_txt(ARGS_FROMTEXT) { |
21 | 289k | isc_token_t token; |
22 | 289k | int strings; |
23 | | |
24 | 289k | UNUSED(type); |
25 | 289k | UNUSED(rdclass); |
26 | 289k | UNUSED(origin); |
27 | 289k | UNUSED(options); |
28 | 289k | UNUSED(callbacks); |
29 | | |
30 | 289k | strings = 0; |
31 | 289k | if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) { |
32 | 38.2k | isc_textregion_t r; |
33 | 38.2k | r.base = UNCONST("#"); |
34 | 38.2k | r.length = 1; |
35 | 38.2k | RETERR(txt_fromtext(&r, target)); |
36 | 38.2k | strings++; |
37 | 38.2k | } |
38 | 756k | for (;;) { |
39 | 756k | RETERR(isc_lex_getmastertoken(lexer, &token, |
40 | 756k | isc_tokentype_qstring, true)); |
41 | 756k | if (token.type != isc_tokentype_qstring && |
42 | 741k | token.type != isc_tokentype_string) |
43 | 288k | { |
44 | 288k | break; |
45 | 288k | } |
46 | 467k | RETTOK(txt_fromtext(&token.value.as_textregion, target)); |
47 | 467k | strings++; |
48 | 467k | } |
49 | | /* Let upper layer handle eol/eof. */ |
50 | 288k | isc_lex_ungettoken(lexer, &token); |
51 | 288k | return strings == 0 ? ISC_R_UNEXPECTEDEND : ISC_R_SUCCESS; |
52 | 289k | } |
53 | | |
54 | | static isc_result_t |
55 | 6.13k | generic_totext_txt(ARGS_TOTEXT) { |
56 | 6.13k | isc_region_t region; |
57 | | |
58 | 6.13k | UNUSED(tctx); |
59 | | |
60 | 6.13k | dns_rdata_toregion(rdata, ®ion); |
61 | | |
62 | 47.1k | while (region.length > 0) { |
63 | 40.9k | RETERR(txt_totext(®ion, true, target)); |
64 | 40.9k | if (region.length > 0) { |
65 | 34.8k | RETERR(str_totext(" ", target)); |
66 | 34.8k | } |
67 | 40.9k | } |
68 | | |
69 | 6.13k | return ISC_R_SUCCESS; |
70 | 6.13k | } |
71 | | |
72 | | static isc_result_t |
73 | 11.2k | generic_fromwire_txt(ARGS_FROMWIRE) { |
74 | 11.2k | UNUSED(type); |
75 | 11.2k | UNUSED(dctx); |
76 | 11.2k | UNUSED(rdclass); |
77 | | |
78 | 52.6k | do { |
79 | 52.6k | RETERR(txt_fromwire(source, target)); |
80 | 51.9k | } while (!buffer_empty(source)); |
81 | 10.4k | return ISC_R_SUCCESS; |
82 | 11.2k | } |
83 | | |
84 | | static isc_result_t |
85 | 41.5k | fromtext_txt(ARGS_FROMTEXT) { |
86 | 41.5k | REQUIRE(type == dns_rdatatype_txt); |
87 | | |
88 | 41.5k | return generic_fromtext_txt(CALL_FROMTEXT); |
89 | 41.5k | } |
90 | | |
91 | | static isc_result_t |
92 | 1.39k | totext_txt(ARGS_TOTEXT) { |
93 | 1.39k | REQUIRE(rdata != NULL); |
94 | 1.39k | REQUIRE(rdata->type == dns_rdatatype_txt); |
95 | | |
96 | 1.39k | return generic_totext_txt(CALL_TOTEXT); |
97 | 1.39k | } |
98 | | |
99 | | static isc_result_t |
100 | 2.05k | fromwire_txt(ARGS_FROMWIRE) { |
101 | 2.05k | REQUIRE(type == dns_rdatatype_txt); |
102 | | |
103 | 2.05k | return generic_fromwire_txt(CALL_FROMWIRE); |
104 | 2.05k | } |
105 | | |
106 | | static isc_result_t |
107 | 704 | towire_txt(ARGS_TOWIRE) { |
108 | 704 | REQUIRE(rdata->type == dns_rdatatype_txt); |
109 | | |
110 | 704 | UNUSED(cctx); |
111 | | |
112 | 704 | return mem_tobuffer(target, rdata->data, rdata->length); |
113 | 704 | } |
114 | | |
115 | | static int |
116 | 256k | compare_txt(ARGS_COMPARE) { |
117 | 256k | isc_region_t r1; |
118 | 256k | isc_region_t r2; |
119 | | |
120 | 256k | REQUIRE(rdata1->type == rdata2->type); |
121 | 256k | REQUIRE(rdata1->rdclass == rdata2->rdclass); |
122 | 256k | REQUIRE(rdata1->type == dns_rdatatype_txt); |
123 | | |
124 | 256k | dns_rdata_toregion(rdata1, &r1); |
125 | 256k | dns_rdata_toregion(rdata2, &r2); |
126 | 256k | return isc_region_compare(&r1, &r2); |
127 | 256k | } |
128 | | |
129 | | static isc_result_t |
130 | 0 | generic_fromstruct_txt(ARGS_FROMSTRUCT) { |
131 | 0 | dns_rdata_txt_t *txt = source; |
132 | 0 | isc_region_t region; |
133 | 0 | uint8_t length; |
134 | |
|
135 | 0 | REQUIRE(txt != NULL); |
136 | 0 | REQUIRE(txt->common.rdtype == type); |
137 | 0 | REQUIRE(txt->common.rdclass == rdclass); |
138 | 0 | REQUIRE(txt->txt != NULL && txt->txt_len != 0); |
139 | |
|
140 | 0 | UNUSED(type); |
141 | 0 | UNUSED(rdclass); |
142 | |
|
143 | 0 | region.base = txt->txt; |
144 | 0 | region.length = txt->txt_len; |
145 | 0 | while (region.length > 0) { |
146 | 0 | length = uint8_fromregion(®ion); |
147 | 0 | isc_region_consume(®ion, 1); |
148 | 0 | if (region.length < length) { |
149 | 0 | return ISC_R_UNEXPECTEDEND; |
150 | 0 | } |
151 | 0 | isc_region_consume(®ion, length); |
152 | 0 | } |
153 | | |
154 | 0 | return mem_tobuffer(target, txt->txt, txt->txt_len); |
155 | 0 | } |
156 | | |
157 | | static isc_result_t |
158 | 0 | generic_tostruct_txt(ARGS_TOSTRUCT) { |
159 | 0 | dns_rdata_txt_t *txt = target; |
160 | 0 | isc_region_t r; |
161 | |
|
162 | 0 | REQUIRE(txt != NULL); |
163 | 0 | REQUIRE(txt->common.rdclass == rdata->rdclass); |
164 | 0 | REQUIRE(txt->common.rdtype == rdata->type); |
165 | |
|
166 | 0 | dns_rdata_toregion(rdata, &r); |
167 | 0 | txt->txt_len = r.length; |
168 | 0 | txt->txt = mem_maybedup(mctx, r.base, r.length); |
169 | 0 | txt->offset = 0; |
170 | 0 | txt->mctx = mctx; |
171 | 0 | return ISC_R_SUCCESS; |
172 | 0 | } |
173 | | |
174 | | static void |
175 | 0 | generic_freestruct_txt(ARGS_FREESTRUCT) { |
176 | 0 | dns_rdata_txt_t *txt = source; |
177 | |
|
178 | 0 | REQUIRE(txt != NULL); |
179 | |
|
180 | 0 | if (txt->mctx == NULL) { |
181 | 0 | return; |
182 | 0 | } |
183 | | |
184 | 0 | if (txt->txt != NULL) { |
185 | 0 | isc_mem_free(txt->mctx, txt->txt); |
186 | 0 | } |
187 | 0 | txt->mctx = NULL; |
188 | 0 | } |
189 | | |
190 | | static isc_result_t |
191 | 0 | fromstruct_txt(ARGS_FROMSTRUCT) { |
192 | 0 | REQUIRE(type == dns_rdatatype_txt); |
193 | |
|
194 | 0 | return generic_fromstruct_txt(CALL_FROMSTRUCT); |
195 | 0 | } |
196 | | |
197 | | static isc_result_t |
198 | 0 | tostruct_txt(ARGS_TOSTRUCT) { |
199 | 0 | dns_rdata_txt_t *txt = target; |
200 | |
|
201 | 0 | REQUIRE(rdata->type == dns_rdatatype_txt); |
202 | 0 | REQUIRE(txt != NULL); |
203 | |
|
204 | 0 | DNS_RDATACOMMON_INIT(txt, rdata->type, rdata->rdclass); |
205 | |
|
206 | 0 | return generic_tostruct_txt(CALL_TOSTRUCT); |
207 | 0 | } |
208 | | |
209 | | static void |
210 | 0 | freestruct_txt(ARGS_FREESTRUCT) { |
211 | 0 | dns_rdata_txt_t *txt = source; |
212 | |
|
213 | 0 | REQUIRE(txt != NULL); |
214 | 0 | REQUIRE(txt->common.rdtype == dns_rdatatype_txt); |
215 | |
|
216 | 0 | generic_freestruct_txt(source); |
217 | 0 | } |
218 | | |
219 | | static isc_result_t |
220 | 0 | additionaldata_txt(ARGS_ADDLDATA) { |
221 | 0 | REQUIRE(rdata->type == dns_rdatatype_txt); |
222 | |
|
223 | 0 | UNUSED(rdata); |
224 | 0 | UNUSED(owner); |
225 | 0 | UNUSED(add); |
226 | 0 | UNUSED(arg); |
227 | |
|
228 | 0 | return ISC_R_SUCCESS; |
229 | 0 | } |
230 | | |
231 | | static isc_result_t |
232 | 0 | digest_txt(ARGS_DIGEST) { |
233 | 0 | isc_region_t r; |
234 | |
|
235 | 0 | REQUIRE(rdata->type == dns_rdatatype_txt); |
236 | |
|
237 | 0 | dns_rdata_toregion(rdata, &r); |
238 | |
|
239 | 0 | return (digest)(arg, &r); |
240 | 0 | } |
241 | | |
242 | | static bool |
243 | 0 | checkowner_txt(ARGS_CHECKOWNER) { |
244 | 0 | REQUIRE(type == dns_rdatatype_txt); |
245 | |
|
246 | 0 | UNUSED(name); |
247 | 0 | UNUSED(type); |
248 | 0 | UNUSED(rdclass); |
249 | 0 | UNUSED(wildcard); |
250 | |
|
251 | 0 | return true; |
252 | 0 | } |
253 | | |
254 | | static bool |
255 | 0 | checknames_txt(ARGS_CHECKNAMES) { |
256 | 0 | REQUIRE(rdata->type == dns_rdatatype_txt); |
257 | |
|
258 | 0 | UNUSED(rdata); |
259 | 0 | UNUSED(owner); |
260 | 0 | UNUSED(bad); |
261 | |
|
262 | 0 | return true; |
263 | 0 | } |
264 | | |
265 | | static int |
266 | 0 | casecompare_txt(ARGS_COMPARE) { |
267 | 0 | return compare_txt(rdata1, rdata2); |
268 | 0 | } |
269 | | |
270 | | static isc_result_t |
271 | 0 | generic_txt_first(dns_rdata_txt_t *txt) { |
272 | 0 | REQUIRE(txt != NULL); |
273 | 0 | REQUIRE(txt->txt != NULL || txt->txt_len == 0); |
274 | |
|
275 | 0 | if (txt->txt_len == 0) { |
276 | 0 | return ISC_R_NOMORE; |
277 | 0 | } |
278 | | |
279 | 0 | txt->offset = 0; |
280 | 0 | return ISC_R_SUCCESS; |
281 | 0 | } |
282 | | |
283 | | static isc_result_t |
284 | 0 | generic_txt_next(dns_rdata_txt_t *txt) { |
285 | 0 | isc_region_t r; |
286 | 0 | uint8_t length; |
287 | |
|
288 | 0 | REQUIRE(txt != NULL); |
289 | 0 | REQUIRE(txt->txt != NULL && txt->txt_len != 0); |
290 | |
|
291 | 0 | INSIST(txt->offset + 1 <= txt->txt_len); |
292 | 0 | r.base = txt->txt + txt->offset; |
293 | 0 | r.length = txt->txt_len - txt->offset; |
294 | 0 | length = uint8_fromregion(&r); |
295 | 0 | INSIST(txt->offset + 1 + length <= txt->txt_len); |
296 | 0 | txt->offset = txt->offset + 1 + length; |
297 | 0 | if (txt->offset == txt->txt_len) { |
298 | 0 | return ISC_R_NOMORE; |
299 | 0 | } |
300 | 0 | return ISC_R_SUCCESS; |
301 | 0 | } |
302 | | |
303 | | static isc_result_t |
304 | 0 | generic_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { |
305 | 0 | isc_region_t r; |
306 | |
|
307 | 0 | REQUIRE(txt != NULL); |
308 | 0 | REQUIRE(string != NULL); |
309 | 0 | REQUIRE(txt->txt != NULL); |
310 | 0 | REQUIRE(txt->offset < txt->txt_len); |
311 | |
|
312 | 0 | INSIST(txt->offset + 1 <= txt->txt_len); |
313 | 0 | r.base = txt->txt + txt->offset; |
314 | 0 | r.length = txt->txt_len - txt->offset; |
315 | |
|
316 | 0 | string->length = uint8_fromregion(&r); |
317 | 0 | isc_region_consume(&r, 1); |
318 | 0 | string->data = r.base; |
319 | 0 | INSIST(txt->offset + 1 + string->length <= txt->txt_len); |
320 | |
|
321 | 0 | return ISC_R_SUCCESS; |
322 | 0 | } |
323 | | |
324 | | isc_result_t |
325 | 0 | dns_rdata_txt_first(dns_rdata_txt_t *txt) { |
326 | 0 | REQUIRE(txt != NULL); |
327 | 0 | REQUIRE(txt->common.rdtype == dns_rdatatype_txt); |
328 | |
|
329 | 0 | return generic_txt_first(txt); |
330 | 0 | } |
331 | | |
332 | | isc_result_t |
333 | 0 | dns_rdata_txt_next(dns_rdata_txt_t *txt) { |
334 | 0 | REQUIRE(txt != NULL); |
335 | 0 | REQUIRE(txt->common.rdtype == dns_rdatatype_txt); |
336 | |
|
337 | 0 | return generic_txt_next(txt); |
338 | 0 | } |
339 | | |
340 | | isc_result_t |
341 | 0 | dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) { |
342 | 0 | REQUIRE(txt != NULL); |
343 | 0 | REQUIRE(txt->common.rdtype == dns_rdatatype_txt); |
344 | |
|
345 | 0 | return generic_txt_current(txt, string); |
346 | 0 | } |
347 | | #endif /* RDATA_GENERIC_TXT_16_C */ |