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, &region);
77 
78 	/*
79 	 * Priority
80 	 */
81 	priority = uint16_fromregion(&region);
82 	isc_region_consume(&region, 2);
83 	sprintf(buf, "%u ", priority);
84 	RETERR(str_totext(buf, target));
85 
86 	/*
87 	 * Weight
88 	 */
89 	weight = uint16_fromregion(&region);
90 	isc_region_consume(&region, 2);
91 	sprintf(buf, "%u ", weight);
92 	RETERR(str_totext(buf, target));
93 
94 	/*
95 	 * Target URI
96 	 */
97 	RETERR(multitxt_totext(&region, 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, &region);
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, &region);
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