"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.11.23/lib/lwres/lwres_grbn.c" (7 Sep 2020, 9990 Bytes) of package /linux/misc/dns/bind9/9.11.23/bind-9.11.23.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "lwres_grbn.c" see the Fossies "Dox" file reference documentation.

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