2 * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000, 2001 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
18 /* $Id: lwres_grbn.c,v 1.10 2007/06/19 23:47:22 tbox Exp $ */
20 /*! \file lwres_grbn.c
30 #include <lwres/lwbuffer.h>
31 #include <lwres/lwpacket.h>
32 #include <lwres/lwres.h>
33 #include <lwres/result.h>
35 #include "context_p.h"
38 /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
40 lwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req,
41 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
46 size_t payload_length;
47 lwres_uint16_t datalen;
51 REQUIRE(req->name != NULL);
55 datalen = strlen(req->name);
57 payload_length = 4 + 2 + 2 + 2 + req->namelen + 1;
59 buflen = LWRES_LWPACKET_LENGTH + payload_length;
60 buf = CTXMALLOC(buflen);
62 return (LWRES_R_NOMEMORY);
64 lwres_buffer_init(b, buf, buflen);
67 pkt->version = LWRES_LWPACKETVERSION_0;
68 pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE;
69 pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
74 ret = lwres_lwpacket_renderheader(b, pkt);
75 if (ret != LWRES_R_SUCCESS) {
76 lwres_buffer_invalidate(b);
81 INSIST(SPACE_OK(b, payload_length));
86 lwres_buffer_putuint32(b, req->flags);
91 lwres_buffer_putuint16(b, req->rdclass);
96 lwres_buffer_putuint16(b, req->rdtype);
99 * Put the length and the data. We know this will fit because we
100 * just checked for it.
102 lwres_buffer_putuint16(b, datalen);
103 lwres_buffer_putmem(b, (unsigned char *)req->name, datalen);
104 lwres_buffer_putuint8(b, 0); /* trailing NUL */
106 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
108 return (LWRES_R_SUCCESS);
111 /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
113 lwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req,
114 lwres_lwpacket_t *pkt, lwres_buffer_t *b)
119 size_t payload_length;
120 lwres_uint16_t datalen;
123 REQUIRE(ctx != NULL);
124 REQUIRE(req != NULL);
125 REQUIRE(pkt != NULL);
128 /* flags, class, type, ttl, nrdatas, nsigs */
129 payload_length = 4 + 2 + 2 + 4 + 2 + 2;
130 /* real name encoding */
131 payload_length += 2 + req->realnamelen + 1;
133 for (x = 0; x < req->nrdatas; x++)
134 payload_length += 2 + req->rdatalen[x];
135 for (x = 0; x < req->nsigs; x++)
136 payload_length += 2 + req->siglen[x];
138 buflen = LWRES_LWPACKET_LENGTH + payload_length;
139 buf = CTXMALLOC(buflen);
141 return (LWRES_R_NOMEMORY);
142 lwres_buffer_init(b, buf, buflen);
144 pkt->length = buflen;
145 pkt->version = LWRES_LWPACKETVERSION_0;
146 pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE;
147 pkt->opcode = LWRES_OPCODE_GETRDATABYNAME;
151 ret = lwres_lwpacket_renderheader(b, pkt);
152 if (ret != LWRES_R_SUCCESS) {
153 lwres_buffer_invalidate(b);
154 CTXFREE(buf, buflen);
159 * Check space needed here.
161 INSIST(SPACE_OK(b, payload_length));
164 lwres_buffer_putuint32(b, req->flags);
166 /* encode class, type, ttl, and nrdatas */
167 lwres_buffer_putuint16(b, req->rdclass);
168 lwres_buffer_putuint16(b, req->rdtype);
169 lwres_buffer_putuint32(b, req->ttl);
170 lwres_buffer_putuint16(b, req->nrdatas);
171 lwres_buffer_putuint16(b, req->nsigs);
173 /* encode the real name */
174 datalen = req->realnamelen;
175 lwres_buffer_putuint16(b, datalen);
176 lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen);
177 lwres_buffer_putuint8(b, 0);
179 /* encode the rdatas */
180 for (x = 0; x < req->nrdatas; x++) {
181 datalen = req->rdatalen[x];
182 lwres_buffer_putuint16(b, datalen);
183 lwres_buffer_putmem(b, req->rdatas[x], datalen);
186 /* encode the signatures */
187 for (x = 0; x < req->nsigs; x++) {
188 datalen = req->siglen[x];
189 lwres_buffer_putuint16(b, datalen);
190 lwres_buffer_putmem(b, req->sigs[x], datalen);
193 INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0);
194 INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length);
196 return (LWRES_R_SUCCESS);
199 /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
201 lwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b,
202 lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp)
206 lwres_grbnrequest_t *grbn;
207 lwres_uint32_t flags;
208 lwres_uint16_t rdclass, rdtype;
209 lwres_uint16_t namelen;
211 REQUIRE(ctx != NULL);
212 REQUIRE(pkt != NULL);
214 REQUIRE(structp != NULL && *structp == NULL);
216 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0)
217 return (LWRES_R_FAILURE);
219 if (!SPACE_REMAINING(b, 4 + 2 + 2))
220 return (LWRES_R_UNEXPECTEDEND);
223 * Pull off the flags, class, and type.
225 flags = lwres_buffer_getuint32(b);
226 rdclass = lwres_buffer_getuint16(b);
227 rdtype = lwres_buffer_getuint16(b);
230 * Pull off the name itself
232 ret = lwres_string_parse(b, &name, &namelen);
233 if (ret != LWRES_R_SUCCESS)
236 if (LWRES_BUFFER_REMAINING(b) != 0)
237 return (LWRES_R_TRAILINGDATA);
239 grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t));
241 return (LWRES_R_NOMEMORY);
244 grbn->rdclass = rdclass;
245 grbn->rdtype = rdtype;
247 grbn->namelen = namelen;
250 return (LWRES_R_SUCCESS);
253 /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
255 lwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b,
256 lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp)
260 lwres_uint32_t flags;
261 lwres_uint16_t rdclass, rdtype;
263 lwres_uint16_t nrdatas, nsigs;
264 lwres_grbnresponse_t *grbn;
266 REQUIRE(ctx != NULL);
267 REQUIRE(pkt != NULL);
269 REQUIRE(structp != NULL && *structp == NULL);
273 if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0)
274 return (LWRES_R_FAILURE);
277 * Pull off the flags, class, type, ttl, nrdatas, and nsigs
279 if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2))
280 return (LWRES_R_UNEXPECTEDEND);
281 flags = lwres_buffer_getuint32(b);
282 rdclass = lwres_buffer_getuint16(b);
283 rdtype = lwres_buffer_getuint16(b);
284 ttl = lwres_buffer_getuint32(b);
285 nrdatas = lwres_buffer_getuint16(b);
286 nsigs = lwres_buffer_getuint16(b);
289 * Pull off the name itself
292 grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t));
294 return (LWRES_R_NOMEMORY);
296 grbn->rdatalen = NULL;
302 grbn->rdclass = rdclass;
303 grbn->rdtype = rdtype;
305 grbn->nrdatas = nrdatas;
309 grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas);
310 if (grbn->rdatas == NULL) {
311 ret = LWRES_R_NOMEMORY;
315 grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas);
316 if (grbn->rdatalen == NULL) {
317 ret = LWRES_R_NOMEMORY;
323 grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs);
324 if (grbn->sigs == NULL) {
325 ret = LWRES_R_NOMEMORY;
329 grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs);
330 if (grbn->siglen == NULL) {
331 ret = LWRES_R_NOMEMORY;
337 * Now, pull off the real name.
339 ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen);
340 if (ret != LWRES_R_SUCCESS)
344 * Parse off the rdatas.
346 for (x = 0; x < grbn->nrdatas; x++) {
347 ret = lwres_data_parse(b, &grbn->rdatas[x],
349 if (ret != LWRES_R_SUCCESS)
354 * Parse off the signatures.
356 for (x = 0; x < grbn->nsigs; x++) {
357 ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]);
358 if (ret != LWRES_R_SUCCESS)
362 if (LWRES_BUFFER_REMAINING(b) != 0) {
363 ret = LWRES_R_TRAILINGDATA;
368 return (LWRES_R_SUCCESS);
372 if (grbn->rdatas != NULL)
373 CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas);
374 if (grbn->rdatalen != NULL)
375 CTXFREE(grbn->rdatalen,
376 sizeof(lwres_uint16_t) * nrdatas);
377 if (grbn->sigs != NULL)
378 CTXFREE(grbn->sigs, sizeof(char *) * nsigs);
379 if (grbn->siglen != NULL)
380 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs);
381 CTXFREE(grbn, sizeof(lwres_grbnresponse_t));
387 /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
389 lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp)
391 lwres_grbnrequest_t *grbn;
393 REQUIRE(ctx != NULL);
394 REQUIRE(structp != NULL && *structp != NULL);
399 CTXFREE(grbn, sizeof(lwres_grbnrequest_t));
402 /*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */
404 lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp)
406 lwres_grbnresponse_t *grbn;
408 REQUIRE(ctx != NULL);
409 REQUIRE(structp != NULL && *structp != NULL);
414 if (grbn->nrdatas > 0) {
415 CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas);
416 CTXFREE(grbn->rdatalen,
417 sizeof(lwres_uint16_t) * grbn->nrdatas);
419 if (grbn->nsigs > 0) {
420 CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs);
421 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs);
423 if (grbn->base != NULL)
424 CTXFREE(grbn->base, grbn->baselen);
425 CTXFREE(grbn, sizeof(lwres_grbnresponse_t));