1253592Serwin/*
2254897Serwin * Copyright (C) 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3253592Serwin *
4253592Serwin * Permission to use, copy, modify, and/or distribute this software for any
5253592Serwin * purpose with or without fee is hereby granted, provided that the above
6253592Serwin * copyright notice and this permission notice appear in all copies.
7253592Serwin *
8253592Serwin * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9253592Serwin * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10253592Serwin * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11253592Serwin * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12253592Serwin * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13253592Serwin * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14253592Serwin * PERFORMANCE OF THIS SOFTWARE.
15253592Serwin */
16253592Serwin
17254897Serwin/* $Id$ */
18253592Serwin
19253592Serwin#ifndef GENERIC_URI_256_C
20253592Serwin#define GENERIC_URI_256_C 1
21253592Serwin
22253592Serwin#define RRTYPE_URI_ATTRIBUTES (0)
23253592Serwin
24253592Serwinstatic inline isc_result_t
25253592Serwinfromtext_uri(ARGS_FROMTEXT) {
26253592Serwin	isc_token_t token;
27253592Serwin
28253592Serwin	REQUIRE(type == 256);
29253592Serwin
30253592Serwin	UNUSED(type);
31253592Serwin	UNUSED(rdclass);
32253592Serwin	UNUSED(origin);
33253592Serwin	UNUSED(options);
34253592Serwin	UNUSED(callbacks);
35253592Serwin
36253592Serwin	/*
37253592Serwin	 * Priority
38253592Serwin	 */
39253592Serwin	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
40253592Serwin				      ISC_FALSE));
41253592Serwin	if (token.value.as_ulong > 0xffffU)
42253592Serwin		RETTOK(ISC_R_RANGE);
43253592Serwin	RETERR(uint16_tobuffer(token.value.as_ulong, target));
44253592Serwin
45253592Serwin	/*
46253592Serwin	 * Weight
47253592Serwin	 */
48253592Serwin	RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
49253592Serwin				      ISC_FALSE));
50253592Serwin	if (token.value.as_ulong > 0xffffU)
51253592Serwin		RETTOK(ISC_R_RANGE);
52253592Serwin	RETERR(uint16_tobuffer(token.value.as_ulong, target));
53253592Serwin
54253592Serwin	/*
55253592Serwin	 * Target URI
56253592Serwin	 */
57253592Serwin	RETERR(isc_lex_getmastertoken(lexer, &token,
58253592Serwin				      isc_tokentype_qstring, ISC_FALSE));
59253592Serwin	if (token.type != isc_tokentype_qstring)
60253592Serwin		RETTOK(DNS_R_SYNTAX);
61253592Serwin	RETTOK(multitxt_fromtext(&token.value.as_textregion, target));
62253592Serwin	return (ISC_R_SUCCESS);
63253592Serwin}
64253592Serwin
65253592Serwinstatic inline isc_result_t
66253592Serwintotext_uri(ARGS_TOTEXT) {
67253592Serwin	isc_region_t region;
68253592Serwin	unsigned short priority, weight;
69253592Serwin	char buf[sizeof("65000 ")];
70253592Serwin
71253592Serwin	UNUSED(tctx);
72253592Serwin
73253592Serwin	REQUIRE(rdata->type == 256);
74253592Serwin	REQUIRE(rdata->length != 0);
75253592Serwin
76253592Serwin	dns_rdata_toregion(rdata, &region);
77253592Serwin
78253592Serwin	/*
79253592Serwin	 * Priority
80253592Serwin	 */
81253592Serwin	priority = uint16_fromregion(&region);
82253592Serwin	isc_region_consume(&region, 2);
83253592Serwin	sprintf(buf, "%u ", priority);
84253592Serwin	RETERR(str_totext(buf, target));
85253592Serwin
86253592Serwin	/*
87253592Serwin	 * Weight
88253592Serwin	 */
89253592Serwin	weight = uint16_fromregion(&region);
90253592Serwin	isc_region_consume(&region, 2);
91253592Serwin	sprintf(buf, "%u ", weight);
92253592Serwin	RETERR(str_totext(buf, target));
93253592Serwin
94253592Serwin	/*
95253592Serwin	 * Target URI
96253592Serwin	 */
97253592Serwin	RETERR(multitxt_totext(&region, target));
98253592Serwin	return (ISC_R_SUCCESS);
99253592Serwin}
100253592Serwin
101253592Serwinstatic inline isc_result_t
102253592Serwinfromwire_uri(ARGS_FROMWIRE) {
103253592Serwin	isc_region_t region;
104253592Serwin
105253592Serwin	REQUIRE(type == 256);
106253592Serwin
107253592Serwin	UNUSED(type);
108253592Serwin	UNUSED(rdclass);
109253592Serwin	UNUSED(dctx);
110253592Serwin	UNUSED(options);
111253592Serwin
112253592Serwin	/*
113253592Serwin	 * Priority, weight
114253592Serwin	 */
115253592Serwin	isc_buffer_activeregion(source, &region);
116253592Serwin	if (region.length < 4)
117253592Serwin		return (ISC_R_UNEXPECTEDEND);
118253592Serwin	RETERR(mem_tobuffer(target, region.base, 4));
119253592Serwin	isc_buffer_forward(source, 4);
120253592Serwin
121253592Serwin	/*
122253592Serwin	 * Target URI
123253592Serwin	 */
124253592Serwin	RETERR(multitxt_fromwire(source, target));
125253592Serwin
126253592Serwin	return (ISC_R_SUCCESS);
127253592Serwin}
128253592Serwin
129253592Serwinstatic inline isc_result_t
130253592Serwintowire_uri(ARGS_TOWIRE) {
131253592Serwin	isc_region_t region;
132253592Serwin
133253592Serwin	REQUIRE(rdata->type == 256);
134253592Serwin	REQUIRE(rdata->length != 0);
135253592Serwin
136253592Serwin	UNUSED(cctx);
137253592Serwin
138253592Serwin	dns_rdata_toregion(rdata, &region);
139253592Serwin	return (mem_tobuffer(target, region.base, region.length));
140253592Serwin}
141253592Serwin
142253592Serwinstatic inline int
143253592Serwincompare_uri(ARGS_COMPARE) {
144253592Serwin	isc_region_t r1;
145253592Serwin	isc_region_t r2;
146253592Serwin	int order;
147253592Serwin
148253592Serwin	REQUIRE(rdata1->type == rdata2->type);
149253592Serwin	REQUIRE(rdata1->rdclass == rdata2->rdclass);
150253592Serwin	REQUIRE(rdata1->type == 256);
151253592Serwin	REQUIRE(rdata1->length != 0);
152253592Serwin	REQUIRE(rdata2->length != 0);
153253592Serwin
154253592Serwin	dns_rdata_toregion(rdata1, &r1);
155253592Serwin	dns_rdata_toregion(rdata2, &r2);
156253592Serwin
157253592Serwin	/*
158253592Serwin	 * Priority
159253592Serwin	 */
160253592Serwin	order = memcmp(r1.base, r2.base, 2);
161253592Serwin	if (order != 0)
162253592Serwin		return (order < 0 ? -1 : 1);
163253592Serwin	isc_region_consume(&r1, 2);
164253592Serwin	isc_region_consume(&r2, 2);
165253592Serwin
166253592Serwin	/*
167253592Serwin	 * Weight
168253592Serwin	 */
169253592Serwin	order = memcmp(r1.base, r2.base, 2);
170253592Serwin	if (order != 0)
171253592Serwin		return (order < 0 ? -1 : 1);
172253592Serwin	isc_region_consume(&r1, 2);
173253592Serwin	isc_region_consume(&r2, 2);
174253592Serwin
175253592Serwin	return (isc_region_compare(&r1, &r2));
176253592Serwin}
177253592Serwin
178253592Serwinstatic inline isc_result_t
179253592Serwinfromstruct_uri(ARGS_FROMSTRUCT) {
180253592Serwin	dns_rdata_uri_t *uri = source;
181253592Serwin	isc_region_t region;
182253592Serwin	isc_uint8_t len;
183253592Serwin
184253592Serwin	REQUIRE(type == 256);
185253592Serwin	REQUIRE(source != NULL);
186253592Serwin	REQUIRE(uri->common.rdtype == type);
187253592Serwin	REQUIRE(uri->common.rdclass == rdclass);
188253592Serwin	REQUIRE(uri->target != NULL && uri->tgt_len != 0);
189253592Serwin
190253592Serwin	UNUSED(type);
191253592Serwin	UNUSED(rdclass);
192253592Serwin
193253592Serwin	/*
194253592Serwin	 * Priority
195253592Serwin	 */
196253592Serwin	RETERR(uint16_tobuffer(uri->priority, target));
197253592Serwin
198253592Serwin	/*
199253592Serwin	 * Weight
200253592Serwin	 */
201253592Serwin	RETERR(uint16_tobuffer(uri->weight, target));
202253592Serwin
203253592Serwin	/*
204253592Serwin	 * Target URI
205253592Serwin	 */
206253592Serwin	len = 255U;
207253592Serwin	region.base = uri->target;
208253592Serwin	region.length = uri->tgt_len;
209253592Serwin	while (region.length > 0) {
210253592Serwin		REQUIRE(len == 255U);
211253592Serwin		len = uint8_fromregion(&region);
212253592Serwin		isc_region_consume(&region, 1);
213253592Serwin		if (region.length < len)
214253592Serwin			return (ISC_R_UNEXPECTEDEND);
215253592Serwin		isc_region_consume(&region, len);
216253592Serwin	}
217253592Serwin
218253592Serwin	return (mem_tobuffer(target, uri->target, uri->tgt_len));
219253592Serwin}
220253592Serwin
221253592Serwinstatic inline isc_result_t
222253592Serwintostruct_uri(ARGS_TOSTRUCT) {
223253592Serwin	dns_rdata_uri_t *uri = target;
224253592Serwin	isc_region_t sr;
225253592Serwin
226253592Serwin	REQUIRE(rdata->type == 256);
227253592Serwin	REQUIRE(target != NULL);
228253592Serwin	REQUIRE(rdata->length != 0);
229253592Serwin
230253592Serwin	uri->common.rdclass = rdata->rdclass;
231253592Serwin	uri->common.rdtype = rdata->type;
232253592Serwin	ISC_LINK_INIT(&uri->common, link);
233253592Serwin
234253592Serwin	dns_rdata_toregion(rdata, &sr);
235253592Serwin
236253592Serwin	/*
237253592Serwin	 * Priority
238253592Serwin	 */
239253592Serwin	if (sr.length < 2)
240253592Serwin		return (ISC_R_UNEXPECTEDEND);
241253592Serwin	uri->priority = uint16_fromregion(&sr);
242253592Serwin	isc_region_consume(&sr, 2);
243253592Serwin
244253592Serwin	/*
245253592Serwin	 * Weight
246253592Serwin	 */
247253592Serwin	if (sr.length < 2)
248253592Serwin		return (ISC_R_UNEXPECTEDEND);
249253592Serwin	uri->weight = uint16_fromregion(&sr);
250253592Serwin	isc_region_consume(&sr, 2);
251253592Serwin
252253592Serwin	/*
253253592Serwin	 * Target URI
254253592Serwin	 */
255253592Serwin	uri->tgt_len = sr.length;
256253592Serwin	uri->target = mem_maybedup(mctx, sr.base, sr.length);
257253592Serwin	if (uri->target == NULL)
258253592Serwin		return (ISC_R_NOMEMORY);
259253592Serwin
260253592Serwin	uri->mctx = mctx;
261253592Serwin	return (ISC_R_SUCCESS);
262253592Serwin}
263253592Serwin
264253592Serwinstatic inline void
265253592Serwinfreestruct_uri(ARGS_FREESTRUCT) {
266253592Serwin	dns_rdata_uri_t *uri = (dns_rdata_uri_t *) source;
267253592Serwin
268253592Serwin	REQUIRE(source != NULL);
269253592Serwin	REQUIRE(uri->common.rdtype == 256);
270253592Serwin
271253592Serwin	if (uri->mctx == NULL)
272253592Serwin		return;
273253592Serwin
274253592Serwin	if (uri->target != NULL)
275253592Serwin		isc_mem_free(uri->mctx, uri->target);
276253592Serwin	uri->mctx = NULL;
277253592Serwin}
278253592Serwin
279253592Serwinstatic inline isc_result_t
280253592Serwinadditionaldata_uri(ARGS_ADDLDATA) {
281253592Serwin	REQUIRE(rdata->type == 256);
282253592Serwin
283253592Serwin	UNUSED(rdata);
284253592Serwin	UNUSED(add);
285253592Serwin	UNUSED(arg);
286253592Serwin
287253592Serwin	return (ISC_R_SUCCESS);
288253592Serwin}
289253592Serwin
290253592Serwinstatic inline isc_result_t
291253592Serwindigest_uri(ARGS_DIGEST) {
292253592Serwin	isc_region_t r;
293253592Serwin
294253592Serwin	REQUIRE(rdata->type == 256);
295253592Serwin
296253592Serwin	dns_rdata_toregion(rdata, &r);
297253592Serwin
298253592Serwin	return ((digest)(arg, &r));
299253592Serwin}
300253592Serwin
301253592Serwinstatic inline isc_boolean_t
302253592Serwincheckowner_uri(ARGS_CHECKOWNER) {
303253592Serwin
304253592Serwin	REQUIRE(type == 256);
305253592Serwin
306253592Serwin	UNUSED(name);
307253592Serwin	UNUSED(type);
308253592Serwin	UNUSED(rdclass);
309253592Serwin	UNUSED(wildcard);
310253592Serwin
311253592Serwin	return (ISC_TRUE);
312253592Serwin}
313253592Serwin
314253592Serwinstatic inline isc_boolean_t
315253592Serwinchecknames_uri(ARGS_CHECKNAMES) {
316253592Serwin
317253592Serwin	REQUIRE(rdata->type == 256);
318253592Serwin
319253592Serwin	UNUSED(rdata);
320253592Serwin	UNUSED(owner);
321253592Serwin	UNUSED(bad);
322253592Serwin
323253592Serwin	return (ISC_TRUE);
324253592Serwin}
325253592Serwin
326253592Serwinstatic inline int
327253592Serwincasecompare_uri(ARGS_COMPARE) {
328253592Serwin	return (compare_uri(rdata1, rdata2));
329253592Serwin}
330253592Serwin
331253592Serwin#endif /* GENERIC_URI_256_C */
332