message.c revision 0fd13c7aca8533fbc86e4c7aa326cc828844b9b5
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
7d32c065c7bb56f281651ae3dd2888f32ce4f1d9Bob Halley * Copyright (C) 1999, 2000 Internet Software Consortium.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * copyright notice and this permission notice appear in all copies.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/***
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *** Imports
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ***/
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <config.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/string.h> /* Required for HP/UX (and others?) */
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#include <isc/buffer.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/dnssec.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/keyvalues.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <dns/message.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/rdata.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/rdatalist.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/rdataset.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/result.h>
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington#include <dns/tsig.h>
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington#include <dns/view.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
75ec9bc9c7b4f2485647414330122e7b8e188097Andreas Gustafsson#define DNS_MESSAGE_OPCODE_MASK 0x7800U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_OPCODE_SHIFT 11
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#define DNS_MESSAGE_RCODE_MASK 0x000fU
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#define DNS_MESSAGE_FLAG_MASK 0x8ff0U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSRCODE_SHIFT 24
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSVERSION_SHIFT 16
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
f9df80f4348ef68043903efa08299480324f4823Michael Graff && ((s) < DNS_SECTION_MAX))
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
f9df80f4348ef68043903efa08299480324f4823Michael Graff && ((s) < DNS_SECTION_MAX))
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define ADD_STRING(b, s) {if (strlen(s) >= \
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_buffer_availablelength(b)) \
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return(ISC_R_NOSPACE); else \
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_buffer_putstr(b, s);}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * This is the size of each individual scratchpad buffer, and the numbers
f9df80f4348ef68043903efa08299480324f4823Michael Graff * of various block allocations used within the server.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * XXXMLG These should come from a config setting.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff#define SCRATCHPAD_SIZE 512
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define NAME_COUNT 8
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATA_COUNT 8
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATALIST_COUNT 8
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATASET_COUNT RDATALIST_COUNT
f9df80f4348ef68043903efa08299480324f4823Michael Graff
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer/*
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * Text representation of the different items, for message_totext
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * functions.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic char *sectiontext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "QUESTION",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ANSWER",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "AUTHORITY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ADDITIONAL"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic char *opcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "QUERY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "IQUERY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "STATUS",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED3",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTIFY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "UPDATE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED6",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED7",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED8",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED9",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED10",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED15"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic char *rcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOERROR",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "FORMERR",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "SERVFAIL",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NXDOMAIN",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTIMPL",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "REFUSED",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "YXDOMAIN",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "YXRRSET",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NXRRSET",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTAUTH",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTZONE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED15",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "BADVERS"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * "helper" type, which consists of a block of some type, and is linkable.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
f9df80f4348ef68043903efa08299480324f4823Michael Graff * size, or the allocated elements will not be alligned correctly.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graffstruct dns_msgblock {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int remaining;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LINK(dns_msgblock_t) link;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}; /* dynamically sized */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic inline dns_msgblock_t *
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define msgblock_get(block, type) \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ((type *)msgblock_internalget(block, sizeof(type)))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_internalget(dns_msgblock_t *, unsigned int);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_reset(dns_msgblock_t *);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * is free, return NULL.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline dns_msgblock_t *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int count)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff dns_msgblock_t *block;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int length;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * count);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block = isc_mem_get(mctx, length);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (block == NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff return (NULL);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff block->count = count;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block->remaining = count;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ISC_LINK_INIT(block, link);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (block);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Return an element from the msgblock. If no more are available, return
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * NULL.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff void *ptr;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
8c55a67a6d185de7036e39da30561a5c1637d22bAndreas Gustafsson if (block == NULL || block->remaining == 0)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (NULL);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block->remaining--;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ptr = (((unsigned char *)block)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff + sizeof(dns_msgblock_t)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff + (sizeof_type * block->remaining));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (ptr);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_reset(dns_msgblock_t *block) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff block->remaining = block->count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Release memory associated with a message block.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int length;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_mem_put(mctx, block, length);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff/*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new dynamic buffer, and attach it to this message as the
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * "current" buffer. (which is always the last on the list, for our
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * uses)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic inline isc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewbuffer(dns_message_t *msg, unsigned int size) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dynbuf = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline isc_buffer_t *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencecurrentbuffer(dns_message_t *msg) {
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dynbuf = ISC_LIST_TAIL(msg->scratchpad);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(dynbuf != NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff return (dynbuf);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencereleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_PREPEND(msg->freerdata, rdata, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdata_t *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewrdata(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_msgblock_t *msgblock;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdata_t *rdata;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (rdata != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdata, rdata, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock = ISC_LIST_TAIL(msg->rdatas);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = msgblock_get(msgblock, dns_rdata_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (rdata == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RDATA_COUNT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (msgblock == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->rdatas, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = msgblock_get(msgblock, dns_rdata_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencereleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdatalist_t *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewrdatalist(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_msgblock_t *msgblock;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdatalist_t *rdatalist;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (rdatalist != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdatalist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock = ISC_LIST_TAIL(msg->rdatalists);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (rdatalist == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sizeof(dns_rdatalist_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RDATALIST_COUNT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (msgblock == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdatalist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginitheader(dns_message_t *m) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->id = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->flags = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->rcode = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->opcode = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff m->rdclass = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginitprivate(dns_message_t *m) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley unsigned int i;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley for (i = 0; i < DNS_SECTION_MAX; i++) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff m->cursors[i] = NULL;
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff m->counts[i] = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff m->opt = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington m->sig0 = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington m->tsigset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington m->tsigname = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley m->opt_reserved = 0;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff m->reserved = 0;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff m->buffer = NULL;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff m->need_cctx_cleanup = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginittsig(dns_message_t *m) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->tsigstatus = m->querytsigstatus = dns_rcode_noerror;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->tsig = m->querytsig = NULL;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->tsigkey = NULL;
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellington m->tsigctx = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->sigstart = -1;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->sig0key = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->sig0status = dns_rcode_noerror;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->query = NULL;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington m->saved = NULL;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington}
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Init elements to default state. Used both when allocating a new element
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * and when resetting one.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginit(dns_message_t *m) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msginitheader(m);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msginitprivate(m);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msginittsig(m);
996028142c5f95492fcd42e69186b95641320c7bBob Halley m->header_ok = 0;
996028142c5f95492fcd42e69186b95641320c7bBob Halley m->question_ok = 0;
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellington m->tcp_continuation = 0;
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington m->verified_sig = 0;
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington m->verify_attempted = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleymsgresetnames(dns_message_t *msg, unsigned int first_section) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_name_t *name, *next_name;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_rdataset_t *rds, *next_rds;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up name lists by calling the rdataset disassociate function.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley for (i = first_section; i < DNS_SECTION_MAX; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff name = ISC_LIST_HEAD(msg->sections[i]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (name != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_name = ISC_LIST_NEXT(name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[i], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff rds = ISC_LIST_HEAD(name->list);
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (rds != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_rds = ISC_LIST_NEXT(rds, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(name->list, rds, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff INSIST(dns_rdataset_isassociated(rds));
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_rdataset_disassociate(rds);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdspool, rds);
f9df80f4348ef68043903efa08299480324f4823Michael Graff rds = next_rds;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff name = next_name;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleystatic void
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleymsgresetopt(dns_message_t *msg)
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley{
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley if (msg->opt != NULL) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley if (msg->opt_reserved > 0) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_message_renderrelease(msg, msg->opt_reserved);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 0;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley }
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley INSIST(dns_rdataset_isassociated(msg->opt));
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_rdataset_disassociate(msg->opt);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley isc_mempool_put(msg->rdspool, msg->opt);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt = NULL;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley }
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley}
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtonstatic void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgresetsigs(dns_message_t *msg) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->tsigset != NULL) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(dns_rdataset_isassociated(msg->tsigset));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(msg->namepool != NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_disassociate(msg->tsigset);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->rdspool, msg->tsigset);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->namepool, msg->tsigname);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->tsigset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->tsigname = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->sig0 != NULL) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(dns_rdataset_isassociated(msg->sig0));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_disassociate(msg->sig0);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->rdspool, msg->sig0);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->sig0 = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley/*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Free all but one (or everything) for this message. This is used by
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * both dns_message_reset() and dns_message_parse().
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgreset(dns_message_t *msg, isc_boolean_t everything) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_msgblock_t *msgblock, *next_msgblock;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf, *next_dynbuf;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_rdata_t *rdata;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_rdatalist_t *rdatalist;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msgresetnames(msg, 0);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msgresetopt(msg);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msgresetsigs(msg);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up linked lists.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff /*
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * Run through the free lists, and just unlink anything found there.
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * The memory isn't lost since these are part of message blocks we
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * have allocated.
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff */
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff while (rdata != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdata, rdata, link);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff while (rdatalist != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_HEAD(msg->scratchpad);
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(dynbuf != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything) {
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_clear(dynbuf);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_NEXT(dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (dynbuf != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_free(&dynbuf);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = next_dynbuf;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = ISC_LIST_HEAD(msg->rdatas);
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(msgblock != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_reset(msgblock);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = ISC_LIST_NEXT(msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (msgblock != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->rdatas, msgblock, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = next_msgblock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * rdatalists could be empty.
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff */
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msgblock = ISC_LIST_HEAD(msg->rdatalists);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything && msgblock != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_reset(msgblock);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msgblock = ISC_LIST_NEXT(msgblock, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff }
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff while (msgblock != NULL) {
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t));
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msgblock = next_msgblock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (msg->need_cctx_cleanup == 1)
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff dns_compress_invalidate(&msg->cctx);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if (msg->tsig != NULL) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington dns_rdata_freestruct(msg->tsig);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley isc_mem_put(msg->mctx, msg->tsig,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley sizeof(dns_rdata_any_tsig_t));
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->tsig = NULL;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if (msg->querytsig != NULL) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington dns_rdata_freestruct(msg->querytsig);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_mem_put(msg->mctx, msg->querytsig,
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington sizeof(dns_rdata_any_tsig_t));
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->querytsig = NULL;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (msg->tsigkey != NULL) {
b6666e61dc9b91f4ac6af3aa1172bfd8a5f2d6ffBrian Wellington dns_tsigkey_free(&msg->tsigkey);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->tsigkey = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (msg->query != NULL) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_mem_put(msg->mctx, msg->query->base, msg->query->length);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_mem_put(msg->mctx, msg->query, sizeof(isc_region_t));
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->query = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington if (msg->saved != NULL) {
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington isc_mem_put(msg->mctx, msg->saved->base, msg->saved->length);
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington isc_mem_put(msg->mctx, msg->saved, sizeof(isc_region_t));
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->saved = NULL;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington }
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * cleanup the buffer cleanup list
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dynbuf = ISC_LIST_HEAD(msg->cleanup);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff while (dynbuf != NULL) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
069104dd6a1bba610d0c3a413459accf73f3921bBrian Wellington ISC_LIST_UNLINK(msg->cleanup, dynbuf, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_buffer_free(&dynbuf);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dynbuf = next_dynbuf;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Set other bits to normal default values.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msginit(msg);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_message_t *m;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_result_t result;
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_msgblock_t *msgblock;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(mctx != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(msgp != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(*msgp == NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff || intent == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff m = isc_mem_get(mctx, sizeof(dns_message_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (m == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * No allocations until further notice. Just initialize all lists
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * and other members that are freed in the cleanup phase here.
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->magic = DNS_MESSAGE_MAGIC;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->from_to_wire = intent;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msginit(m);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (i = 0 ; i < DNS_SECTION_MAX ; i++)
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->sections[i]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->mctx = mctx;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->scratchpad);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_INIT(m->cleanup);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff m->namepool = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff m->rdspool = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->rdatas);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->rdatalists);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_INIT(m->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_INIT(m->freerdatalist);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * Ok, it is safe to allocate (and then "goto cleanup" if failure)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (result != ISC_R_SUCCESS)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_setfreemax(m->namepool, NAME_COUNT);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_setfillcount(m->namepool, NAME_COUNT);
0583bf2d0affe0a90ca2284cc27840b160029ff9Michael Graff isc_mempool_setname(m->namepool, "msg:names");
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t),
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff &m->rdspool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (result != ISC_R_SUCCESS)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_setfreemax(m->rdspool, NAME_COUNT);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_setfillcount(m->rdspool, NAME_COUNT);
0583bf2d0affe0a90ca2284cc27840b160029ff9Michael Graff isc_mempool_setname(m->rdspool, "msg:rdataset");
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (result != ISC_R_SUCCESS)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = msgblock_allocate(mctx, sizeof(dns_rdata_t),
f9df80f4348ef68043903efa08299480324f4823Michael Graff RDATA_COUNT);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msgblock == NULL)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(m->rdatas, msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (intent == DNS_MESSAGE_INTENTPARSE) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = msgblock_allocate(mctx, sizeof(dns_rdatalist_t),
f9df80f4348ef68043903efa08299480324f4823Michael Graff RDATALIST_COUNT);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msgblock == NULL)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(m->rdatalists, msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *msgp = m;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Cleanup for error returns.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff cleanup:
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = ISC_LIST_HEAD(m->rdatas);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (msgblock != NULL)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff msgblock_free(mctx, msgblock, sizeof(dns_rdata_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_HEAD(m->scratchpad);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (dynbuf != NULL)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_buffer_free(&dynbuf);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (m->namepool != NULL)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_destroy(&m->namepool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (m->rdspool != NULL)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_destroy(&m->rdspool);
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->magic = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(mctx, m, sizeof(dns_message_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_reset(dns_message_t *msg, unsigned int intent) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley || intent == DNS_MESSAGE_INTENTRENDER);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->from_to_wire = intent;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgreset(msg, ISC_FALSE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_destroy(dns_message_t **msgp) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_message_t *msg;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(msgp != NULL);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(*msgp));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg = *msgp;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *msgp = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgreset(msg, ISC_TRUE);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_destroy(&msg->namepool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_destroy(&msg->rdspool);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->magic = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(msg->mctx, msg, sizeof(dns_message_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halleyfindname(dns_name_t **foundname, dns_name_t *target, unsigned int attributes,
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley dns_namelist_t *section)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *curr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (curr = ISC_LIST_TAIL(*section) ;
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr != NULL ;
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr = ISC_LIST_PREV(curr, link)) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley if (dns_name_equal(curr, target) &&
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley (curr->attributes & attributes) == attributes) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (foundname != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff *foundname = curr;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOTFOUND);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graffdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff dns_rdatatype_t covers, dns_rdataset_t **rdataset)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataset_t *curr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff if (rdataset != NULL) {
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff REQUIRE(*rdataset == NULL);
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff }
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (curr = ISC_LIST_TAIL(name->list) ;
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr != NULL ;
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr = ISC_LIST_PREV(curr, link)) {
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley if (curr->type == type && curr->covers == covers) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdataset != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff *rdataset = curr;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOTFOUND);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff/*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Read a name from buffer "source".
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
e223094b2248afa2697c531f75e6f84855638becMichael Graffgetname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_decompress_t *dctx)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_buffer_t *scratch;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int tries;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff scratch = currentbuffer(msg);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * First try: use current buffer.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Second try: allocate a new buffer and use that.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff tries = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff while (tries < 2) {
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff dns_name_init(name, NULL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
e223094b2248afa2697c531f75e6f84855638becMichael Graff scratch);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOSPACE) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff tries++;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = newbuffer(msg, SCRATCHPAD_SIZE);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff scratch = currentbuffer(msg);
e223094b2248afa2697c531f75e6f84855638becMichael Graff } else {
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(0); /* Cannot get here... */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTED);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrencegetrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence unsigned int rdatalen, dns_rdata_t *rdata)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff{
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_t *scratch;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int tries;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson unsigned int trysize;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson /*
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson * In dynamic update messages, the rdata can be empty.
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson */
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson if (msg->opcode == dns_opcode_update && rdatalen == 0) {
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson /*
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson * When the rdata is empty, the data pointer is never
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson * dereferenced, but it must still be non-NULL.
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson */
42a5f9c8f535fb2a6d1cbfaa38533176e1f1667aBob Halley rdata->data = (unsigned char *)"";
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson rdata->length = 0;
0e919917cce54d09407393499ea5c019b93750e2Bob Halley rdata->rdclass = rdclass;
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson rdata->type = rdtype;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
3b40e78974c55304af90c7c9c63af7e933846543Andreas Gustafsson }
9dee95b41cfe1d33d542cc2ec0337d66b28b75abBrian Wellington
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch = currentbuffer(msg);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_setactive(source, rdatalen);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * First try: use current buffer.
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Second try: allocate a new buffer of size
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * (the data will fit if it was not more than 50% compressed)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Subsequent tries: double buffer size on each try.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tries = 0;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize = 0;
9dee95b41cfe1d33d542cc2ec0337d66b28b75abBrian Wellington /* XXX possibly change this to a while (tries < 2) loop */
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson for (;;) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = dns_rdata_fromwire(rdata, rdclass, rdtype,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff source, dctx, ISC_FALSE,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOSPACE) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (tries == 0) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize = 2 * rdatalen;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (trysize < SCRATCHPAD_SIZE)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize = SCRATCHPAD_SIZE;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson } else {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson INSIST(trysize != 0);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (trysize >= 65535)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson return (ISC_R_NOSPACE);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson /* XXX DNS_R_RRTOOLONG? */
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize *= 2;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tries++;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = newbuffer(msg, trysize);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch = currentbuffer(msg);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_region_t r;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int count;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_name_t *name;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_name_t *name2;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdataset_t *rdataset;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdatalist_t *rdatalist;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdatatype_t rdtype;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataclass_t rdclass;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_namelist_t *section;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_boolean_t free_name;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff section = &msg->sections[DNS_SECTION_QUESTION];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff name = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdataset = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdatalist = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (count = 0 ; count < msg->counts[DNS_SECTION_QUESTION] ; count++) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name = isc_mempool_get(msg->namepool);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (name == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff free_name = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Parse the name out of this packet.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_setactive(source, r.length);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = getname(name, source, msg, dctx);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Run through the section, looking to see if this name
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * is already there. If it is found, put back the allocated
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * name since we no longer need it, and set our name pointer
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * to point to the name we found.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley result = findname(&name2, name, 0, section);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is the first name in the section, accept it.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff *
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is not, but is not the same as the name already
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * in the question section, append to the section. Note that
e223094b2248afa2697c531f75e6f84855638becMichael Graff * here in the question section this is illegal, so return
e223094b2248afa2697c531f75e6f84855638becMichael Graff * FORMERR. In the future, check the opcode to see if
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this should be legal or not. In either case we no longer
e223094b2248afa2697c531f75e6f84855638becMichael Graff * need this name pointer.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (ISC_LIST_EMPTY(*section)) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(*section, name, link);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff free_name = ISC_FALSE;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = DNS_R_FORMERR;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff name = name2;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name2 = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff free_name = ISC_FALSE;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Get type and class.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (r.length < 4) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_UNEXPECTEDEND;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdclass = isc_buffer_getuint16(source);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If this class is different than the one we already read,
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this is an error.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (msg->state == DNS_SECTION_ANY) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->state = DNS_SECTION_QUESTION;
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->rdclass = rdclass;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff } else if (msg->rdclass != rdclass) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = DNS_R_FORMERR;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff /*
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * If this is a type that cannot occur in a question section,
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * return failure.
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff */
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff if (dns_rdatatype_notquestion(rdtype)) {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff result = DNS_R_FORMERR;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff goto cleanup;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff }
5d4660ccb5726e858bd74b6fabf635b3a7b51c10Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Can't ask the same question twice.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(name, rdtype, 0, NULL);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_SUCCESS) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = DNS_R_FORMERR;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new rdatalist.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist = newrdatalist(msg);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (rdatalist == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdataset = isc_mempool_get(msg->rdspool);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (rdataset == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Convert rdatalist to rdataset, and attach the latter to
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * the name.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->type = rdtype;
8b791b4ee85d7926170438752aae9c76f35a056fMark Andrews rdatalist->covers = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->rdclass = rdclass;
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->ttl = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_INIT(rdatalist->rdata);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdataset_init(rdataset);
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_rdatalist_tordataset(rdatalist, rdataset);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_APPEND(name->list, rdataset, link);
97f75286ada13a1b06a424607e638bde5ebfb3caAndreas Gustafsson rdataset = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff cleanup:
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff if (rdataset != NULL) {
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff INSIST(!dns_rdataset_isassociated(rdataset));
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdspool, rdataset);
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff }
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff#if 0
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (rdatalist != NULL)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdlpool, rdatalist);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff#endif
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (free_name)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->namepool, name);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson dns_section_t sectionid, isc_boolean_t preserve_order)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_region_t r;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley unsigned int count, rdatalen, attributes;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name2;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataset_t *rdataset;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdatalist_t *rdatalist;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t rdtype, covers;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataclass_t rdclass;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdata_t *rdata;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_ttl_t ttl;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_namelist_t *section;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_boolean_t free_name, free_rdataset;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (count = 0 ; count < msg->counts[sectionid] ; count++) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington int recstart = source->current;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley isc_boolean_t skip_name_search, skip_type_search;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff section = &msg->sections[sectionid];
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_FALSE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name = isc_mempool_get(msg->namepool);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (name == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_TRUE;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Parse the name out of this packet.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_setactive(source, r.length);
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = getname(name, source, msg, dctx);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Get type, class, ttl, and rdatalen. Verify that at least
e223094b2248afa2697c531f75e6f84855638becMichael Graff * rdatalen bytes remain. (Some of this is deferred to
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * later.)
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (r.length < 2 + 2 + 4 + 2) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_UNEXPECTEDEND;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdclass = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson /*
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson * If there was no question section, we may not yet have
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson * established a class. Do so now.
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson */
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson if (msg->state == DNS_SECTION_ANY) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdclass == 0 || rdclass == dns_rdataclass_any) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = DNS_R_FORMERR;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson msg->rdclass = rdclass;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson msg->state = DNS_SECTION_QUESTION;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson }
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If this class is different than the one in the question
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * section, bail.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (msg->opcode != dns_opcode_update
991322a2ab96f2e2379e3bf8b2220cf89f494ad9Brian Wellington && rdtype != dns_rdatatype_tsig
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley && rdtype != dns_rdatatype_opt
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington && rdtype != dns_rdatatype_key /* XXX in a TKEY query */
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington && rdtype != dns_rdatatype_sig /* XXX SIG(0) */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff && msg->rdclass != rdclass) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = DNS_R_FORMERR;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Special type handling for TSIG, OPT, and TKEY.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (rdtype == dns_rdatatype_tsig) {
bf555703f27295798de30fa8c04d727410788f66Bob Halley /*
bf555703f27295798de30fa8c04d727410788f66Bob Halley * If it is a tsig, verify that it is in the
bf555703f27295798de30fa8c04d727410788f66Bob Halley * additional data section, and switch sections for
bf555703f27295798de30fa8c04d727410788f66Bob Halley * the rest of this rdata.
bf555703f27295798de30fa8c04d727410788f66Bob Halley */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if ((sectionid != DNS_SECTION_ADDITIONAL)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff || (rdclass != dns_rdataclass_any)) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = DNS_R_FORMERR;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->tsigset != NULL) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = DNS_R_FORMERR;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington goto cleanup;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->sigstart = recstart;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_TRUE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = ISC_TRUE;
bf555703f27295798de30fa8c04d727410788f66Bob Halley } else if (rdtype == dns_rdatatype_opt) {
bf555703f27295798de30fa8c04d727410788f66Bob Halley /*
bf555703f27295798de30fa8c04d727410788f66Bob Halley * The name of an OPT record must be ".", it
bf555703f27295798de30fa8c04d727410788f66Bob Halley * must be in the additional data section, and
bf555703f27295798de30fa8c04d727410788f66Bob Halley * it must be the first OPT we've seen.
bf555703f27295798de30fa8c04d727410788f66Bob Halley */
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (!dns_name_equal(dns_rootname, name) ||
bf555703f27295798de30fa8c04d727410788f66Bob Halley sectionid != DNS_SECTION_ADDITIONAL ||
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff msg->opt != NULL) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = DNS_R_FORMERR;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_TRUE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = ISC_TRUE;
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington } else if (rdtype == dns_rdatatype_tkey) {
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * A TKEY must be in the additional section if this
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * is a query, and the answer section if this is a
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * response.
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Its class is ignored.
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington */
c0a868943801d6d5c764ee644a515b1a67d587edMichael Graff dns_section_t tkeysection;
c0a868943801d6d5c764ee644a515b1a67d587edMichael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington tkeysection = DNS_SECTION_ADDITIONAL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington else
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington tkeysection = DNS_SECTION_ANSWER;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (sectionid != tkeysection) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = DNS_R_FORMERR;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * ... now get ttl and rdatalen, and check buffer.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff ttl = isc_buffer_getuint32(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalen = isc_buffer_getuint16(source);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff r.length -= (2 + 2 + 4 + 2);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (r.length < rdatalen) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_UNEXPECTEDEND;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley /*
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * Read the rdata from the wire format. Interpret the
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * rdata according to its actual class, even if it had a
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * DynDNS meta-class in the packet (unless this is a TSIG).
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * Then put the meta-class back into the finished rdata.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley rdata = newrdata(msg);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdata == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley attributes = 0;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley if (rdtype != dns_rdatatype_tsig) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley if (rdtype == dns_rdatatype_cname) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley name->attributes |= DNS_NAMEATTR_CNAME;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley attributes = DNS_NAMEATTR_CNAME;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_TRUE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley } else if (rdtype == dns_rdatatype_dname) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley name->attributes |= DNS_NAMEATTR_DNAME;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley attributes = DNS_NAMEATTR_DNAME;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_TRUE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley }
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence result = getrdata(source, msg, dctx, msg->rdclass,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence rdtype, rdatalen, rdata);
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley } else
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence result = getrdata(source, msg, dctx, rdclass,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence rdtype, rdatalen, rdata);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley rdata->rdclass = rdclass;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley if (rdtype == dns_rdatatype_sig && rdata->length > 0) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley covers = dns_rdata_covers(rdata);
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley if (covers == dns_rdatatype_cname)
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley attributes = DNS_NAMEATTR_CNAME;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley else if (covers == dns_rdatatype_dname)
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley attributes = DNS_NAMEATTR_DNAME;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington else if (covers == 0) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->sig0 != NULL) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = DNS_R_FORMERR;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington goto cleanup;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->sigstart = recstart;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington skip_name_search = ISC_TRUE;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington skip_type_search = ISC_TRUE;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley } else
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley covers = 0;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If we are doing a dynamic update don't bother searching
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * for a name, just append this one to the end of the message.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (rdtype != dns_rdatatype_opt &&
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdtype != dns_rdatatype_tsig &&
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington !(rdtype == dns_rdatatype_sig && covers == 0))
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ISC_LIST_APPEND(*section, name, link);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff } else {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Run through the section, looking to see if this name
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * is already there. If it is found, put back the
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * allocated name since we no longer need it, and set
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * our name pointer to point to the name we found.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley result = findname(&name2, name, attributes, section);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If it is a new name, append to the section.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_SUCCESS) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, name);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff name = name2;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff } else {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff ISC_LIST_APPEND(*section, name, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Search name for the particular type and class.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Skip this stage if in update mode, or this is a TSIG.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOTFOUND;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff else {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff /*
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * If this is a type that can only occur in
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * the question section, fail.
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff */
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff if (dns_rdatatype_questiononly(rdtype)) {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff result = DNS_R_FORMERR;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff goto cleanup;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff }
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff rdataset = NULL;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(name, rdtype, covers,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff &rdataset);
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If we found an rdataset that matches, we need to
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * append this rdata to that set. If we did not, we need
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * to create a new rdatalist, store the important bits there,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * convert it to an rdataset, and link the latter to the name.
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * Yuck. When appending, make certain that the type isn't
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * a singleton type, such as SOA or CNAME.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley *
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * Note that this check will be bypassed when preserving order,
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * the opcode is an update, or the type search is skipped.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff if (result == ISC_R_SUCCESS) {
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff if (dns_rdatatype_issingleton(rdtype)) {
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff result = DNS_R_FORMERR;
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff goto cleanup;
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff }
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff }
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOTFOUND) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdataset = isc_mempool_get(msg->rdspool);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdataset == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_TRUE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist = newrdatalist(msg);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdatalist == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->type = rdtype;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdatalist->covers = covers;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->rdclass = rdclass;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->ttl = ttl;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_INIT(rdatalist->rdata);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdataset_init(rdataset);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdatalist_tordataset(rdatalist, rdataset);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdtype != dns_rdatatype_opt) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ISC_LIST_APPEND(name->list, rdataset, link);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * Minimize TTLs.
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley *
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * Section 5.2 of RFC 2181 says we should drop
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * nonauthoritative rrsets where the TTLs differ, but we
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * currently treat them the as if they were authoritative and
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * minimize them.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff if (ttl != rdataset->ttl) {
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff if (ttl < rdataset->ttl)
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff rdataset->ttl = ttl;
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff /*
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * XXXMLG Perform a totally ugly hack here to pull
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * the rdatalist out of the private field in the rdataset,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * and append this rdata to the rdatalist's linked list
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * of rdata.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist = (dns_rdatalist_t *)(rdataset->private1);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * If this is an OPT record, remember it. Also, set
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * the extended rcode.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (rdtype == dns_rdatatype_opt) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley unsigned int ercode;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
bf555703f27295798de30fa8c04d727410788f66Bob Halley msg->opt = rdataset;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff rdataset = NULL;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_FALSE;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ercode = (msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley >> 20;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->rcode |= ercode;
7153a32ae99388656620b200e6f4ba6e170a208cMichael Graff isc_mempool_put(msg->namepool, name);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * If this is an SIG(0) or TSIG record, remember it.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (rdtype == dns_rdatatype_sig && covers == 0) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->sig0 = rdataset;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdataset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_rdataset = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->namepool, name);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_name = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington else if (rdtype == dns_rdatatype_tsig) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->tsigset = rdataset;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->tsigname = name;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdataset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_rdataset = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_name = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff INSIST(free_name == ISC_FALSE);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff INSIST(free_rdataset == ISC_FALSE);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff cleanup:
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (free_name)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_mempool_put(msg->namepool, name);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (free_rdataset)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_mempool_put(msg->rdspool, rdataset);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafssondns_message_parse(dns_message_t *msg, isc_buffer_t *source,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson isc_boolean_t preserve_order)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_region_t r;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_decompress_t dctx;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t ret;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_uint16_t tmpflags;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_buffer_t origsource;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(source != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington origsource = *source;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->header_ok = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->question_ok = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (r.length < DNS_MESSAGE_HEADERLEN)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTEDEND);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msg->id = isc_buffer_getuint16(source);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tmpflags = isc_buffer_getuint16(source);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff >> DNS_MESSAGE_OPCODE_SHIFT);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->rcode = (tmpflags & DNS_MESSAGE_RCODE_MASK);
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->header_ok = 1;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff /*
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * -1 means no EDNS.
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_decompress_init(&dctx, -1, ISC_FALSE);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ret = getquestions(source, msg, &dctx);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->question_ok = 1;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson preserve_order);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson preserve_order);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson preserve_order);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (r.length != 0)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (DNS_R_FORMERR);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (msg->tsigset != NULL || msg->tsigkey != NULL ||
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence msg->sig0 != NULL) {
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->saved = isc_mem_get(msg->mctx, sizeof(isc_region_t));
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington if (msg->saved == NULL)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (ISC_R_NOMEMORY);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(&origsource, &r);
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->saved->length = r.length;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->saved->base = isc_mem_get(msg->mctx, msg->saved->length);
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington if (msg->saved->base == NULL) {
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington isc_mem_put(msg->mctx, msg->saved,
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington sizeof(isc_region_t));
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->saved = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (ISC_R_NOMEMORY);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington memcpy(msg->saved->base, r.base, msg->saved->length);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer) {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_region_t r;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(buffer != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer == NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Erase the contents of this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_clear(buffer);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Make certain there is enough for at least the header in this
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(buffer, &r);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff result = dns_compress_init(&msg->cctx, -1, msg->mctx);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff return (result);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff msg->need_cctx_cleanup = 1;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Reserve enough space for the header in this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->buffer = buffer;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff}
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_region_t r, rn;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(buffer != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Ensure that the new buffer is empty, and has enough space to
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * hold the current contents.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_clear(buffer);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(buffer, &rn);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(msg->buffer, &r);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(rn.length > r.length);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Copy the contents from the old to the new buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_add(buffer, r.length);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff memcpy(rn.base, r.base, r.length);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->buffer = buffer;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleyvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderrelease(dns_message_t *msg, unsigned int space) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer != NULL);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley REQUIRE(space <= msg->reserved);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->reserved -= space;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderreserve(dns_message_t *msg, unsigned int space) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_region_t r;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(msg->buffer, &r);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (r.length < (space + msg->reserved))
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOSPACE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->reserved += space;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffstatic inline isc_boolean_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencewrong_priority(dns_rdataset_t *rds, int pass) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff int pass_needed;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * If we are not rendering class IN, this ordering is bogus.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (rds->rdclass != dns_rdataclass_in)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_FALSE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff switch (rds->type) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_a:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_aaaa:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_a6:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 3;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff break;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_sig:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_key:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 2;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff break;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff default:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 1;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (pass_needed >= pass)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_FALSE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_TRUE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff}
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
a920f559c3689f52731519a9d5169ad5814866edMichael Graffdns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff unsigned int options)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
a920f559c3689f52731519a9d5169ad5814866edMichael Graff dns_namelist_t *section;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff dns_name_t *name, *next_name;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff dns_rdataset_t *rdataset, *next_rdataset;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff unsigned int count, total;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff isc_buffer_t st; /* for rollbacks */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff int pass;
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer != NULL);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff REQUIRE(VALID_NAMED_SECTION(sectionid));
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
a920f559c3689f52731519a9d5169ad5814866edMichael Graff section = &msg->sections[sectionid];
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if ((sectionid == DNS_SECTION_ADDITIONAL)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff && (options & DNS_MESSAGERENDER_ORDERED) == 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass = 3;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff else
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass = 1;
41cc03374dc7fd58d3b099d6c921f192a7bbb5f7Michael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff /*
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff * Shrink the space in the buffer by the reserved amount.
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff */
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff msg->buffer->length -= msg->reserved;
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff total = 0;
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff do {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff name = ISC_LIST_HEAD(*section);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (name == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff while (name != NULL) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next_name = ISC_LIST_NEXT(name, link);
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff rdataset = ISC_LIST_HEAD(name->list);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff while (rdataset != NULL) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next_rdataset = ISC_LIST_NEXT(rdataset, link);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if ((rdataset->attributes &
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence DNS_RDATASETATTR_RENDERED) != 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff goto next;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (((options & DNS_MESSAGERENDER_ORDERED)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence == 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff && (sectionid == DNS_SECTION_ADDITIONAL)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff && wrong_priority(rdataset, pass))
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff goto next;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff st = *(msg->buffer);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff count = 0;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff result = dns_rdataset_towire(rdataset, name,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff &msg->cctx,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence msg->buffer,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence &count);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff total += count;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * If out of space, record stats on what we
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rendered so far, and return that status.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff *
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * XXXMLG Need to change this when
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * dns_rdataset_towire() can render partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * sets starting at some arbitary point in the
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * set. This will include setting a bit in the
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rdataset to indicate that a partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rendering was done, and some state saved
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * somewhere (probably in the message struct)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * to indicate where to continue from.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff INSIST(st.used < 65536);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff dns_compress_rollback(&msg->cctx,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)st.used);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff *(msg->buffer) = st; /* rollback */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->buffer->length += msg->reserved;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->counts[sectionid] += total;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (result);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * If we have rendered pending data, ensure
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * that the AD bit is not set.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff */
0fd13c7aca8533fbc86e4c7aa326cc828844b9b5Andreas Gustafsson if (rdataset->trust == dns_trust_pending &&
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff (sectionid == DNS_SECTION_ANSWER ||
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff sectionid == DNS_SECTION_AUTHORITY))
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->flags &= ~DNS_MESSAGEFLAG_AD;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence rdataset->attributes |=
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence DNS_RDATASETATTR_RENDERED;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff rdataset = next_rdataset;
d070219e016b292a49f6f8ccd8975bcc18e46e40Michael Graff }
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff name = next_name;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff } while (--pass != 0);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff msg->buffer->length += msg->reserved;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->counts[sectionid] += total;
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_uint16_t tmp;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_region_t r;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(target != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(target, &r);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_buffer_putuint16(target, msg->id);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT)
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff & DNS_MESSAGE_OPCODE_MASK);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley tmp |= (msg->rcode & DNS_MESSAGE_RCODE_MASK);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff tmp |= (msg->flags & DNS_MESSAGE_FLAG_MASK);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence msg->counts[DNS_SECTION_ANSWER] < 65536 &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence msg->counts[DNS_SECTION_AUTHORITY] < 65536 &&
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] < 65536);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_buffer_putuint16(target, tmp);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington}
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderend(dns_message_t *msg) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_buffer_t tmpbuf;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_region_t r;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington int result;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley unsigned int count;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(msg->buffer != NULL);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * We have an extended rcode but are not using EDNS.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (DNS_R_FORMERR);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * If we've got an OPT record, render it.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (msg->opt != NULL) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_message_renderrelease(msg, msg->opt_reserved);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Set the extended rcode.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->opt->ttl |= ((msg->rcode << 20) &
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley DNS_MESSAGE_EDNSRCODE_MASK);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Render.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley count = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_rdataset_towire(msg->opt, dns_rootname,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley &msg->cctx, msg->buffer, &count);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->counts[DNS_SECTION_ADDITIONAL] += count;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (result != ISC_R_SUCCESS)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (result);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (msg->tsigkey != NULL) {
2871292a5674f7dcf300b3dc25969bb6e9656020Brian Wellington REQUIRE(msg->tsig == NULL);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington result = dns_tsig_sign(msg);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington return (result);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington count = 0;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_towire(msg->tsigset, msg->tsigname,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington &msg->cctx, msg->buffer, &count);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] += count;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington else if (msg->sig0key != NULL) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = dns_dnssec_signmessage(msg, msg->sig0key);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington count = 0;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_towire(msg->sig0, dns_rootname,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington &msg->cctx, msg->buffer, &count);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] += count;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result != ISC_R_SUCCESS)
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington return (result);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(msg->buffer, &r);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&tmpbuf, r.base, r.length);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington dns_message_renderheader(msg, &tmpbuf);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->buffer = NULL; /* forget about this buffer only on success XXX */
f9df80f4348ef68043903efa08299480324f4823Michael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff dns_compress_invalidate(&msg->cctx);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff msg->need_cctx_cleanup = 0;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halleyvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderreset(dns_message_t *msg) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley unsigned int i;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley dns_name_t *name;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley dns_rdataset_t *rds;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley /*
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Reset the message so that it may be rendered again.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley */
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
acb0311b113e3729dd1ac78dd14c51dc2c010393Mark Andrews msg->buffer = NULL;
acb0311b113e3729dd1ac78dd14c51dc2c010393Mark Andrews
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (i = 0; i < DNS_SECTION_MAX; i++) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley msg->cursors[i] = NULL;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley msg->counts[i] = 0;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (name = ISC_LIST_HEAD(msg->sections[i]);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley name != NULL;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley name = ISC_LIST_NEXT(name, link)) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (rds = ISC_LIST_HEAD(name->list);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rds != NULL;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rds = ISC_LIST_NEXT(rds, link)) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rds->attributes &= ~DNS_RDATASETATTR_RENDERED;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley}
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_firstname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msg->cursors[section] == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMORE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_nextname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->cursors[section] != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msg->cursors[section] == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMORE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_currentname(dns_message_t *msg, dns_section_t section,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_name_t **name)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff REQUIRE(name != NULL && *name == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->cursors[section] != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff *name = msg->cursors[section];
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_findname(dns_message_t *msg, dns_section_t section,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_name_t *target, dns_rdatatype_t type,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t covers, dns_name_t **name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdataset_t **rdataset)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff dns_name_t *foundname;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley unsigned int attributes;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley dns_rdatatype_t atype;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * XXX These requirements are probably too intensive, especially
f9df80f4348ef68043903efa08299480324f4823Michael Graff * where things can be NULL, but as they are they ensure that if
f9df80f4348ef68043903efa08299480324f4823Michael Graff * something is NON-NULL, indicating that the caller expects it
f9df80f4348ef68043903efa08299480324f4823Michael Graff * to be filled in, that we can in fact fill it in.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(target != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (name != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(*name == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (type == dns_rdatatype_any) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(rdataset == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff } else {
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (rdataset != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(*rdataset == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley /*
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley * Figure out what attributes we should look for.
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley */
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley if (type == dns_rdatatype_sig)
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley atype = covers;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley else
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley atype = type;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley attributes = 0;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley if (atype == dns_rdatatype_cname)
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley attributes = DNS_NAMEATTR_CNAME;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley else if (atype == dns_rdatatype_cname)
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley attributes = DNS_NAMEATTR_DNAME;
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff /*
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff * Search through, looking for the name.
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff */
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley result = findname(&foundname, target, attributes,
004da17157c0a0eab619cc7c16aba897b9506d4bBob Halley &msg->sections[section]);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOTFOUND)
a920f559c3689f52731519a9d5169ad5814866edMichael Graff return (DNS_R_NXDOMAIN);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff else if (result != ISC_R_SUCCESS)
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff return (result);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff if (name != NULL)
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff *name = foundname;
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff /*
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff * And now look for the type.
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff */
08d94b539a96857670540342df4d81ea55348d03Michael Graff if (type == dns_rdatatype_any)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(foundname, type, covers, rdataset);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOTFOUND)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (DNS_R_NXRRSET);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff return (result);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_movename(dns_message_t *msg, dns_name_t *name,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_section_t fromsection,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_section_t tosection)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(name != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(fromsection));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(tosection));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Unlink the name from the old section
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(msg->sections[tosection], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_addname(dns_message_t *msg, dns_name_t *name,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_section_t section)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(name != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(msg->sections[section], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff *item = isc_mempool_get(msg->namepool);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(item != NULL && *item != NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, *item);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff *item = NULL;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff}
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = newrdata(msg);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff *item = isc_mempool_get(msg->rdspool);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
499371d17c34a5770af022f4aa15e764e957a803Michael Graff dns_rdataset_init(*item);
499371d17c34a5770af022f4aa15e764e957a803Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = newrdatalist(msg);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff releaserdata(msg, *item);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = NULL;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff REQUIRE(!dns_rdataset_isassociated(*item));
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdspool, *item);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = NULL;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff releaserdatalist(msg, *item);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = NULL;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graffdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff unsigned int *flagsp)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff{
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff isc_region_t r;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff isc_buffer_t buffer;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff dns_messageid_t id;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff unsigned int flags;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff REQUIRE(source != NULL);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff buffer = *source;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(&buffer, &r);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (r.length < DNS_MESSAGE_HEADERLEN)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTEDEND);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
5039f2cad30410b47330c14c0d7ce4ca493a8712Michael Graff id = isc_buffer_getuint16(&buffer);
5039f2cad30410b47330c14c0d7ce4ca493a8712Michael Graff flags = isc_buffer_getuint16(&buffer);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff flags &= DNS_MESSAGE_FLAG_MASK;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (flagsp != NULL)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff *flagsp = flags;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (idp != NULL)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff *idp = id;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley unsigned int first_section;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (!msg->header_ok)
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley return (DNS_R_FORMERR);
271154eafd1111455030abc2997120228be55ef9Mark Andrews if (msg->opcode != dns_opcode_query &&
271154eafd1111455030abc2997120228be55ef9Mark Andrews msg->opcode != dns_opcode_notify)
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley want_question_section = ISC_FALSE;
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley if (want_question_section) {
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley if (!msg->question_ok)
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley return (DNS_R_FORMERR);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley first_section = DNS_SECTION_ANSWER;
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley } else
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley first_section = DNS_SECTION_QUESTION;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msgresetnames(msg, first_section);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msgresetopt(msg);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msgresetsigs(msg);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msginitprivate(msg);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley /*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * We now clear most flags and then set QR, ensuring that the
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * reply's flags will be in a reasonable state.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->flags &= DNS_MESSAGE_REPLYPRESERVE;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->flags |= DNS_MESSAGEFLAG_QR;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington /*
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington * This saves the query TSIG information for later use, if there is
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington * any. This only happens once - that is, if dns_message_reply
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington * has already moved the variables, this has no effect.
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington */
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if (msg->tsig != NULL) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msg->querytsig = msg->tsig;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msg->tsig = NULL;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msg->querytsigstatus = msg->tsigstatus;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msg->tsigstatus = dns_rcode_noerror;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington if (msg->saved != NULL) {
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->query = msg->saved;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msg->saved = NULL;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_rdataset_t *
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_getopt(dns_message_t *msg) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Get the OPT record for 'msg'.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (msg->opt);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley}
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley dns_rdata_t rdata;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Set the OPT record for 'msg'.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * The space required for an OPT record is:
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley *
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 1 byte for the name
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 2 bytes for the type
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 2 bytes for the class
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 4 bytes for the ttl
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 2 bytes for the rdata length
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * ---------------------------------
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 11 bytes
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley *
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * plus the length of the rdata.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(opt->type == dns_rdatatype_opt);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->buffer != NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->state == DNS_SECTION_ANY);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msgresetopt(msg);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msgresetsigs(msg);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_rdataset_first(opt);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (result != ISC_R_SUCCESS)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (result);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley dns_rdataset_current(opt, &rdata);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 11 + rdata.length;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley result = dns_message_renderreserve(msg, msg->opt_reserved);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley if (result != ISC_R_SUCCESS) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (result);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->opt = opt;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley}
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_rdataset_t *
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Get the TSIG record and owner for 'msg'.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(owner != NULL && *owner == NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington *owner = msg->tsigname;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (msg->tsigset);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_rdataset_t *
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_message_getsig0(dns_message_t *msg) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Get the SIG(0) record for 'msg'.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (msg->sig0);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(buffer != NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(ISC_BUFFER_VALID(*buffer));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_APPEND(msg->cleanup, *buffer, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff *buffer = NULL;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff}
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellingtonisc_result_t
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellingtondns_message_signer(dns_message_t *msg, dns_name_t *signer) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_region_t r;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_result_t result = ISC_R_SUCCESS;
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(signer != NULL);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if ((msg->tsig == NULL || msg->tsigkey == NULL) && msg->sig0 == NULL)
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington return (ISC_R_NOTFOUND);
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->verify_attempted == 0)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (DNS_R_NOTVERIFIEDYET);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (!dns_name_hasbuffer(signer)) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_buffer_t *dynbuf = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_setbuffer(signer, dynbuf);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_message_takebuffer(msg, &dynbuf);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->sig0 != NULL) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_rdata_t rdata;
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews dns_rdata_sig_t sig;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_first(msg->sig0);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(result == ISC_R_SUCCESS);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_current(msg->sig0, &rdata);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = ISC_R_SUCCESS;
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington else
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington result = DNS_R_SIGINVALID;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_toregion(&sig.signer, &r);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_fromregion(signer, &r);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_rdata_freestruct(&sig);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington else {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_t *identity;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->tsigstatus != dns_rcode_noerror)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_TSIGVERIFYFAILURE;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington else if (msg->tsig->error != dns_rcode_noerror)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_TSIGERRORSET;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington else
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = ISC_R_SUCCESS;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington identity = dns_tsigkey_identity(msg->tsigkey);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (identity == NULL) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (result == ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_NOIDENTITY;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington identity = &msg->tsigkey->name;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_toregion(identity, &r);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_fromregion(signer, &r);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington return (result);
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington}
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtonisc_result_t
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtondns_message_checksig(dns_message_t *msg, dns_view_t *view) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_t b, msgb;
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington REQUIRE(view != NULL);
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (msg->tsigkey == NULL && msg->tsigset == NULL && msg->sig0 == NULL)
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington return (ISC_R_SUCCESS);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(msg->saved != NULL);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&msgb, msg->saved->base, msg->saved->length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_add(&msgb, msg->saved->length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (msg->tsigkey != NULL || msg->tsigset != NULL)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (dns_view_checksig(view, &msgb, msg));
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington else {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_t rdata;
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews dns_rdata_sig_t sig;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_t keyset;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_result_t result;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_first(msg->sig0);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(result == ISC_R_SUCCESS);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_current(msg->sig0, &rdata);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_init(&keyset);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_view_simplefind(view, &sig.signer,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdatatype_key, 0, 0,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington ISC_FALSE, &keyset, NULL);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /* XXXBEW Should possibly create a fetch here */
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = DNS_R_KEYUNAUTHORIZED;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto freesig;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington } else if (keyset.trust < dns_trust_secure) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /* XXXBEW Should call a validator here */
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = DNS_R_KEYUNAUTHORIZED;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto freesig;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_first(&keyset);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(result == ISC_R_SUCCESS);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington for (;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result == ISC_R_SUCCESS;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_next(&keyset))
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_t *key = NULL;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_current(&keyset, &rdata);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&b, rdata.data, rdata.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_add(&b, rdata.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /*
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington * XXXBEW should actually pass in the key name,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington * but it's not used anyway.
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington */
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dst_key_fromdns("", &b, view->mctx, &key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington continue;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (dst_key_alg(key) != sig.algorithm ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_id(key) != sig.keyid ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_proto(key) == DNS_KEYPROTO_ANY))
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_free(key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington continue;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_dnssec_verifymessage(&msgb, msg, key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_free(key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result == ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington break;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result == ISC_R_NOMORE)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = DNS_R_KEYUNAUTHORIZED;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington freesig:
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_disassociate(&keyset);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_freestruct(&sig);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerisc_result_t
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_boolean_t comments,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_boolean_t omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_boolean_t no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_buffer_t *target) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_t *name, empty_name;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdataset_t *rdataset;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_result_t result;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(target != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(VALID_SECTION(section));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (comments) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, sectiontext[section]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, " SECTION:\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_init(&empty_name, NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_firstname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return(result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer do {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer name = NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_message_currentname(msg, section, &name);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer for (rdataset = ISC_LIST_HEAD(name->list);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer rdataset != NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer rdataset = ISC_LIST_NEXT(rdataset, link)) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdataset_first(rdataset);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_NOMORE) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return(result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdataset_totext(rdataset, name,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer target);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return(result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_nextname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer } while (result == ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result == ISC_R_NOMORE)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = ISC_R_SUCCESS;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return(result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerisc_result_t
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_totext(dns_message_t *msg, isc_boolean_t comments,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_boolean_t headers, isc_boolean_t omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_boolean_t no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_buffer_t *target) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer char buf[sizeof "1234567890"];
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdataset_t *opt;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_t *tsigname;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdataset_t *tsig;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_result_t result;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(target != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (headers) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, opcodetext[msg->opcode]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", status: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, rcodetext[msg->rcode]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", id: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%6u", msg->id);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n;; flags: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "qr ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "aa ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "tc ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "rd ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "ra ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "ad ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "cd ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n; QUESTION: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%3u", msg->counts[DNS_SECTION_QUESTION]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", ANSWER: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%3u", msg->counts[DNS_SECTION_ANSWER]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", AUTHORITY: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%3u", msg->counts[DNS_SECTION_AUTHORITY]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", ADDITIONAL: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%3u", msg->counts[DNS_SECTION_ADDITIONAL]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer opt = dns_message_getopt(msg);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (opt != NULL) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; EDNS: version: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%4u",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer (unsigned int)((opt->ttl &
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer 0x00ff0000 >> 16)));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", udp=");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer sprintf(buf, "%7u",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer (unsigned int)opt->rdclass);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer tsigname = NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer tsig = dns_message_gettsig(msg, &tsigname);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (tsig != NULL)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; PSEUDOSECTIONS: TSIG\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_QUESTION])) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer comments,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer target);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ANSWER])) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer comments,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer target);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_AUTHORITY])) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer comments,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer target);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (! ISC_LIST_EMPTY(msg->sections[DNS_SECTION_ADDITIONAL])) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer comments,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer omit_final_dot,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer no_rdata_or_ttl,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer target);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return(ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}