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