xref: /minix3/external/bsd/bind/dist/lib/lwres/lwres_grbn.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: lwres_grbn.c,v 1.5 2014/12/10 04:38:02 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2005, 2007, 2013  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 2000, 2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: lwres_grbn.c,v 1.10 2007/06/19 23:47:22 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*! \file lwres_grbn.c
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek  */
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <config.h>
27*00b67f09SDavid van Moolenbroek 
28*00b67f09SDavid van Moolenbroek #include <assert.h>
29*00b67f09SDavid van Moolenbroek #include <stdlib.h>
30*00b67f09SDavid van Moolenbroek #include <string.h>
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <lwres/lwbuffer.h>
33*00b67f09SDavid van Moolenbroek #include <lwres/lwpacket.h>
34*00b67f09SDavid van Moolenbroek #include <lwres/lwres.h>
35*00b67f09SDavid van Moolenbroek #include <lwres/result.h>
36*00b67f09SDavid van Moolenbroek 
37*00b67f09SDavid van Moolenbroek #include "context_p.h"
38*00b67f09SDavid van Moolenbroek #include "assert_p.h"
39*00b67f09SDavid van Moolenbroek 
40*00b67f09SDavid van Moolenbroek /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
41*00b67f09SDavid van Moolenbroek lwres_result_t
lwres_grbnrequest_render(lwres_context_t * ctx,lwres_grbnrequest_t * req,lwres_lwpacket_t * pkt,lwres_buffer_t * b)42*00b67f09SDavid van Moolenbroek lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
43*00b67f09SDavid van Moolenbroek 			 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
44*00b67f09SDavid van Moolenbroek {
45*00b67f09SDavid van Moolenbroek 	unsigned char *buf;
46*00b67f09SDavid van Moolenbroek 	size_t buflen;
47*00b67f09SDavid van Moolenbroek 	int ret;
48*00b67f09SDavid van Moolenbroek 	size_t payload_length;
49*00b67f09SDavid van Moolenbroek 	lwres_uint16_t datalen;
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek 	REQUIRE(ctx != NULL);
52*00b67f09SDavid van Moolenbroek 	REQUIRE(req != NULL);
53*00b67f09SDavid van Moolenbroek 	REQUIRE(req->name != NULL);
54*00b67f09SDavid van Moolenbroek 	REQUIRE(pkt != NULL);
55*00b67f09SDavid van Moolenbroek 	REQUIRE(b != NULL);
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek 	datalen = strlen(req->name);
58*00b67f09SDavid van Moolenbroek 
59*00b67f09SDavid van Moolenbroek 	payload_length = 4 + 2 + 2 + 2 + req->namelen + 1;
60*00b67f09SDavid van Moolenbroek 
61*00b67f09SDavid van Moolenbroek 	buflen = LWRES_LWPACKET_LENGTH + payload_length;
62*00b67f09SDavid van Moolenbroek 	buf = CTXMALLOC(buflen);
63*00b67f09SDavid van Moolenbroek 	if (buf == NULL)
64*00b67f09SDavid van Moolenbroek 		return (LWRES_R_NOMEMORY);
65*00b67f09SDavid van Moolenbroek 
66*00b67f09SDavid van Moolenbroek 	lwres_buffer_init(b, buf, (unsigned int)buflen);
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek 	pkt->length = (lwres_uint32_t)buflen;
69*00b67f09SDavid van Moolenbroek 	pkt->version = LWRES_LWPACKETVERSION_0;
70*00b67f09SDavid van Moolenbroek 	pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
71*00b67f09SDavid van Moolenbroek 	pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
72*00b67f09SDavid van Moolenbroek 	pkt->result = 0;
73*00b67f09SDavid van Moolenbroek 	pkt->authtype = 0;
74*00b67f09SDavid van Moolenbroek 	pkt->authlength = 0;
75*00b67f09SDavid van Moolenbroek 
76*00b67f09SDavid van Moolenbroek 	ret = lwres_lwpacket_renderheader(b, pkt);
77*00b67f09SDavid van Moolenbroek 	if (ret != LWRES_R_SUCCESS) {
78*00b67f09SDavid van Moolenbroek 		lwres_buffer_invalidate(b);
79*00b67f09SDavid van Moolenbroek 		CTXFREE(buf, buflen);
80*00b67f09SDavid van Moolenbroek 		return (ret);
81*00b67f09SDavid van Moolenbroek 	}
82*00b67f09SDavid van Moolenbroek 
83*00b67f09SDavid van Moolenbroek 	INSIST(SPACE_OK(b, payload_length));
84*00b67f09SDavid van Moolenbroek 
85*00b67f09SDavid van Moolenbroek 	/*
86*00b67f09SDavid van Moolenbroek 	 * Flags.
87*00b67f09SDavid van Moolenbroek 	 */
88*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint32(b, req->flags);
89*00b67f09SDavid van Moolenbroek 
90*00b67f09SDavid van Moolenbroek 	/*
91*00b67f09SDavid van Moolenbroek 	 * Class.
92*00b67f09SDavid van Moolenbroek 	 */
93*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, req->rdclass);
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	/*
96*00b67f09SDavid van Moolenbroek 	 * Type.
97*00b67f09SDavid van Moolenbroek 	 */
98*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, req->rdtype);
99*00b67f09SDavid van Moolenbroek 
100*00b67f09SDavid van Moolenbroek 	/*
101*00b67f09SDavid van Moolenbroek 	 * Put the length and the data.  We know this will fit because we
102*00b67f09SDavid van Moolenbroek 	 * just checked for it.
103*00b67f09SDavid van Moolenbroek 	 */
104*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, datalen);
105*00b67f09SDavid van Moolenbroek 	lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
106*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint8(b, 0); /* trailing NUL */
107*00b67f09SDavid van Moolenbroek 
108*00b67f09SDavid van Moolenbroek 	INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
109*00b67f09SDavid van Moolenbroek 
110*00b67f09SDavid van Moolenbroek 	return (LWRES_R_SUCCESS);
111*00b67f09SDavid van Moolenbroek }
112*00b67f09SDavid van Moolenbroek 
113*00b67f09SDavid van Moolenbroek /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
114*00b67f09SDavid van Moolenbroek lwres_result_t
lwres_grbnresponse_render(lwres_context_t * ctx,lwres_grbnresponse_t * req,lwres_lwpacket_t * pkt,lwres_buffer_t * b)115*00b67f09SDavid van Moolenbroek lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
116*00b67f09SDavid van Moolenbroek 			  lwres_lwpacket_t *pkt, lwres_buffer_t *b)
117*00b67f09SDavid van Moolenbroek {
118*00b67f09SDavid van Moolenbroek 	unsigned char *buf;
119*00b67f09SDavid van Moolenbroek 	size_t buflen;
120*00b67f09SDavid van Moolenbroek 	int ret;
121*00b67f09SDavid van Moolenbroek 	size_t payload_length;
122*00b67f09SDavid van Moolenbroek 	lwres_uint16_t datalen;
123*00b67f09SDavid van Moolenbroek 	int x;
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek 	REQUIRE(ctx != NULL);
126*00b67f09SDavid van Moolenbroek 	REQUIRE(req != NULL);
127*00b67f09SDavid van Moolenbroek 	REQUIRE(pkt != NULL);
128*00b67f09SDavid van Moolenbroek 	REQUIRE(b != NULL);
129*00b67f09SDavid van Moolenbroek 
130*00b67f09SDavid van Moolenbroek 	/* flags, class, type, ttl, nrdatas, nsigs */
131*00b67f09SDavid van Moolenbroek 	payload_length = 4 + 2 + 2 + 4 + 2 + 2;
132*00b67f09SDavid van Moolenbroek 	/* real name encoding */
133*00b67f09SDavid van Moolenbroek 	payload_length += 2 + req->realnamelen + 1;
134*00b67f09SDavid van Moolenbroek 	/* each rr */
135*00b67f09SDavid van Moolenbroek 	for (x = 0; x < req->nrdatas; x++)
136*00b67f09SDavid van Moolenbroek 		payload_length += 2 + req->rdatalen[x];
137*00b67f09SDavid van Moolenbroek 	for (x = 0; x < req->nsigs; x++)
138*00b67f09SDavid van Moolenbroek 		payload_length += 2 + req->siglen[x];
139*00b67f09SDavid van Moolenbroek 
140*00b67f09SDavid van Moolenbroek 	buflen = LWRES_LWPACKET_LENGTH + payload_length;
141*00b67f09SDavid van Moolenbroek 	buf = CTXMALLOC(buflen);
142*00b67f09SDavid van Moolenbroek 	if (buf == NULL)
143*00b67f09SDavid van Moolenbroek 		return (LWRES_R_NOMEMORY);
144*00b67f09SDavid van Moolenbroek 	lwres_buffer_init(b, buf, (unsigned int)buflen);
145*00b67f09SDavid van Moolenbroek 
146*00b67f09SDavid van Moolenbroek 	pkt->length = (lwres_uint32_t)buflen;
147*00b67f09SDavid van Moolenbroek 	pkt->version = LWRES_LWPACKETVERSION_0;
148*00b67f09SDavid van Moolenbroek 	pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
149*00b67f09SDavid van Moolenbroek 	pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
150*00b67f09SDavid van Moolenbroek 	pkt->authtype = 0;
151*00b67f09SDavid van Moolenbroek 	pkt->authlength = 0;
152*00b67f09SDavid van Moolenbroek 
153*00b67f09SDavid van Moolenbroek 	ret = lwres_lwpacket_renderheader(b, pkt);
154*00b67f09SDavid van Moolenbroek 	if (ret != LWRES_R_SUCCESS) {
155*00b67f09SDavid van Moolenbroek 		lwres_buffer_invalidate(b);
156*00b67f09SDavid van Moolenbroek 		CTXFREE(buf, buflen);
157*00b67f09SDavid van Moolenbroek 		return (ret);
158*00b67f09SDavid van Moolenbroek 	}
159*00b67f09SDavid van Moolenbroek 
160*00b67f09SDavid van Moolenbroek 	/*
161*00b67f09SDavid van Moolenbroek 	 * Check space needed here.
162*00b67f09SDavid van Moolenbroek 	 */
163*00b67f09SDavid van Moolenbroek 	INSIST(SPACE_OK(b, payload_length));
164*00b67f09SDavid van Moolenbroek 
165*00b67f09SDavid van Moolenbroek 	/* Flags. */
166*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint32(b, req->flags);
167*00b67f09SDavid van Moolenbroek 
168*00b67f09SDavid van Moolenbroek 	/* encode class, type, ttl, and nrdatas */
169*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, req->rdclass);
170*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, req->rdtype);
171*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint32(b, req->ttl);
172*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, req->nrdatas);
173*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, req->nsigs);
174*00b67f09SDavid van Moolenbroek 
175*00b67f09SDavid van Moolenbroek 	/* encode the real name */
176*00b67f09SDavid van Moolenbroek 	datalen = req->realnamelen;
177*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint16(b, datalen);
178*00b67f09SDavid van Moolenbroek 	lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
179*00b67f09SDavid van Moolenbroek 	lwres_buffer_putuint8(b, 0);
180*00b67f09SDavid van Moolenbroek 
181*00b67f09SDavid van Moolenbroek 	/* encode the rdatas */
182*00b67f09SDavid van Moolenbroek 	for (x = 0; x < req->nrdatas; x++) {
183*00b67f09SDavid van Moolenbroek 		datalen = req->rdatalen[x];
184*00b67f09SDavid van Moolenbroek 		lwres_buffer_putuint16(b, datalen);
185*00b67f09SDavid van Moolenbroek 		lwres_buffer_putmem(b, req->rdatas[x], datalen);
186*00b67f09SDavid van Moolenbroek 	}
187*00b67f09SDavid van Moolenbroek 
188*00b67f09SDavid van Moolenbroek 	/* encode the signatures */
189*00b67f09SDavid van Moolenbroek 	for (x = 0; x < req->nsigs; x++) {
190*00b67f09SDavid van Moolenbroek 		datalen = req->siglen[x];
191*00b67f09SDavid van Moolenbroek 		lwres_buffer_putuint16(b, datalen);
192*00b67f09SDavid van Moolenbroek 		lwres_buffer_putmem(b, req->sigs[x], datalen);
193*00b67f09SDavid van Moolenbroek 	}
194*00b67f09SDavid van Moolenbroek 
195*00b67f09SDavid van Moolenbroek 	INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
196*00b67f09SDavid van Moolenbroek 	INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
197*00b67f09SDavid van Moolenbroek 
198*00b67f09SDavid van Moolenbroek 	return (LWRES_R_SUCCESS);
199*00b67f09SDavid van Moolenbroek }
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
202*00b67f09SDavid van Moolenbroek lwres_result_t
lwres_grbnrequest_parse(lwres_context_t * ctx,lwres_buffer_t * b,lwres_lwpacket_t * pkt,lwres_grbnrequest_t ** structp)203*00b67f09SDavid van Moolenbroek lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
204*00b67f09SDavid van Moolenbroek 			lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp)
205*00b67f09SDavid van Moolenbroek {
206*00b67f09SDavid van Moolenbroek 	int ret;
207*00b67f09SDavid van Moolenbroek 	char *name;
208*00b67f09SDavid van Moolenbroek 	lwres_grbnrequest_t *grbn;
209*00b67f09SDavid van Moolenbroek 	lwres_uint32_t flags;
210*00b67f09SDavid van Moolenbroek 	lwres_uint16_t rdclass, rdtype;
211*00b67f09SDavid van Moolenbroek 	lwres_uint16_t namelen;
212*00b67f09SDavid van Moolenbroek 
213*00b67f09SDavid van Moolenbroek 	REQUIRE(ctx != NULL);
214*00b67f09SDavid van Moolenbroek 	REQUIRE(pkt != NULL);
215*00b67f09SDavid van Moolenbroek 	REQUIRE(b != NULL);
216*00b67f09SDavid van Moolenbroek 	REQUIRE(structp != NULL && *structp == NULL);
217*00b67f09SDavid van Moolenbroek 
218*00b67f09SDavid van Moolenbroek 	if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
219*00b67f09SDavid van Moolenbroek 		return (LWRES_R_FAILURE);
220*00b67f09SDavid van Moolenbroek 
221*00b67f09SDavid van Moolenbroek 	if (!SPACE_REMAINING(b, 4 + 2 + 2))
222*00b67f09SDavid van Moolenbroek 		return (LWRES_R_UNEXPECTEDEND);
223*00b67f09SDavid van Moolenbroek 
224*00b67f09SDavid van Moolenbroek 	/*
225*00b67f09SDavid van Moolenbroek 	 * Pull off the flags, class, and type.
226*00b67f09SDavid van Moolenbroek 	 */
227*00b67f09SDavid van Moolenbroek 	flags = lwres_buffer_getuint32(b);
228*00b67f09SDavid van Moolenbroek 	rdclass = lwres_buffer_getuint16(b);
229*00b67f09SDavid van Moolenbroek 	rdtype = lwres_buffer_getuint16(b);
230*00b67f09SDavid van Moolenbroek 
231*00b67f09SDavid van Moolenbroek 	/*
232*00b67f09SDavid van Moolenbroek 	 * Pull off the name itself
233*00b67f09SDavid van Moolenbroek 	 */
234*00b67f09SDavid van Moolenbroek 	ret = lwres_string_parse(b, &name, &namelen);
235*00b67f09SDavid van Moolenbroek 	if (ret != LWRES_R_SUCCESS)
236*00b67f09SDavid van Moolenbroek 		return (ret);
237*00b67f09SDavid van Moolenbroek 
238*00b67f09SDavid van Moolenbroek 	if (LWRES_BUFFER_REMAINING(b) != 0)
239*00b67f09SDavid van Moolenbroek 		return (LWRES_R_TRAILINGDATA);
240*00b67f09SDavid van Moolenbroek 
241*00b67f09SDavid van Moolenbroek 	grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t));
242*00b67f09SDavid van Moolenbroek 	if (grbn == NULL)
243*00b67f09SDavid van Moolenbroek 		return (LWRES_R_NOMEMORY);
244*00b67f09SDavid van Moolenbroek 
245*00b67f09SDavid van Moolenbroek 	grbn->flags = flags;
246*00b67f09SDavid van Moolenbroek 	grbn->rdclass = rdclass;
247*00b67f09SDavid van Moolenbroek 	grbn->rdtype = rdtype;
248*00b67f09SDavid van Moolenbroek 	grbn->name = name;
249*00b67f09SDavid van Moolenbroek 	grbn->namelen = namelen;
250*00b67f09SDavid van Moolenbroek 
251*00b67f09SDavid van Moolenbroek 	*structp = grbn;
252*00b67f09SDavid van Moolenbroek 	return (LWRES_R_SUCCESS);
253*00b67f09SDavid van Moolenbroek }
254*00b67f09SDavid van Moolenbroek 
255*00b67f09SDavid van Moolenbroek /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
256*00b67f09SDavid van Moolenbroek lwres_result_t
lwres_grbnresponse_parse(lwres_context_t * ctx,lwres_buffer_t * b,lwres_lwpacket_t * pkt,lwres_grbnresponse_t ** structp)257*00b67f09SDavid van Moolenbroek lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
258*00b67f09SDavid van Moolenbroek 			lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
259*00b67f09SDavid van Moolenbroek {
260*00b67f09SDavid van Moolenbroek 	lwres_result_t ret;
261*00b67f09SDavid van Moolenbroek 	unsigned int x;
262*00b67f09SDavid van Moolenbroek 	lwres_uint32_t flags;
263*00b67f09SDavid van Moolenbroek 	lwres_uint16_t rdclass, rdtype;
264*00b67f09SDavid van Moolenbroek 	lwres_uint32_t ttl;
265*00b67f09SDavid van Moolenbroek 	lwres_uint16_t nrdatas, nsigs;
266*00b67f09SDavid van Moolenbroek 	lwres_grbnresponse_t *grbn;
267*00b67f09SDavid van Moolenbroek 
268*00b67f09SDavid van Moolenbroek 	REQUIRE(ctx != NULL);
269*00b67f09SDavid van Moolenbroek 	REQUIRE(pkt != NULL);
270*00b67f09SDavid van Moolenbroek 	REQUIRE(b != NULL);
271*00b67f09SDavid van Moolenbroek 	REQUIRE(structp != NULL && *structp == NULL);
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	grbn = NULL;
274*00b67f09SDavid van Moolenbroek 
275*00b67f09SDavid van Moolenbroek 	if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
276*00b67f09SDavid van Moolenbroek 		return (LWRES_R_FAILURE);
277*00b67f09SDavid van Moolenbroek 
278*00b67f09SDavid van Moolenbroek 	/*
279*00b67f09SDavid van Moolenbroek 	 * Pull off the flags, class, type, ttl, nrdatas, and nsigs
280*00b67f09SDavid van Moolenbroek 	 */
281*00b67f09SDavid van Moolenbroek 	if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
282*00b67f09SDavid van Moolenbroek 		return (LWRES_R_UNEXPECTEDEND);
283*00b67f09SDavid van Moolenbroek 	flags = lwres_buffer_getuint32(b);
284*00b67f09SDavid van Moolenbroek 	rdclass = lwres_buffer_getuint16(b);
285*00b67f09SDavid van Moolenbroek 	rdtype = lwres_buffer_getuint16(b);
286*00b67f09SDavid van Moolenbroek 	ttl = lwres_buffer_getuint32(b);
287*00b67f09SDavid van Moolenbroek 	nrdatas = lwres_buffer_getuint16(b);
288*00b67f09SDavid van Moolenbroek 	nsigs = lwres_buffer_getuint16(b);
289*00b67f09SDavid van Moolenbroek 
290*00b67f09SDavid van Moolenbroek 	/*
291*00b67f09SDavid van Moolenbroek 	 * Pull off the name itself
292*00b67f09SDavid van Moolenbroek 	 */
293*00b67f09SDavid van Moolenbroek 
294*00b67f09SDavid van Moolenbroek 	grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
295*00b67f09SDavid van Moolenbroek 	if (grbn == NULL)
296*00b67f09SDavid van Moolenbroek 		return (LWRES_R_NOMEMORY);
297*00b67f09SDavid van Moolenbroek 	grbn->rdatas = NULL;
298*00b67f09SDavid van Moolenbroek 	grbn->rdatalen = NULL;
299*00b67f09SDavid van Moolenbroek 	grbn->sigs = NULL;
300*00b67f09SDavid van Moolenbroek 	grbn->siglen = NULL;
301*00b67f09SDavid van Moolenbroek 	grbn->base = NULL;
302*00b67f09SDavid van Moolenbroek 
303*00b67f09SDavid van Moolenbroek 	grbn->flags = flags;
304*00b67f09SDavid van Moolenbroek 	grbn->rdclass = rdclass;
305*00b67f09SDavid van Moolenbroek 	grbn->rdtype = rdtype;
306*00b67f09SDavid van Moolenbroek 	grbn->ttl = ttl;
307*00b67f09SDavid van Moolenbroek 	grbn->nrdatas = nrdatas;
308*00b67f09SDavid van Moolenbroek 	grbn->nsigs = nsigs;
309*00b67f09SDavid van Moolenbroek 
310*00b67f09SDavid van Moolenbroek 	if (nrdatas > 0) {
311*00b67f09SDavid van Moolenbroek 		grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
312*00b67f09SDavid van Moolenbroek 		if (grbn->rdatas == NULL) {
313*00b67f09SDavid van Moolenbroek 			ret = LWRES_R_NOMEMORY;
314*00b67f09SDavid van Moolenbroek 			goto out;
315*00b67f09SDavid van Moolenbroek 		}
316*00b67f09SDavid van Moolenbroek 
317*00b67f09SDavid van Moolenbroek 		grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
318*00b67f09SDavid van Moolenbroek 		if (grbn->rdatalen == NULL) {
319*00b67f09SDavid van Moolenbroek 			ret = LWRES_R_NOMEMORY;
320*00b67f09SDavid van Moolenbroek 			goto out;
321*00b67f09SDavid van Moolenbroek 		}
322*00b67f09SDavid van Moolenbroek 	}
323*00b67f09SDavid van Moolenbroek 
324*00b67f09SDavid van Moolenbroek 	if (nsigs > 0) {
325*00b67f09SDavid van Moolenbroek 		grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
326*00b67f09SDavid van Moolenbroek 		if (grbn->sigs == NULL) {
327*00b67f09SDavid van Moolenbroek 			ret = LWRES_R_NOMEMORY;
328*00b67f09SDavid van Moolenbroek 			goto out;
329*00b67f09SDavid van Moolenbroek 		}
330*00b67f09SDavid van Moolenbroek 
331*00b67f09SDavid van Moolenbroek 		grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
332*00b67f09SDavid van Moolenbroek 		if (grbn->siglen == NULL) {
333*00b67f09SDavid van Moolenbroek 			ret = LWRES_R_NOMEMORY;
334*00b67f09SDavid van Moolenbroek 			goto out;
335*00b67f09SDavid van Moolenbroek 		}
336*00b67f09SDavid van Moolenbroek 	}
337*00b67f09SDavid van Moolenbroek 
338*00b67f09SDavid van Moolenbroek 	/*
339*00b67f09SDavid van Moolenbroek 	 * Now, pull off the real name.
340*00b67f09SDavid van Moolenbroek 	 */
341*00b67f09SDavid van Moolenbroek 	ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
342*00b67f09SDavid van Moolenbroek 	if (ret != LWRES_R_SUCCESS)
343*00b67f09SDavid van Moolenbroek 		goto out;
344*00b67f09SDavid van Moolenbroek 
345*00b67f09SDavid van Moolenbroek 	/*
346*00b67f09SDavid van Moolenbroek 	 * Parse off the rdatas.
347*00b67f09SDavid van Moolenbroek 	 */
348*00b67f09SDavid van Moolenbroek 	for (x = 0; x < grbn->nrdatas; x++) {
349*00b67f09SDavid van Moolenbroek 		ret = lwres_data_parse(b, &grbn->rdatas[x],
350*00b67f09SDavid van Moolenbroek 					 &grbn->rdatalen[x]);
351*00b67f09SDavid van Moolenbroek 		if (ret != LWRES_R_SUCCESS)
352*00b67f09SDavid van Moolenbroek 			goto out;
353*00b67f09SDavid van Moolenbroek 	}
354*00b67f09SDavid van Moolenbroek 
355*00b67f09SDavid van Moolenbroek 	/*
356*00b67f09SDavid van Moolenbroek 	 * Parse off the signatures.
357*00b67f09SDavid van Moolenbroek 	 */
358*00b67f09SDavid van Moolenbroek 	for (x = 0; x < grbn->nsigs; x++) {
359*00b67f09SDavid van Moolenbroek 		ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
360*00b67f09SDavid van Moolenbroek 		if (ret != LWRES_R_SUCCESS)
361*00b67f09SDavid van Moolenbroek 			goto out;
362*00b67f09SDavid van Moolenbroek 	}
363*00b67f09SDavid van Moolenbroek 
364*00b67f09SDavid van Moolenbroek 	if (LWRES_BUFFER_REMAINING(b) != 0) {
365*00b67f09SDavid van Moolenbroek 		ret = LWRES_R_TRAILINGDATA;
366*00b67f09SDavid van Moolenbroek 		goto out;
367*00b67f09SDavid van Moolenbroek 	}
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek 	*structp = grbn;
370*00b67f09SDavid van Moolenbroek 	return (LWRES_R_SUCCESS);
371*00b67f09SDavid van Moolenbroek 
372*00b67f09SDavid van Moolenbroek  out:
373*00b67f09SDavid van Moolenbroek 	if (grbn != NULL) {
374*00b67f09SDavid van Moolenbroek 		if (grbn->rdatas != NULL)
375*00b67f09SDavid van Moolenbroek 			CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
376*00b67f09SDavid van Moolenbroek 		if (grbn->rdatalen != NULL)
377*00b67f09SDavid van Moolenbroek 			CTXFREE(grbn->rdatalen,
378*00b67f09SDavid van Moolenbroek 				sizeof(lwres_uint16_t) * nrdatas);
379*00b67f09SDavid van Moolenbroek 		if (grbn->sigs != NULL)
380*00b67f09SDavid van Moolenbroek 			CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
381*00b67f09SDavid van Moolenbroek 		if (grbn->siglen != NULL)
382*00b67f09SDavid van Moolenbroek 			CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
383*00b67f09SDavid van Moolenbroek 		CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
384*00b67f09SDavid van Moolenbroek 	}
385*00b67f09SDavid van Moolenbroek 
386*00b67f09SDavid van Moolenbroek 	return (ret);
387*00b67f09SDavid van Moolenbroek }
388*00b67f09SDavid van Moolenbroek 
389*00b67f09SDavid van Moolenbroek /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
390*00b67f09SDavid van Moolenbroek void
lwres_grbnrequest_free(lwres_context_t * ctx,lwres_grbnrequest_t ** structp)391*00b67f09SDavid van Moolenbroek lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp)
392*00b67f09SDavid van Moolenbroek {
393*00b67f09SDavid van Moolenbroek 	lwres_grbnrequest_t *grbn;
394*00b67f09SDavid van Moolenbroek 
395*00b67f09SDavid van Moolenbroek 	REQUIRE(ctx != NULL);
396*00b67f09SDavid van Moolenbroek 	REQUIRE(structp != NULL && *structp != NULL);
397*00b67f09SDavid van Moolenbroek 
398*00b67f09SDavid van Moolenbroek 	grbn = *structp;
399*00b67f09SDavid van Moolenbroek 	*structp = NULL;
400*00b67f09SDavid van Moolenbroek 
401*00b67f09SDavid van Moolenbroek 	CTXFREE(grbn, sizeof(lwres_grbnrequest_t));
402*00b67f09SDavid van Moolenbroek }
403*00b67f09SDavid van Moolenbroek 
404*00b67f09SDavid van Moolenbroek /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
405*00b67f09SDavid van Moolenbroek void
lwres_grbnresponse_free(lwres_context_t * ctx,lwres_grbnresponse_t ** structp)406*00b67f09SDavid van Moolenbroek lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp)
407*00b67f09SDavid van Moolenbroek {
408*00b67f09SDavid van Moolenbroek 	lwres_grbnresponse_t *grbn;
409*00b67f09SDavid van Moolenbroek 
410*00b67f09SDavid van Moolenbroek 	REQUIRE(ctx != NULL);
411*00b67f09SDavid van Moolenbroek 	REQUIRE(structp != NULL && *structp != NULL);
412*00b67f09SDavid van Moolenbroek 
413*00b67f09SDavid van Moolenbroek 	grbn = *structp;
414*00b67f09SDavid van Moolenbroek 	*structp = NULL;
415*00b67f09SDavid van Moolenbroek 
416*00b67f09SDavid van Moolenbroek 	if (grbn->nrdatas > 0) {
417*00b67f09SDavid van Moolenbroek 		CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas);
418*00b67f09SDavid van Moolenbroek 		CTXFREE(grbn->rdatalen,
419*00b67f09SDavid van Moolenbroek 			sizeof(lwres_uint16_t) * grbn->nrdatas);
420*00b67f09SDavid van Moolenbroek 	}
421*00b67f09SDavid van Moolenbroek 	if (grbn->nsigs > 0) {
422*00b67f09SDavid van Moolenbroek 		CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs);
423*00b67f09SDavid van Moolenbroek 		CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs);
424*00b67f09SDavid van Moolenbroek 	}
425*00b67f09SDavid van Moolenbroek 	if (grbn->base != NULL)
426*00b67f09SDavid van Moolenbroek 		CTXFREE(grbn->base, grbn->baselen);
427*00b67f09SDavid van Moolenbroek 	CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
428*00b67f09SDavid van Moolenbroek }
429