lwres_grbn.c revision 170222
1207618Srdivacky/* 2207618Srdivacky * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") 3207618Srdivacky * Copyright (C) 2000, 2001 Internet Software Consortium. 4207618Srdivacky * 5207618Srdivacky * Permission to use, copy, modify, and distribute this software for any 6207618Srdivacky * purpose with or without fee is hereby granted, provided that the above 7207618Srdivacky * copyright notice and this permission notice appear in all copies. 8207618Srdivacky * 9207618Srdivacky * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 10207618Srdivacky * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 11207618Srdivacky * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 12207618Srdivacky * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 13207618Srdivacky * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 14207618Srdivacky * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 15207618Srdivacky * PERFORMANCE OF THIS SOFTWARE. 16207618Srdivacky */ 17207618Srdivacky 18207618Srdivacky/* $Id: lwres_grbn.c,v 1.6.18.2 2005/04/29 00:17:20 marka Exp $ */ 19207618Srdivacky 20207618Srdivacky/*! \file lwres_grbn.c 21207618Srdivacky 22210299Sed */ 23210299Sed 24207618Srdivacky#include <config.h> 25207618Srdivacky 26207618Srdivacky#include <assert.h> 27207618Srdivacky#include <stdlib.h> 28207618Srdivacky#include <string.h> 29207618Srdivacky 30207618Srdivacky#include <lwres/lwbuffer.h> 31207618Srdivacky#include <lwres/lwpacket.h> 32207618Srdivacky#include <lwres/lwres.h> 33207618Srdivacky#include <lwres/result.h> 34207618Srdivacky 35207618Srdivacky#include "context_p.h" 36207618Srdivacky#include "assert_p.h" 37252723Sdim 38252723Sdim/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 39207618Srdivackylwres_result_t 40210299Sedlwres_grbnrequest_render(lwres_context_t *ctx, lwres_grbnrequest_t *req, 41210299Sed lwres_lwpacket_t *pkt, lwres_buffer_t *b) 42252723Sdim{ 43210299Sed unsigned char *buf; 44252723Sdim size_t buflen; 45207618Srdivacky int ret; 46207618Srdivacky size_t payload_length; 47252723Sdim lwres_uint16_t datalen; 48252723Sdim 49252723Sdim REQUIRE(ctx != NULL); 50252723Sdim REQUIRE(req != NULL); 51207618Srdivacky REQUIRE(req->name != NULL); 52207618Srdivacky REQUIRE(pkt != NULL); 53207618Srdivacky REQUIRE(b != NULL); 54207618Srdivacky 55207618Srdivacky datalen = strlen(req->name); 56252723Sdim 57207618Srdivacky payload_length = 4 + 2 + 2 + 2 + req->namelen + 1; 58207618Srdivacky 59207618Srdivacky buflen = LWRES_LWPACKET_LENGTH + payload_length; 60207618Srdivacky buf = CTXMALLOC(buflen); 61207618Srdivacky if (buf == NULL) 62207618Srdivacky return (LWRES_R_NOMEMORY); 63207618Srdivacky 64207618Srdivacky lwres_buffer_init(b, buf, buflen); 65207618Srdivacky 66207618Srdivacky pkt->length = buflen; 67207618Srdivacky pkt->version = LWRES_LWPACKETVERSION_0; 68207618Srdivacky pkt->pktflags &= ~LWRES_LWPACKETFLAG_RESPONSE; 69207618Srdivacky pkt->opcode = LWRES_OPCODE_GETRDATABYNAME; 70207618Srdivacky pkt->result = 0; 71207618Srdivacky pkt->authtype = 0; 72207618Srdivacky pkt->authlength = 0; 73210299Sed 74218893Sdim ret = lwres_lwpacket_renderheader(b, pkt); 75226890Sdim if (ret != LWRES_R_SUCCESS) { 76207618Srdivacky lwres_buffer_invalidate(b); 77207618Srdivacky CTXFREE(buf, buflen); 78207618Srdivacky return (ret); 79207618Srdivacky } 80207618Srdivacky 81207618Srdivacky INSIST(SPACE_OK(b, payload_length)); 82207618Srdivacky 83207618Srdivacky /* 84207618Srdivacky * Flags. 85207618Srdivacky */ 86207618Srdivacky lwres_buffer_putuint32(b, req->flags); 87207618Srdivacky 88207618Srdivacky /* 89207618Srdivacky * Class. 90207618Srdivacky */ 91207618Srdivacky lwres_buffer_putuint16(b, req->rdclass); 92207618Srdivacky 93207618Srdivacky /* 94207618Srdivacky * Type. 95207618Srdivacky */ 96207618Srdivacky lwres_buffer_putuint16(b, req->rdtype); 97207618Srdivacky 98210299Sed /* 99210299Sed * Put the length and the data. We know this will fit because we 100210299Sed * just checked for it. 101210299Sed */ 102207618Srdivacky lwres_buffer_putuint16(b, datalen); 103207618Srdivacky lwres_buffer_putmem(b, (unsigned char *)req->name, datalen); 104207618Srdivacky lwres_buffer_putuint8(b, 0); /* trailing NUL */ 105210299Sed 106245431Sdim INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); 107235633Sdim 108207618Srdivacky return (LWRES_R_SUCCESS); 109207618Srdivacky} 110207618Srdivacky 111207618Srdivacky/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 112207618Srdivackylwres_result_t 113218893Sdimlwres_grbnresponse_render(lwres_context_t *ctx, lwres_grbnresponse_t *req, 114218893Sdim lwres_lwpacket_t *pkt, lwres_buffer_t *b) 115218893Sdim{ 116207618Srdivacky unsigned char *buf; 117207618Srdivacky size_t buflen; 118207618Srdivacky int ret; 119207618Srdivacky size_t payload_length; 120207618Srdivacky lwres_uint16_t datalen; 121207618Srdivacky int x; 122235633Sdim 123210299Sed REQUIRE(ctx != NULL); 124207618Srdivacky REQUIRE(req != NULL); 125207618Srdivacky REQUIRE(pkt != NULL); 126207618Srdivacky REQUIRE(b != NULL); 127207618Srdivacky 128207618Srdivacky /* flags, class, type, ttl, nrdatas, nsigs */ 129207618Srdivacky payload_length = 4 + 2 + 2 + 4 + 2 + 2; 130207618Srdivacky /* real name encoding */ 131207618Srdivacky payload_length += 2 + req->realnamelen + 1; 132207618Srdivacky /* each rr */ 133207618Srdivacky for (x = 0; x < req->nrdatas; x++) 134207618Srdivacky payload_length += 2 + req->rdatalen[x]; 135207618Srdivacky for (x = 0; x < req->nsigs; x++) 136207618Srdivacky payload_length += 2 + req->siglen[x]; 137207618Srdivacky 138207618Srdivacky buflen = LWRES_LWPACKET_LENGTH + payload_length; 139207618Srdivacky buf = CTXMALLOC(buflen); 140207618Srdivacky if (buf == NULL) 141207618Srdivacky return (LWRES_R_NOMEMORY); 142207618Srdivacky lwres_buffer_init(b, buf, buflen); 143207618Srdivacky 144207618Srdivacky pkt->length = buflen; 145207618Srdivacky pkt->version = LWRES_LWPACKETVERSION_0; 146207618Srdivacky pkt->pktflags |= LWRES_LWPACKETFLAG_RESPONSE; 147207618Srdivacky pkt->opcode = LWRES_OPCODE_GETRDATABYNAME; 148207618Srdivacky pkt->authtype = 0; 149207618Srdivacky pkt->authlength = 0; 150207618Srdivacky 151207618Srdivacky ret = lwres_lwpacket_renderheader(b, pkt); 152207618Srdivacky if (ret != LWRES_R_SUCCESS) { 153218893Sdim lwres_buffer_invalidate(b); 154218893Sdim CTXFREE(buf, buflen); 155235633Sdim return (ret); 156218893Sdim } 157218893Sdim 158218893Sdim /* 159218893Sdim * Check space needed here. 160207618Srdivacky */ 161207618Srdivacky INSIST(SPACE_OK(b, payload_length)); 162207618Srdivacky 163207618Srdivacky /* Flags. */ 164207618Srdivacky lwres_buffer_putuint32(b, req->flags); 165207618Srdivacky 166207618Srdivacky /* encode class, type, ttl, and nrdatas */ 167207618Srdivacky lwres_buffer_putuint16(b, req->rdclass); 168207618Srdivacky lwres_buffer_putuint16(b, req->rdtype); 169207618Srdivacky lwres_buffer_putuint32(b, req->ttl); 170207618Srdivacky lwres_buffer_putuint16(b, req->nrdatas); 171207618Srdivacky lwres_buffer_putuint16(b, req->nsigs); 172207618Srdivacky 173207618Srdivacky /* encode the real name */ 174207618Srdivacky datalen = req->realnamelen; 175207618Srdivacky lwres_buffer_putuint16(b, datalen); 176207618Srdivacky lwres_buffer_putmem(b, (unsigned char *)req->realname, datalen); 177207618Srdivacky lwres_buffer_putuint8(b, 0); 178207618Srdivacky 179210299Sed /* encode the rdatas */ 180245431Sdim for (x = 0; x < req->nrdatas; x++) { 181235633Sdim datalen = req->rdatalen[x]; 182207618Srdivacky lwres_buffer_putuint16(b, datalen); 183207618Srdivacky lwres_buffer_putmem(b, req->rdatas[x], datalen); 184208599Srdivacky } 185207618Srdivacky 186207618Srdivacky /* encode the signatures */ 187207618Srdivacky for (x = 0; x < req->nsigs; x++) { 188207618Srdivacky datalen = req->siglen[x]; 189207618Srdivacky lwres_buffer_putuint16(b, datalen); 190207618Srdivacky lwres_buffer_putmem(b, req->sigs[x], datalen); 191207618Srdivacky } 192207618Srdivacky 193210299Sed INSIST(LWRES_BUFFER_AVAILABLECOUNT(b) == 0); 194210299Sed INSIST(LWRES_BUFFER_USEDCOUNT(b) == pkt->length); 195207618Srdivacky 196207618Srdivacky return (LWRES_R_SUCCESS); 197207618Srdivacky} 198207618Srdivacky 199207618Srdivacky/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 200207618Srdivackylwres_result_t 201218893Sdimlwres_grbnrequest_parse(lwres_context_t *ctx, lwres_buffer_t *b, 202218893Sdim lwres_lwpacket_t *pkt, lwres_grbnrequest_t **structp) 203207618Srdivacky{ 204210299Sed int ret; 205207618Srdivacky char *name; 206207618Srdivacky lwres_grbnrequest_t *grbn; 207207618Srdivacky lwres_uint32_t flags; 208207618Srdivacky lwres_uint16_t rdclass, rdtype; 209226890Sdim lwres_uint16_t namelen; 210263509Sdim 211207618Srdivacky REQUIRE(ctx != NULL); 212207618Srdivacky REQUIRE(pkt != NULL); 213207618Srdivacky REQUIRE(b != NULL); 214207618Srdivacky REQUIRE(structp != NULL && *structp == NULL); 215207618Srdivacky 216207618Srdivacky if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) != 0) 217207618Srdivacky return (LWRES_R_FAILURE); 218210299Sed 219210299Sed if (!SPACE_REMAINING(b, 4 + 2 + 2)) 220210299Sed return (LWRES_R_UNEXPECTEDEND); 221207618Srdivacky 222210299Sed /* 223210299Sed * Pull off the flags, class, and type. 224210299Sed */ 225210299Sed flags = lwres_buffer_getuint32(b); 226210299Sed rdclass = lwres_buffer_getuint16(b); 227210299Sed rdtype = lwres_buffer_getuint16(b); 228210299Sed 229210299Sed /* 230210299Sed * Pull off the name itself 231210299Sed */ 232210299Sed ret = lwres_string_parse(b, &name, &namelen); 233207618Srdivacky if (ret != LWRES_R_SUCCESS) 234218893Sdim return (ret); 235218893Sdim 236218893Sdim if (LWRES_BUFFER_REMAINING(b) != 0) 237210299Sed return (LWRES_R_TRAILINGDATA); 238218893Sdim 239218893Sdim grbn = CTXMALLOC(sizeof(lwres_grbnrequest_t)); 240218893Sdim if (grbn == NULL) 241218893Sdim return (LWRES_R_NOMEMORY); 242218893Sdim 243218893Sdim grbn->flags = flags; 244218893Sdim grbn->rdclass = rdclass; 245210299Sed grbn->rdtype = rdtype; 246210299Sed grbn->name = name; 247210299Sed grbn->namelen = namelen; 248226890Sdim 249210299Sed *structp = grbn; 250210299Sed return (LWRES_R_SUCCESS); 251210299Sed} 252210299Sed 253210299Sed/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 254210299Sedlwres_result_t 255210299Sedlwres_grbnresponse_parse(lwres_context_t *ctx, lwres_buffer_t *b, 256207618Srdivacky lwres_lwpacket_t *pkt, lwres_grbnresponse_t **structp) 257207618Srdivacky{ 258208599Srdivacky lwres_result_t ret; 259208599Srdivacky unsigned int x; 260208599Srdivacky lwres_uint32_t flags; 261210299Sed lwres_uint16_t rdclass, rdtype; 262210299Sed lwres_uint32_t ttl; 263208599Srdivacky lwres_uint16_t nrdatas, nsigs; 264210299Sed lwres_grbnresponse_t *grbn; 265208599Srdivacky 266207618Srdivacky REQUIRE(ctx != NULL); 267208599Srdivacky REQUIRE(pkt != NULL); 268207618Srdivacky REQUIRE(b != NULL); 269207618Srdivacky REQUIRE(structp != NULL && *structp == NULL); 270207618Srdivacky 271207618Srdivacky grbn = NULL; 272207618Srdivacky 273207618Srdivacky if ((pkt->pktflags & LWRES_LWPACKETFLAG_RESPONSE) == 0) 274207618Srdivacky return (LWRES_R_FAILURE); 275207618Srdivacky 276210299Sed /* 277218893Sdim * Pull off the flags, class, type, ttl, nrdatas, and nsigs 278218893Sdim */ 279207618Srdivacky if (!SPACE_REMAINING(b, 4 + 2 + 2 + 4 + 2 + 2)) 280218893Sdim return (LWRES_R_UNEXPECTEDEND); 281218893Sdim flags = lwres_buffer_getuint32(b); 282207618Srdivacky rdclass = lwres_buffer_getuint16(b); 283207618Srdivacky rdtype = lwres_buffer_getuint16(b); 284207618Srdivacky ttl = lwres_buffer_getuint32(b); 285207618Srdivacky nrdatas = lwres_buffer_getuint16(b); 286207618Srdivacky nsigs = lwres_buffer_getuint16(b); 287218893Sdim 288207618Srdivacky /* 289210299Sed * Pull off the name itself 290210299Sed */ 291207618Srdivacky 292207618Srdivacky grbn = CTXMALLOC(sizeof(lwres_grbnresponse_t)); 293207618Srdivacky if (grbn == NULL) 294207618Srdivacky return (LWRES_R_NOMEMORY); 295207618Srdivacky grbn->rdatas = NULL; 296207618Srdivacky grbn->rdatalen = NULL; 297207618Srdivacky grbn->sigs = NULL; 298207618Srdivacky grbn->siglen = NULL; 299207618Srdivacky grbn->base = NULL; 300210299Sed 301218893Sdim grbn->flags = flags; 302218893Sdim grbn->rdclass = rdclass; 303207618Srdivacky grbn->rdtype = rdtype; 304218893Sdim grbn->ttl = ttl; 305218893Sdim grbn->nrdatas = nrdatas; 306207618Srdivacky grbn->nsigs = nsigs; 307207618Srdivacky 308207618Srdivacky if (nrdatas > 0) { 309207618Srdivacky grbn->rdatas = CTXMALLOC(sizeof(char *) * nrdatas); 310207618Srdivacky if (grbn->rdatas == NULL) { 311210299Sed ret = LWRES_R_NOMEMORY; 312218893Sdim goto out; 313218893Sdim } 314207618Srdivacky 315207618Srdivacky grbn->rdatalen = CTXMALLOC(sizeof(lwres_uint16_t) * nrdatas); 316207618Srdivacky if (grbn->rdatalen == NULL) { 317207618Srdivacky ret = LWRES_R_NOMEMORY; 318207618Srdivacky goto out; 319207618Srdivacky } 320207618Srdivacky } 321207618Srdivacky 322207618Srdivacky if (nsigs > 0) { 323218893Sdim grbn->sigs = CTXMALLOC(sizeof(char *) * nsigs); 324218893Sdim if (grbn->sigs == NULL) { 325207618Srdivacky ret = LWRES_R_NOMEMORY; 326207618Srdivacky goto out; 327218893Sdim } 328218893Sdim 329218893Sdim grbn->siglen = CTXMALLOC(sizeof(lwres_uint16_t) * nsigs); 330218893Sdim if (grbn->siglen == NULL) { 331207618Srdivacky ret = LWRES_R_NOMEMORY; 332207618Srdivacky goto out; 333218893Sdim } 334218893Sdim } 335207618Srdivacky 336207618Srdivacky /* 337207618Srdivacky * Now, pull off the real name. 338208599Srdivacky */ 339208599Srdivacky ret = lwres_string_parse(b, &grbn->realname, &grbn->realnamelen); 340208599Srdivacky if (ret != LWRES_R_SUCCESS) 341218893Sdim goto out; 342218893Sdim 343207618Srdivacky /* 344207618Srdivacky * Parse off the rdatas. 345207618Srdivacky */ 346207618Srdivacky for (x = 0; x < grbn->nrdatas; x++) { 347207618Srdivacky ret = lwres_data_parse(b, &grbn->rdatas[x], 348207618Srdivacky &grbn->rdatalen[x]); 349207618Srdivacky if (ret != LWRES_R_SUCCESS) 350207618Srdivacky goto out; 351207618Srdivacky } 352207618Srdivacky 353207618Srdivacky /* 354207618Srdivacky * Parse off the signatures. 355207618Srdivacky */ 356207618Srdivacky for (x = 0; x < grbn->nsigs; x++) { 357207618Srdivacky ret = lwres_data_parse(b, &grbn->sigs[x], &grbn->siglen[x]); 358207618Srdivacky if (ret != LWRES_R_SUCCESS) 359207618Srdivacky goto out; 360210299Sed } 361210299Sed 362210299Sed if (LWRES_BUFFER_REMAINING(b) != 0) { 363210299Sed ret = LWRES_R_TRAILINGDATA; 364210299Sed goto out; 365210299Sed } 366207618Srdivacky 367207618Srdivacky *structp = grbn; 368210299Sed return (LWRES_R_SUCCESS); 369210299Sed 370207618Srdivacky out: 371218893Sdim if (grbn != NULL) { 372226890Sdim if (grbn->rdatas != NULL) 373210299Sed CTXFREE(grbn->rdatas, sizeof(char *) * nrdatas); 374210299Sed if (grbn->rdatalen != NULL) 375210299Sed CTXFREE(grbn->rdatalen, 376210299Sed sizeof(lwres_uint16_t) * nrdatas); 377210299Sed if (grbn->sigs != NULL) 378210299Sed CTXFREE(grbn->sigs, sizeof(char *) * nsigs); 379207618Srdivacky if (grbn->siglen != NULL) 380207618Srdivacky CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * nsigs); 381207618Srdivacky CTXFREE(grbn, sizeof(lwres_grbnresponse_t)); 382207618Srdivacky } 383210299Sed 384210299Sed return (ret); 385210299Sed} 386210299Sed 387210299Sed/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 388210299Sedvoid 389207618Srdivackylwres_grbnrequest_free(lwres_context_t *ctx, lwres_grbnrequest_t **structp) 390207618Srdivacky{ 391207618Srdivacky lwres_grbnrequest_t *grbn; 392207618Srdivacky 393207618Srdivacky REQUIRE(ctx != NULL); 394207618Srdivacky REQUIRE(structp != NULL && *structp != NULL); 395207618Srdivacky 396207618Srdivacky grbn = *structp; 397207618Srdivacky *structp = NULL; 398207618Srdivacky 399207618Srdivacky CTXFREE(grbn, sizeof(lwres_grbnrequest_t)); 400207618Srdivacky} 401207618Srdivacky 402207618Srdivacky/*% Thread-save equivalent to \link lwres_gabn.c lwres_gabn* \endlink routines. */ 403207618Srdivackyvoid 404207618Srdivackylwres_grbnresponse_free(lwres_context_t *ctx, lwres_grbnresponse_t **structp) 405207618Srdivacky{ 406207618Srdivacky lwres_grbnresponse_t *grbn; 407207618Srdivacky 408207618Srdivacky REQUIRE(ctx != NULL); 409207618Srdivacky REQUIRE(structp != NULL && *structp != NULL); 410207618Srdivacky 411207618Srdivacky grbn = *structp; 412207618Srdivacky *structp = NULL; 413207618Srdivacky 414245431Sdim if (grbn->nrdatas > 0) { 415252723Sdim CTXFREE(grbn->rdatas, sizeof(char *) * grbn->nrdatas); 416252723Sdim CTXFREE(grbn->rdatalen, 417252723Sdim sizeof(lwres_uint16_t) * grbn->nrdatas); 418252723Sdim } 419252723Sdim if (grbn->nsigs > 0) { 420252723Sdim CTXFREE(grbn->sigs, sizeof(char *) * grbn->nsigs); 421252723Sdim CTXFREE(grbn->siglen, sizeof(lwres_uint16_t) * grbn->nsigs); 422252723Sdim } 423252723Sdim if (grbn->base != NULL) 424207618Srdivacky CTXFREE(grbn->base, grbn->baselen); 425252723Sdim CTXFREE(grbn, sizeof(lwres_grbnresponse_t)); 426252723Sdim} 427252723Sdim