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 GENERIC_URI_256_C
15 #define GENERIC_URI_256_C 1
16
17 #define RRTYPE_URI_ATTRIBUTES (0)
18
19 static inline isc_result_t
fromtext_uri(ARGS_FROMTEXT)20 fromtext_uri(ARGS_FROMTEXT) {
21 isc_token_t token;
22
23 REQUIRE(type == dns_rdatatype_uri);
24
25 UNUSED(type);
26 UNUSED(rdclass);
27 UNUSED(origin);
28 UNUSED(options);
29 UNUSED(callbacks);
30
31 /*
32 * Priority
33 */
34 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
35 false));
36 if (token.value.as_ulong > 0xffffU) {
37 RETTOK(ISC_R_RANGE);
38 }
39 RETERR(uint16_tobuffer(token.value.as_ulong, target));
40
41 /*
42 * Weight
43 */
44 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
45 false));
46 if (token.value.as_ulong > 0xffffU) {
47 RETTOK(ISC_R_RANGE);
48 }
49 RETERR(uint16_tobuffer(token.value.as_ulong, target));
50
51 /*
52 * Target URI
53 */
54 RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_qstring,
55 false));
56 if (token.type != isc_tokentype_qstring) {
57 RETTOK(DNS_R_SYNTAX);
58 }
59 RETTOK(multitxt_fromtext(&token.value.as_textregion, target));
60 return (ISC_R_SUCCESS);
61 }
62
63 static inline isc_result_t
totext_uri(ARGS_TOTEXT)64 totext_uri(ARGS_TOTEXT) {
65 isc_region_t region;
66 unsigned short priority, weight;
67 char buf[sizeof("65000 ")];
68
69 UNUSED(tctx);
70
71 REQUIRE(rdata->type == dns_rdatatype_uri);
72 REQUIRE(rdata->length != 0);
73
74 dns_rdata_toregion(rdata, ®ion);
75
76 /*
77 * Priority
78 */
79 priority = uint16_fromregion(®ion);
80 isc_region_consume(®ion, 2);
81 snprintf(buf, sizeof(buf), "%u ", priority);
82 RETERR(str_totext(buf, target));
83
84 /*
85 * Weight
86 */
87 weight = uint16_fromregion(®ion);
88 isc_region_consume(®ion, 2);
89 snprintf(buf, sizeof(buf), "%u ", weight);
90 RETERR(str_totext(buf, target));
91
92 /*
93 * Target URI
94 */
95 RETERR(multitxt_totext(®ion, target));
96 return (ISC_R_SUCCESS);
97 }
98
99 static inline isc_result_t
fromwire_uri(ARGS_FROMWIRE)100 fromwire_uri(ARGS_FROMWIRE) {
101 isc_region_t region;
102
103 REQUIRE(type == dns_rdatatype_uri);
104
105 UNUSED(type);
106 UNUSED(rdclass);
107 UNUSED(dctx);
108 UNUSED(options);
109
110 /*
111 * Priority, weight
112 */
113 isc_buffer_activeregion(source, ®ion);
114 if (region.length < 4) {
115 return (ISC_R_UNEXPECTEDEND);
116 }
117
118 /*
119 * Priority, weight and target URI
120 */
121 isc_buffer_forward(source, region.length);
122 return (mem_tobuffer(target, region.base, region.length));
123 }
124
125 static inline isc_result_t
towire_uri(ARGS_TOWIRE)126 towire_uri(ARGS_TOWIRE) {
127 isc_region_t region;
128
129 REQUIRE(rdata->type == dns_rdatatype_uri);
130 REQUIRE(rdata->length != 0);
131
132 UNUSED(cctx);
133
134 dns_rdata_toregion(rdata, ®ion);
135 return (mem_tobuffer(target, region.base, region.length));
136 }
137
138 static inline int
compare_uri(ARGS_COMPARE)139 compare_uri(ARGS_COMPARE) {
140 isc_region_t r1;
141 isc_region_t r2;
142 int order;
143
144 REQUIRE(rdata1->type == rdata2->type);
145 REQUIRE(rdata1->rdclass == rdata2->rdclass);
146 REQUIRE(rdata1->type == dns_rdatatype_uri);
147 REQUIRE(rdata1->length != 0);
148 REQUIRE(rdata2->length != 0);
149
150 dns_rdata_toregion(rdata1, &r1);
151 dns_rdata_toregion(rdata2, &r2);
152
153 /*
154 * Priority
155 */
156 order = memcmp(r1.base, r2.base, 2);
157 if (order != 0) {
158 return (order < 0 ? -1 : 1);
159 }
160 isc_region_consume(&r1, 2);
161 isc_region_consume(&r2, 2);
162
163 /*
164 * Weight
165 */
166 order = memcmp(r1.base, r2.base, 2);
167 if (order != 0) {
168 return (order < 0 ? -1 : 1);
169 }
170 isc_region_consume(&r1, 2);
171 isc_region_consume(&r2, 2);
172
173 return (isc_region_compare(&r1, &r2));
174 }
175
176 static inline isc_result_t
fromstruct_uri(ARGS_FROMSTRUCT)177 fromstruct_uri(ARGS_FROMSTRUCT) {
178 dns_rdata_uri_t *uri = source;
179
180 REQUIRE(type == dns_rdatatype_uri);
181 REQUIRE(uri != NULL);
182 REQUIRE(uri->common.rdtype == type);
183 REQUIRE(uri->common.rdclass == rdclass);
184 REQUIRE(uri->target != NULL && uri->tgt_len != 0);
185
186 UNUSED(type);
187 UNUSED(rdclass);
188
189 /*
190 * Priority
191 */
192 RETERR(uint16_tobuffer(uri->priority, target));
193
194 /*
195 * Weight
196 */
197 RETERR(uint16_tobuffer(uri->weight, target));
198
199 /*
200 * Target URI
201 */
202 return (mem_tobuffer(target, uri->target, uri->tgt_len));
203 }
204
205 static inline isc_result_t
tostruct_uri(ARGS_TOSTRUCT)206 tostruct_uri(ARGS_TOSTRUCT) {
207 dns_rdata_uri_t *uri = target;
208 isc_region_t sr;
209
210 REQUIRE(rdata->type == dns_rdatatype_uri);
211 REQUIRE(uri != NULL);
212 REQUIRE(rdata->length != 0);
213
214 uri->common.rdclass = rdata->rdclass;
215 uri->common.rdtype = rdata->type;
216 ISC_LINK_INIT(&uri->common, link);
217
218 dns_rdata_toregion(rdata, &sr);
219
220 /*
221 * Priority
222 */
223 if (sr.length < 2) {
224 return (ISC_R_UNEXPECTEDEND);
225 }
226 uri->priority = uint16_fromregion(&sr);
227 isc_region_consume(&sr, 2);
228
229 /*
230 * Weight
231 */
232 if (sr.length < 2) {
233 return (ISC_R_UNEXPECTEDEND);
234 }
235 uri->weight = uint16_fromregion(&sr);
236 isc_region_consume(&sr, 2);
237
238 /*
239 * Target URI
240 */
241 uri->tgt_len = sr.length;
242 uri->target = mem_maybedup(mctx, sr.base, sr.length);
243 if (uri->target == NULL) {
244 return (ISC_R_NOMEMORY);
245 }
246
247 uri->mctx = mctx;
248 return (ISC_R_SUCCESS);
249 }
250
251 static inline void
freestruct_uri(ARGS_FREESTRUCT)252 freestruct_uri(ARGS_FREESTRUCT) {
253 dns_rdata_uri_t *uri = (dns_rdata_uri_t *)source;
254
255 REQUIRE(uri != NULL);
256 REQUIRE(uri->common.rdtype == dns_rdatatype_uri);
257
258 if (uri->mctx == NULL) {
259 return;
260 }
261
262 if (uri->target != NULL) {
263 isc_mem_free(uri->mctx, uri->target);
264 }
265 uri->mctx = NULL;
266 }
267
268 static inline isc_result_t
additionaldata_uri(ARGS_ADDLDATA)269 additionaldata_uri(ARGS_ADDLDATA) {
270 REQUIRE(rdata->type == dns_rdatatype_uri);
271
272 UNUSED(rdata);
273 UNUSED(add);
274 UNUSED(arg);
275
276 return (ISC_R_SUCCESS);
277 }
278
279 static inline isc_result_t
digest_uri(ARGS_DIGEST)280 digest_uri(ARGS_DIGEST) {
281 isc_region_t r;
282
283 REQUIRE(rdata->type == dns_rdatatype_uri);
284
285 dns_rdata_toregion(rdata, &r);
286
287 return ((digest)(arg, &r));
288 }
289
290 static inline bool
checkowner_uri(ARGS_CHECKOWNER)291 checkowner_uri(ARGS_CHECKOWNER) {
292 REQUIRE(type == dns_rdatatype_uri);
293
294 UNUSED(name);
295 UNUSED(type);
296 UNUSED(rdclass);
297 UNUSED(wildcard);
298
299 return (true);
300 }
301
302 static inline bool
checknames_uri(ARGS_CHECKNAMES)303 checknames_uri(ARGS_CHECKNAMES) {
304 REQUIRE(rdata->type == dns_rdatatype_uri);
305
306 UNUSED(rdata);
307 UNUSED(owner);
308 UNUSED(bad);
309
310 return (true);
311 }
312
313 static inline int
casecompare_uri(ARGS_COMPARE)314 casecompare_uri(ARGS_COMPARE) {
315 return (compare_uri(rdata1, rdata2));
316 }
317
318 #endif /* GENERIC_URI_256_C */
319