lwres_grbn.c revision 170223
16448Sache/* 26448Sache * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") 36448Sache * Copyright (C) 2000, 2001 Internet Software Consortium. 46448Sache * 58857Srgrimes * Permission to use, copy, modify, and distribute this software for any 66448Sache * purpose with or without fee is hereby granted, provided that the above 76448Sache * copyright notice and this permission notice appear in all copies. 86448Sache * 96448Sache * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 1029612Sjmg * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1129612Sjmg * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 126448Sache * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 136448Sache * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14114601Sobrien * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15114601Sobrien * PERFORMANCE OF THIS SOFTWARE. 1629963Scharnier */ 1729963Scharnier 1829963Scharnier/* $Id: lwres_grbn.c,v 1.6.18.2 2005/04/29 00:17:20 marka Exp $ */ 19177195Sjkim 20177195Sjkim/*! \file lwres_grbn.c 216448Sache 226448Sache */ 2329612Sjmg 2429612Sjmg#include <config.h> 256448Sache 266448Sache#include <assert.h> 27227255Sed#include <stdlib.h> 286448Sache#include <string.h> 29177197Sjkim 30177197Sjkim#include <lwres/lwbuffer.h> 31177197Sjkim#include <lwres/lwpacket.h> 326448Sache#include <lwres/lwres.h> 33177197Sjkim#include <lwres/result.h> 3429612Sjmg 356448Sache#include "context_p.h" 36177197Sjkim#include "assert_p.h" 376448Sache 38144999Smdodd/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 39177197Sjkimlwres_result_t 40177197Sjkimlwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req, 41177195Sjkim lwres_lwpacket_t *pkt, lwres_buffer_t *b) 42177195Sjkim{ 43177195Sjkim unsigned char *buf; 44177195Sjkim size_t buflen; 45177195Sjkim int ret; 46177195Sjkim size_t payload_length; 47177195Sjkim lwres_uint16_t datalen; 48177197Sjkim 49177195Sjkim REQUIRE(ctx != NULL); 50177195Sjkim REQUIRE(req != NULL); 51177195Sjkim REQUIRE(req->name != NULL); 52177195Sjkim REQUIRE(pkt != NULL); 53177195Sjkim REQUIRE(b != NULL); 54177195Sjkim 55177195Sjkim datalen = strlen(req->name); 56177195Sjkim 57177195Sjkim payload_length = 4 + 2 + 2 + 2 + req->namelen + 1; 58177197Sjkim 59177195Sjkim buflen = LWRES_LWPACKET_LENGTH + payload_length; 60177195Sjkim buf = CTXMALLOC(buflen); 6129612Sjmg if (buf == NULL) 626448Sache return (LWRES_R_NOMEMORY); 636448Sache 646448Sache lwres_buffer_init(b, buf, buflen); 65177197Sjkim 6629612Sjmg pkt->length = buflen; 676448Sache pkt->version = LWRES_LWPACKETVERSION_0; 68177197Sjkim pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE; 6929612Sjmg pkt->opcode = LWRES_OPCODE_GETRDATABYNAME; 7029612Sjmg pkt->result = 0; 71177197Sjkim pkt->authtype = 0; 7229612Sjmg pkt->authlength = 0; 7329612Sjmg 74177197Sjkim ret = lwres_lwpacket_renderheader(b, pkt); 7529612Sjmg if (ret != LWRES_R_SUCCESS) { 7629612Sjmg lwres_buffer_invalidate(b); 77177197Sjkim CTXFREE(buf, buflen); 78177197Sjkim return (ret); 7929612Sjmg } 80177197Sjkim 816448Sache INSIST(SPACE_OK(b, payload_length)); 82177195Sjkim 83177195Sjkim /* 84177195Sjkim * Flags. 85177197Sjkim */ 86153953Sariff lwres_buffer_putuint32(b, req->flags); 87153953Sariff 88177197Sjkim /* 896448Sache * Class. 90177197Sjkim */ 91177197Sjkim lwres_buffer_putuint16(b, req->rdclass); 92177197Sjkim 93153953Sariff /* 94153953Sariff * Type. 95177197Sjkim */ 966448Sache lwres_buffer_putuint16(b, req->rdtype); 97177197Sjkim 98153953Sariff /* 996448Sache * Put the length and the data. We know this will fit because we 1006448Sache * just checked for it. 1018857Srgrimes */ 1026448Sache lwres_buffer_putuint16(b, datalen); 1036448Sache lwres_buffer_putmem(b, (unsigned char *)req->name, datalen); 104177197Sjkim lwres_buffer_putuint8(b, 0); /* trailing NUL */ 105177197Sjkim 106177197Sjkim INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); 107177197Sjkim 108177197Sjkim return (LWRES_R_SUCCESS); 109177197Sjkim} 110177197Sjkim 1116448Sache/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 112177195Sjkimlwres_result_t 113177195Sjkimlwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req, 114177195Sjkim lwres_lwpacket_t *pkt, lwres_buffer_t *b) 115177195Sjkim{ 116177195Sjkim unsigned char *buf; 117177195Sjkim size_t buflen; 118177195Sjkim int ret; 119177195Sjkim size_t payload_length; 120177195Sjkim lwres_uint16_t datalen; 1216448Sache int x; 122177195Sjkim 123177195Sjkim REQUIRE(ctx != NULL); 124177195Sjkim REQUIRE(req != NULL); 125177195Sjkim REQUIRE(pkt != NULL); 126177195Sjkim REQUIRE(b != NULL); 127177195Sjkim 12864657Ssobomax /* flags, class, type, ttl, nrdatas, nsigs */ 129177195Sjkim payload_length = 4 + 2 + 2 + 4 + 2 + 2; 13064657Ssobomax /* real name encoding */ 131177195Sjkim payload_length += 2 + req->realnamelen + 1; 132177195Sjkim /* each rr */ 133177195Sjkim for (x = 0; x < req->nrdatas; x++) 134177195Sjkim payload_length += 2 + req->rdatalen[x]; 135177195Sjkim for (x = 0; x < req->nsigs; x++) 136177197Sjkim payload_length += 2 + req->siglen[x]; 137177195Sjkim 138177195Sjkim buflen = LWRES_LWPACKET_LENGTH + payload_length; 139177197Sjkim buf = CTXMALLOC(buflen); 140177195Sjkim if (buf == NULL) 141177195Sjkim return (LWRES_R_NOMEMORY); 142177195Sjkim lwres_buffer_init(b, buf, buflen); 143177195Sjkim 144177195Sjkim pkt->length = buflen; 145177195Sjkim pkt->version = LWRES_LWPACKETVERSION_0; 146177197Sjkim pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE; 147177195Sjkim pkt->opcode = LWRES_OPCODE_GETRDATABYNAME; 14829612Sjmg pkt->authtype = 0; 149177195Sjkim pkt->authlength = 0; 150177195Sjkim 151177195Sjkim ret = lwres_lwpacket_renderheader(b, pkt); 15229963Scharnier if (ret != LWRES_R_SUCCESS) { 15329963Scharnier lwres_buffer_invalidate(b); 15429963Scharnier CTXFREE(buf, buflen); 15530028Scharnier return (ret); 15629963Scharnier } 15730028Scharnier 15829963Scharnier /* 15930028Scharnier * Check space needed here. 16029612Sjmg */ 1616448Sache INSIST(SPACE_OK(b, payload_length)); 162177197Sjkim 163177197Sjkim /* Flags. */ 164177197Sjkim lwres_buffer_putuint32(b, req->flags); 16513803Smpp 166177197Sjkim /* encode class, type, ttl, and nrdatas */ 16729963Scharnier lwres_buffer_putuint16(b, req->rdclass); 16813803Smpp lwres_buffer_putuint16(b, req->rdtype); 16913803Smpp lwres_buffer_putuint32(b, req->ttl); 170177197Sjkim lwres_buffer_putuint16(b, req->nrdatas); 171177197Sjkim lwres_buffer_putuint16(b, req->nsigs); 172177197Sjkim 173177197Sjkim /* encode the real name */ 174177197Sjkim datalen = req->realnamelen; 175177197Sjkim lwres_buffer_putuint16(b, datalen); 176177197Sjkim lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen); 177177197Sjkim lwres_buffer_putuint8(b, 0); 178177197Sjkim 17913803Smpp /* encode the rdatas */ 180177197Sjkim for (x = 0; x < req->nrdatas; x++) { 181177197Sjkim datalen = req->rdatalen[x]; 182177198Sjkim lwres_buffer_putuint16(b, datalen); 183177197Sjkim lwres_buffer_putmem(b, req->rdatas[x], datalen); 18413803Smpp } 18513803Smpp 186177197Sjkim /* encode the signatures */ 187177197Sjkim for (x = 0; x < req->nsigs; x++) { 1886448Sache datalen = req->siglen[x]; 189177197Sjkim lwres_buffer_putuint16(b, datalen); 190177197Sjkim lwres_buffer_putmem(b, req->sigs[x], datalen); 191177197Sjkim } 19229612Sjmg 193177197Sjkim INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); 194177197Sjkim INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length); 19529612Sjmg 196230611Smav return (LWRES_R_SUCCESS); 19729612Sjmg} 19829612Sjmg 19964657Ssobomax/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 20029612Sjmglwres_result_t 20164657Ssobomaxlwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, 20213435Smpp lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp) 203230611Smav{ 204230611Smav int ret; 205230611Smav char *name; 206230611Smav lwres_grbnrequest_t *grbn; 207230611Smav lwres_uint32_t flags; 20829612Sjmg lwres_uint16_t rdclass, rdtype; 20964657Ssobomax lwres_uint16_t namelen; 21029612Sjmg 21164657Ssobomax REQUIRE(ctx != NULL); 2126448Sache REQUIRE(pkt != NULL); 213177197Sjkim REQUIRE(b != NULL); 21429612Sjmg REQUIRE(structp != NULL && *structp == NULL); 2156448Sache 21629612Sjmg if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0) 21729612Sjmg return (LWRES_R_FAILURE); 2186448Sache 21929612Sjmg if (!SPACE_REMAINING(b, 4 + 2 + 2)) 22029612Sjmg return (LWRES_R_UNEXPECTEDEND); 22129612Sjmg 22229612Sjmg /* 22329612Sjmg * Pull off the flags, class, and type. 22429612Sjmg */ 22529612Sjmg flags = lwres_buffer_getuint32(b); 22629612Sjmg rdclass = lwres_buffer_getuint16(b); 22729612Sjmg rdtype = lwres_buffer_getuint16(b); 228177197Sjkim 229177197Sjkim /* 23029612Sjmg * Pull off the name itself 23129612Sjmg */ 2326448Sache ret = lwres_string_parse(b, &name, &namelen); 233177197Sjkim if (ret != LWRES_R_SUCCESS) 23475334Sgreid return (ret); 235177197Sjkim 23664657Ssobomax if (LWRES_BUFFER_REMAINING(b) != 0) 23729612Sjmg return (LWRES_R_TRAILINGDATA); 23864657Ssobomax 23929612Sjmg grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t)); 24029612Sjmg if (grbn == NULL) 241177197Sjkim return (LWRES_R_NOMEMORY); 242113299Smdodd 243177197Sjkim grbn->flags = flags; 244177197Sjkim grbn->rdclass = rdclass; 245177197Sjkim grbn->rdtype = rdtype; 246113299Smdodd grbn->name = name; 247177197Sjkim grbn->namelen = namelen; 248113299Smdodd 249177197Sjkim *structp = grbn; 250177197Sjkim return (LWRES_R_SUCCESS); 251113299Smdodd} 252177197Sjkim 253113299Smdodd/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 254113299Smdoddlwres_result_t 255113299Smdoddlwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, 256177197Sjkim lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp) 25729612Sjmg{ 258177197Sjkim lwres_result_t ret; 25929963Scharnier unsigned int x; 260177197Sjkim lwres_uint32_t flags; 261177197Sjkim lwres_uint16_t rdclass, rdtype; 26229612Sjmg lwres_uint32_t ttl; 2636448Sache lwres_uint16_t nrdatas, nsigs; 264177197Sjkim lwres_grbnresponse_t *grbn; 265177197Sjkim 266177197Sjkim REQUIRE(ctx != NULL); 267177197Sjkim REQUIRE(pkt != NULL); 268177197Sjkim REQUIRE(b != NULL); 269177197Sjkim REQUIRE(structp != NULL && *structp == NULL); 270177197Sjkim 271177197Sjkim grbn = NULL; 272177197Sjkim 2736448Sache if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) 274177197Sjkim return (LWRES_R_FAILURE); 275177197Sjkim 27629612Sjmg /* 27729612Sjmg * Pull off the flags, class, type, ttl, nrdatas, and nsigs 27829612Sjmg */ 279177197Sjkim if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2)) 28029612Sjmg return (LWRES_R_UNEXPECTEDEND); 281177197Sjkim flags = lwres_buffer_getuint32(b); 282113299Smdodd rdclass = lwres_buffer_getuint16(b); 283177197Sjkim rdtype = lwres_buffer_getuint16(b); 284177197Sjkim ttl = lwres_buffer_getuint32(b); 285113299Smdodd nrdatas = lwres_buffer_getuint16(b); 286113299Smdodd nsigs = lwres_buffer_getuint16(b); 287113299Smdodd 288113299Smdodd /* 289113299Smdodd * Pull off the name itself 290113299Smdodd */ 291113299Smdodd 292113299Smdodd grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t)); 29329612Sjmg if (grbn == NULL) 29429612Sjmg return (LWRES_R_NOMEMORY); 29529612Sjmg grbn->rdatas = NULL; 29629612Sjmg grbn->rdatalen = NULL; 29729612Sjmg grbn->sigs = NULL; 29829612Sjmg grbn->siglen = NULL; 29929612Sjmg grbn->base = NULL; 30029612Sjmg 3018857Srgrimes grbn->flags = flags; 302177197Sjkim grbn->rdclass = rdclass; 303177197Sjkim grbn->rdtype = rdtype; 304177197Sjkim grbn->ttl = ttl; 305177197Sjkim grbn->nrdatas = nrdatas; 306108421Sjmallett grbn->nsigs = nsigs; 30729612Sjmg 30829612Sjmg if (nrdatas > 0) { 30929963Scharnier grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas); 3106448Sache if (grbn->rdatas == NULL) { 311177197Sjkim ret = LWRES_R_NOMEMORY; 312177197Sjkim goto out; 31329612Sjmg } 3146448Sache 3156448Sache grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas); 3166448Sache if (grbn->rdatalen == NULL) { 31764657Ssobomax ret = LWRES_R_NOMEMORY; 31864657Ssobomax goto out; 31964657Ssobomax } 320177197Sjkim } 32164657Ssobomax 32264657Ssobomax if (nsigs > 0) { 323177195Sjkim grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs); 32429963Scharnier if (grbn->sigs == NULL) { 32530028Scharnier ret = LWRES_R_NOMEMORY; 32629963Scharnier goto out; 32730028Scharnier } 32829612Sjmg 329177197Sjkim grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs); 330177195Sjkim if (grbn->siglen == NULL) { 331177197Sjkim ret = LWRES_R_NOMEMORY; 33229612Sjmg goto out; 3336448Sache } 33429612Sjmg } 335177197Sjkim 3366448Sache /* 337 * Now, pull off the real name. 338 */ 339 ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen); 340 if (ret != LWRES_R_SUCCESS) 341 goto out; 342 343 /* 344 * Parse off the rdatas. 345 */ 346 for (x = 0; x < grbn->nrdatas; x++) { 347 ret = lwres_data_parse(b, &grbn->rdatas[x], 348 &grbn->rdatalen[x]); 349 if (ret != LWRES_R_SUCCESS) 350 goto out; 351 } 352 353 /* 354 * Parse off the signatures. 355 */ 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) 359 goto out; 360 } 361 362 if (LWRES_BUFFER_REMAINING(b) != 0) { 363 ret = LWRES_R_TRAILINGDATA; 364 goto out; 365 } 366 367 *structp = grbn; 368 return (LWRES_R_SUCCESS); 369 370 out: 371 if (grbn != NULL) { 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)); 382 } 383 384 return (ret); 385} 386 387/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 388void 389lwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp) 390{ 391 lwres_grbnrequest_t *grbn; 392 393 REQUIRE(ctx != NULL); 394 REQUIRE(structp != NULL && *structp != NULL); 395 396 grbn = *structp; 397 *structp = NULL; 398 399 CTXFREE(grbn, sizeof(lwres_grbnrequest_t)); 400} 401 402/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 403void 404lwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp) 405{ 406 lwres_grbnresponse_t *grbn; 407 408 REQUIRE(ctx != NULL); 409 REQUIRE(structp != NULL && *structp != NULL); 410 411 grbn = *structp; 412 *structp = NULL; 413 414 if (grbn->nrdatas > 0) { 415 CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas); 416 CTXFREE(grbn->rdatalen, 417 sizeof(lwres_uint16_t) * grbn->nrdatas); 418 } 419 if (grbn->nsigs > 0) { 420 CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs); 421 CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs); 422 } 423 if (grbn->base != NULL) 424 CTXFREE(grbn->base, grbn->baselen); 425 CTXFREE(grbn, sizeof(lwres_grbnresponse_t)); 426} 427