message.c revision 33a4294f442f7505c8e2453beb422b5928ec697c
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 1999-2003 Internet Software Consortium.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and/or distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15a44745412679c30a6d022733925af70a38b715David Lawrence * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15a44745412679c30a6d022733925af70a38b715David Lawrence * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15a44745412679c30a6d022733925af70a38b715David Lawrence * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15a44745412679c30a6d022733925af70a38b715David Lawrence * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PERFORMANCE OF THIS SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
5d727330e46c8073703aea7cc0771a456db86829Andreas Gustafsson/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/***
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *** Imports
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ***/
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <config.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <ctype.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/buffer.h>
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/mem.h>
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#include <isc/print.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/string.h> /* Required for HP/UX (and others?) */
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <isc/util.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson#include <dns/dnssec.h>
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson#include <dns/keyvalues.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <dns/log.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/masterdump.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/message.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/opcode.h>
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington#include <dns/rcode.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/rdata.h>
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington#include <dns/rdatalist.h>
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington#include <dns/rdataset.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <dns/rdatastruct.h>
75ec9bc9c7b4f2485647414330122e7b8e188097Andreas Gustafsson#include <dns/result.h>
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#include <dns/tsig.h>
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#include <dns/ttl.h>
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#include <dns/view.h>
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#ifdef SKAN_MSG_DEBUG
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleystatic void
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleyhexdump(const char *msg, const char *msg2, void *base, size_t len) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned char *p;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int cnt;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff p = base;
f9df80f4348ef68043903efa08299480324f4823Michael Graff cnt = 0;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base);
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington while (cnt < len) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (cnt % 16 == 0)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer printf("%p: ", p);
f9df80f4348ef68043903efa08299480324f4823Michael Graff else if (cnt % 8 == 0)
f9df80f4348ef68043903efa08299480324f4823Michael Graff printf(" |");
f9df80f4348ef68043903efa08299480324f4823Michael Graff printf(" %02x %c", *p, (isprint(*p) ? *p : ' '));
f9df80f4348ef68043903efa08299480324f4823Michael Graff p++;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff cnt++;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (cnt % 16 == 0)
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff printf("\n");
be066f0629a12e11bc17f27671036b3f451bd5eaBrian Wellington }
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff if (cnt % 16 != 0)
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff printf("\n");
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#endif
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_OPCODE_MASK 0x7800U
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_OPCODE_SHIFT 11
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence#define DNS_MESSAGE_RCODE_MASK 0x000fU
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_FLAG_MASK 0x8ff0U
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_EDNSRCODE_SHIFT 24
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_EDNSVERSION_SHIFT 16
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer && ((s) < DNS_SECTION_MAX))
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer && ((s) < DNS_SECTION_MAX))
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer#define ADD_STRING(b, s) {if (strlen(s) >= \
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer isc_buffer_availablelength(b)) \
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer return(ISC_R_NOSPACE); else \
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence isc_buffer_putstr(b, s);}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer && ((s) < DNS_PSEUDOSECTION_MAX))
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer/*%
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * This is the size of each individual scratchpad buffer, and the numbers
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * of various block allocations used within the server.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * XXXMLG These should come from a config setting.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define SCRATCHPAD_SIZE 512
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define NAME_COUNT 8
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define OFFSET_COUNT 4
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define RDATA_COUNT 8
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define RDATALIST_COUNT 8
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define RDATASET_COUNT RDATALIST_COUNT
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer/*%
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence * Text representation of the different items, for message_totext
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * functions.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic const char *sectiontext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "QUESTION",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ANSWER",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "AUTHORITY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ADDITIONAL"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic const char *updsectiontext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ZONE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "PREREQUISITE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "UPDATE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ADDITIONAL"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic const char *opcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "QUERY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "IQUERY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "STATUS",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED3",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "NOTIFY",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "UPDATE",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED6",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED7",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED8",
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "RESERVED9",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED10",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED11",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED12",
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff "RESERVED13",
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "RESERVED14",
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "RESERVED15"
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff};
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff/*%
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * "helper" type, which consists of a block of some type, and is linkable.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael 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 aligned correctly.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graffstruct dns_msgblock {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int count;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int remaining;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LINK(dns_msgblock_t) link;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}; /* dynamically sized */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline dns_msgblock_t *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#define msgblock_get(block, type) \
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ((type *)msgblock_internalget(block, sizeof(type)))
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_internalget(dns_msgblock_t *, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_reset(dns_msgblock_t *);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Grafflogfmtpacket(dns_message_t *message, const char *description,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_sockaddr_t *address, isc_logcategory_t *category,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_logmodule_t *module, const dns_master_style_t *style,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff int level, isc_mem_t *mctx);
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 *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int count)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff dns_msgblock_t *block;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence unsigned int length;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * count);
8c55a67a6d185de7036e39da30561a5c1637d22bAndreas Gustafsson
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block = isc_mem_get(mctx, length);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (block == NULL)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (NULL);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael 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}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence/*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Return an element from the msgblock. If no more are available, return
f9df80f4348ef68043903efa08299480324f4823Michael Graff * NULL.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff void *ptr;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (block == NULL || block->remaining == 0)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff block->remaining--;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ptr = (((unsigned char *)block)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff + sizeof(dns_msgblock_t)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff + (sizeof_type * block->remaining));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ptr);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffmsgblock_reset(dns_msgblock_t *block) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff block->remaining = block->count;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff/*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Release memory associated with a message block.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencestatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffmsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int length;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_mem_put(mctx, block, length);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
4556681e191b7c1654639895ce719d98f2822ee2Michael 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
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * uses)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
4556681e191b7c1654639895ce719d98f2822ee2Michael Graffstatic inline isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffnewbuffer(dns_message_t *msg, unsigned int size) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_buffer_t *dynbuf;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff dynbuf = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ISC_R_NOMEMORY);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graffstatic inline isc_buffer_t *
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graffcurrentbuffer(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_buffer_t *dynbuf;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dynbuf = ISC_LIST_TAIL(msg->scratchpad);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(dynbuf != NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (dynbuf);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_PREPEND(msg->freerdata, rdata, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdata_t *
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffnewrdata(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_msgblock_t *msgblock;
5e589b5356a4125b5af32605dead82ab8b467c88Mark Andrews dns_rdata_t *rdata;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (rdata != NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_UNLINK(msg->freerdata, rdata, link);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (rdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = ISC_LIST_TAIL(msg->rdatas);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = msgblock_get(msgblock, dns_rdata_t);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (rdata == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RDATA_COUNT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (msgblock == NULL)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff return (NULL);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_APPEND(msg->rdatas, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = msgblock_get(msgblock, dns_rdata_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdata_init(rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdatalist_t *
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffnewrdatalist(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_msgblock_t *msgblock;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdatalist_t *rdatalist;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (rdatalist != NULL) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington goto out;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = ISC_LIST_TAIL(msg->rdatalists);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (rdatalist == NULL) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = msgblock_allocate(msg->mctx,
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington sizeof(dns_rdatalist_t),
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington RDATALIST_COUNT);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (msgblock == NULL)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (NULL);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington out:
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (rdatalist != NULL)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_rdatalist_init(rdatalist);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (rdatalist);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline dns_offsets_t *
f9df80f4348ef68043903efa08299480324f4823Michael Graffnewoffsets(dns_message_t *msg) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_msgblock_t *msgblock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_offsets_t *offsets;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msgblock = ISC_LIST_TAIL(msg->offsets);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff offsets = msgblock_get(msgblock, dns_offsets_t);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (offsets == NULL) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence msgblock = msgblock_allocate(msg->mctx,
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley sizeof(dns_offsets_t),
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley OFFSET_COUNT);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (msgblock == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (NULL);
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_APPEND(msg->offsets, msgblock, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington offsets = msgblock_get(msgblock, dns_offsets_t);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington }
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (offsets);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsginitheader(dns_message_t *m) {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff m->id = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->flags = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->rcode = 0;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->opcode = 0;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence m->rdclass = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonstatic inline void
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellingtonmsginitprivate(dns_message_t *m) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington unsigned int i;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington for (i = 0; i < DNS_SECTION_MAX; i++) {
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews m->cursors[i] = NULL;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->counts[i] = 0;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->opt = NULL;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->sig0 = NULL;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->sig0name = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->tsig = NULL;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->tsigname = NULL;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->opt_reserved = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->sig_reserved = 0;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->reserved = 0;
996028142c5f95492fcd42e69186b95641320c7bBob Halley m->buffer = NULL;
996028142c5f95492fcd42e69186b95641320c7bBob Halley}
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellington
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellingtonstatic inline void
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellingtonmsginittsig(dns_message_t *m) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson m->tsigstatus = dns_rcode_noerror;
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson m->querytsigstatus = dns_rcode_noerror;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->tsigkey = NULL;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->tsigctx = NULL;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->sigstart = -1;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->sig0key = NULL;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->sig0status = dns_rcode_noerror;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->timeadjust = 0;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley/*
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
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleymsginit(dns_message_t *m) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff msginitheader(m);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msginitprivate(m);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msginittsig(m);
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->header_ok = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->question_ok = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->tcp_continuation = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->verified_sig = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->verify_attempted = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->order = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->order_arg = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->query.base = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->query.length = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->free_query = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->saved.base = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->saved.length = 0;
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff m->free_saved = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->cc_ok = 0;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff m->cc_bad = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->tkey = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->rdclass_set = 0;
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff m->querytsig = NULL;
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff}
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffstatic inline void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgresetnames(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;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley /*
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley * Clean up name lists by calling the rdataset disassociate function.
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley */
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley for (i = first_section; i < DNS_SECTION_MAX; i++) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley name = ISC_LIST_HEAD(msg->sections[i]);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley while (name != NULL) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley next_name = ISC_LIST_NEXT(name, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley ISC_LIST_UNLINK(msg->sections[i], name, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley rds = ISC_LIST_HEAD(name->list);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley while (rds != NULL) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley next_rds = ISC_LIST_NEXT(rds, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley ISC_LIST_UNLINK(name->list, rds, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(dns_rdataset_isassociated(rds));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdataset_disassociate(rds);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_mempool_put(msg->rdspool, rds);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington rds = next_rds;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (dns_name_dynamic(name))
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_name_free(name, msg->mctx);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_mempool_put(msg->namepool, name);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington name = next_name;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington }
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellingtonstatic void
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellingtonmsgresetopt(dns_message_t *msg)
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington{
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->opt != NULL) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->opt_reserved > 0) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->opt_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->opt_reserved = 0;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington }
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington INSIST(dns_rdataset_isassociated(msg->opt));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_disassociate(msg->opt);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_mempool_put(msg->rdspool, msg->opt);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->opt = NULL;
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington msg->cc_ok = 0;
22057930cd2a71e1073781b650c7296739c869a6Brian Wellington msg->cc_bad = 0;
22057930cd2a71e1073781b650c7296739c869a6Brian Wellington }
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtonstatic void
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtonmsgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->sig_reserved > 0) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington msg->sig_reserved = 0;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington }
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington if (msg->tsig != NULL) {
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington INSIST(dns_rdataset_isassociated(msg->tsig));
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington INSIST(msg->namepool != NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (replying) {
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington INSIST(msg->querytsig == NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->querytsig = msg->tsig;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington } else {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_disassociate(msg->tsig);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_mempool_put(msg->rdspool, msg->tsig);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (msg->querytsig != NULL) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson dns_rdataset_disassociate(msg->querytsig);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_mempool_put(msg->rdspool, msg->querytsig);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley }
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence }
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (dns_name_dynamic(msg->tsigname))
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff dns_name_free(msg->tsigname, msg->mctx);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_mempool_put(msg->namepool, msg->tsigname);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->tsig = NULL;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->tsigname = NULL;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley } else if (msg->querytsig != NULL && !replying) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_rdataset_disassociate(msg->querytsig);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_mempool_put(msg->rdspool, msg->querytsig);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->querytsig = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msg->sig0 != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(dns_rdataset_isassociated(msg->sig0));
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_rdataset_disassociate(msg->sig0);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_mempool_put(msg->rdspool, msg->sig0);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (msg->sig0name != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (dns_name_dynamic(msg->sig0name))
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff dns_name_free(msg->sig0name, msg->mctx);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_mempool_put(msg->namepool, msg->sig0name);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff msg->sig0 = NULL;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff msg->sig0name = NULL;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff}
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff/*
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * Free all but one (or everything) for this message. This is used by
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * both dns_message_reset() and dns_message_destroy().
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff */
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graffstatic void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgreset(dns_message_t *msg, isc_boolean_t everything) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_msgblock_t *msgblock, *next_msgblock;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_buffer_t *dynbuf, *next_dynbuf;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff dns_rdata_t *rdata;
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_rdatalist_t *rdatalist;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgresetnames(msg, 0);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgresetopt(msg);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgresetsigs(msg, ISC_FALSE);
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up linked lists.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff
5f8b996a813e3e0adfbba2abf7671f631e21e056Brian Wellington /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Run through the free lists, and just unlink anything found there.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * The memory isn't lost since these are part of message blocks we
f9df80f4348ef68043903efa08299480324f4823Michael Graff * have allocated.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (rdata != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LIST_UNLINK(msg->freerdata, rdata, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff while (rdatalist != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff }
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dynbuf = ISC_LIST_HEAD(msg->scratchpad);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(dynbuf != NULL);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff if (!everything) {
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff isc_buffer_clear(dynbuf);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff dynbuf = ISC_LIST_NEXT(dynbuf, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff }
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff while (dynbuf != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_free(&dynbuf);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = next_dynbuf;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
5f8b996a813e3e0adfbba2abf7671f631e21e056Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = ISC_LIST_HEAD(msg->rdatas);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (!everything && msgblock != NULL) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock_reset(msgblock);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = ISC_LIST_NEXT(msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington while (msgblock != NULL) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington next_msgblock = ISC_LIST_NEXT(msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_UNLINK(msg->rdatas, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t));
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = next_msgblock;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington /*
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington * rdatalists could be empty.
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington */
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msgblock = ISC_LIST_HEAD(msg->rdatalists);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (!everything && msgblock != NULL) {
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msgblock_reset(msgblock);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msgblock = ISC_LIST_NEXT(msgblock, link);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington while (msgblock != NULL) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington next_msgblock = ISC_LIST_NEXT(msgblock, link);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t));
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msgblock = next_msgblock;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington }
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msgblock = ISC_LIST_HEAD(msg->offsets);
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington if (!everything && msgblock != NULL) {
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington msgblock_reset(msgblock);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff msgblock = ISC_LIST_NEXT(msgblock, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff while (msgblock != NULL) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_UNLINK(msg->offsets, msgblock, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t));
069104dd6a1bba610d0c3a413459accf73f3921bBrian Wellington msgblock = next_msgblock;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (msg->tsigkey != NULL) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dns_tsigkey_detach(&msg->tsigkey);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->tsigkey = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (msg->tsigctx != NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dst_context_destroy(&msg->tsigctx);
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington if (msg->query.base != NULL) {
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington if (msg->free_query != 0)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(msg->mctx, msg->query.base,
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->query.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->query.base = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->query.length = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->saved.base != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->free_saved != 0)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_mem_put(msg->mctx, msg->saved.base,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->saved.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->saved.base = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->saved.length = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * cleanup the buffer cleanup list
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dynbuf = ISC_LIST_HEAD(msg->cleanup);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington while (dynbuf != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ISC_LIST_UNLINK(msg->cleanup, dynbuf, link);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_free(&dynbuf);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dynbuf = next_dynbuf;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * Set other bits to normal default values.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (!everything)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msginit(msg);
f2338a0d6aa0327372eb20ab5dc29502bc8c71efBrian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ENSURE(isc_mempool_getallocated(msg->namepool) == 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ENSURE(isc_mempool_getallocated(msg->rdspool) == 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonstatic unsigned int
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonspacefortsig(dns_tsigkey_t *key, int otherlen) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_region_t r1, r2;
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington unsigned int x;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff /*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * The space required for an TSIG record is:
f9df80f4348ef68043903efa08299480324f4823Michael Graff *
f9df80f4348ef68043903efa08299480324f4823Michael Graff * n1 bytes for the name
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the type
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff * 2 bytes for the class
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 4 bytes for the ttl
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the rdlength
f9df80f4348ef68043903efa08299480324f4823Michael Graff * n2 bytes for the algorithm name
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * 6 bytes for the time signed
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * 2 bytes for the fudge
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * 2 bytes for the MAC size
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * x bytes for the MAC
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the original id
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the error
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the other data length
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * y bytes for the other data (at most)
f9df80f4348ef68043903efa08299480324f4823Michael Graff * ---------------------------------
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 26 + n1 + n2 + x + y bytes
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dns_name_toregion(&key->name, &r1);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dns_name_toregion(key->algorithm, &r2);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (key->key == NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff x = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff else {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = dst_key_sigsize(key->key, &x);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson if (result != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff x = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff return (26 + r1.length + r2.length + x + otherlen);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graffisc_result_t
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graffdns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_message_t *m;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington isc_result_t result;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_buffer_t *dynbuf;
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff unsigned int i;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(mctx != NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(msgp != NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(*msgp == NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff || intent == DNS_MESSAGE_INTENTRENDER);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff m = isc_mem_get(mctx, sizeof(dns_message_t));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (m == NULL)
0583bf2d0affe0a90ca2284cc27840b160029ff9Michael Graff return (ISC_R_NOMEMORY);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff /*
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * No allocations until further notice. Just initialize all lists
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * and other members that are freed in the cleanup phase here.
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff */
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff
0583bf2d0affe0a90ca2284cc27840b160029ff9Michael Graff m->magic = DNS_MESSAGE_MAGIC;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff m->from_to_wire = intent;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msginit(m);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff for (i = 0; i < DNS_SECTION_MAX; i++)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_INIT(m->sections[i]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->mctx = NULL;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington isc_mem_attach(mctx, &m->mctx);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff ISC_LIST_INIT(m->scratchpad);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff ISC_LIST_INIT(m->cleanup);
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->namepool = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->rdspool = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->rdatas);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->rdatalists);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_INIT(m->offsets);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->freerdata);
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington ISC_LIST_INIT(m->freerdatalist);
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington * Ok, it is safe to allocate (and then "goto cleanup" if failure)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (result != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mempool_setfreemax(m->namepool, NAME_COUNT);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mempool_setname(m->namepool, "msg:names");
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t),
f9df80f4348ef68043903efa08299480324f4823Michael Graff &m->rdspool);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence goto cleanup;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_mempool_setfreemax(m->rdspool, NAME_COUNT);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_mempool_setname(m->rdspool, "msg:rdataset");
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dynbuf = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE);
c610d78e6773b57a1ead6db210c29355ba0bda19Brian Wellington if (result != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence m->cctx = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff *msgp = m;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff return (ISC_R_SUCCESS);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * Cleanup for error returns.
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff cleanup:
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_HEAD(m->scratchpad);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (dynbuf != NULL) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff ISC_LIST_UNLINK(m->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_free(&dynbuf);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (m->namepool != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mempool_destroy(&m->namepool);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson if (m->rdspool != NULL)
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson isc_mempool_destroy(&m->rdspool);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson m->magic = 0;
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t));
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson return (ISC_R_NOMEMORY);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson}
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafssonvoid
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafssondns_message_reset(dns_message_t *msg, unsigned int intent) {
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson REQUIRE(DNS_MESSAGE_VALID(msg));
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson || intent == DNS_MESSAGE_INTENTRENDER);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson msgreset(msg, ISC_FALSE);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson msg->from_to_wire = intent;
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson}
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafssonvoid
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffdns_message_destroy(dns_message_t **msgp) {
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff dns_message_t *msg;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff REQUIRE(msgp != NULL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff REQUIRE(DNS_MESSAGE_VALID(*msgp));
e223094b2248afa2697c531f75e6f84855638becMichael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff msg = *msgp;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff *msgp = NULL;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff msgreset(msg, ISC_TRUE);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson isc_mempool_destroy(&msg->namepool);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson isc_mempool_destroy(&msg->rdspool);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->magic = 0;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t));
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffstatic isc_result_t
e223094b2248afa2697c531f75e6f84855638becMichael Grafffindname(dns_name_t **foundname, dns_name_t *target,
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_namelist_t *section)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael 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)) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (dns_name_equal(curr, target)) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (foundname != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff *foundname = curr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_SUCCESS);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_NOTFOUND);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graffisc_result_t
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dns_rdatatype_t type, dns_rdatatype_t covers,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff dns_rdataset_t **rdataset)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataset_t *curr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff REQUIRE(name != NULL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff REQUIRE(rdataset == NULL || *rdataset == NULL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff for (curr = ISC_LIST_TAIL(name->list);
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr != NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr = ISC_LIST_PREV(curr, link)) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (curr->rdclass == rdclass &&
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff curr->type == type && curr->covers == covers) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdataset != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff *rdataset = curr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_SUCCESS);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_NOTFOUND);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffisc_result_t
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdatatype_t covers, dns_rdataset_t **rdataset)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff dns_rdataset_t *curr;
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence REQUIRE(name != NULL);
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence REQUIRE(rdataset == NULL || *rdataset == NULL);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff for (curr = ISC_LIST_TAIL(name->list);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff curr != NULL;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff curr = ISC_LIST_PREV(curr, link)) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (curr->type == type && curr->covers == covers) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (ISC_UNLIKELY(rdataset != NULL))
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff *rdataset = curr;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (ISC_R_SUCCESS);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff return (ISC_R_NOTFOUND);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson}
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson/*
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Read a name from buffer "source".
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffstatic isc_result_t
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafssongetname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
9dee95b41cfe1d33d542cc2ec0337d66b28b75abBrian Wellington dns_decompress_t *dctx)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson{
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_t *scratch;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_result_t result;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int tries;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff scratch = currentbuffer(msg);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson /*
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * First try: use current buffer.
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Second try: allocate a new buffer and use that.
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson */
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson tries = 0;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson while (tries < 2) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson scratch);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (result == ISC_R_NOSPACE) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tries++;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = newbuffer(msg, SCRATCHPAD_SIZE);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result != ISC_R_SUCCESS)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch = currentbuffer(msg);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_name_reset(name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington INSIST(0); /* Cannot get here... */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington return (ISC_R_UNEXPECTED);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington}
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellingtonstatic isc_result_t
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellingtongetrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington unsigned int rdatalen, dns_rdata_t *rdata)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington{
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_buffer_t *scratch;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington isc_result_t result;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington unsigned int tries;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int trysize;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff scratch = currentbuffer(msg);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_buffer_setactive(source, rdatalen);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * First try: use current buffer.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * Second try: allocate a new buffer of size
e223094b2248afa2697c531f75e6f84855638becMichael Graff * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen)
e223094b2248afa2697c531f75e6f84855638becMichael Graff * (the data will fit if it was not more than 50% compressed)
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Subsequent tries: double buffer size on each try.
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington tries = 0;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington trysize = 0;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /* XXX possibly change this to a while (tries < 2) loop */
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (;;) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = dns_rdata_fromwire(rdata, rdclass, rdtype,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington source, dctx, 0,
d77d08780908c9dc30de7ffd76ca5407f7bf68f2Brian Wellington scratch);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (result == ISC_R_NOSPACE) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (tries == 0) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff trysize = 2 * rdatalen;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (trysize < SCRATCHPAD_SIZE)
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson trysize = SCRATCHPAD_SIZE;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff } else {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff INSIST(trysize != 0);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (trysize >= 65535)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff return (ISC_R_NOSPACE);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington /* XXX DNS_R_RRTOOLONG? */
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington trysize *= 2;
4ce1248f0937485c777af38af02442499effa409Brian Wellington }
4ce1248f0937485c777af38af02442499effa409Brian Wellington tries++;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington result = newbuffer(msg, trysize);
4ce1248f0937485c777af38af02442499effa409Brian Wellington if (result != ISC_R_SUCCESS)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff scratch = currentbuffer(msg);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff } else {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (result);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff#define DO_ERROR(r) \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff do { \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (best_effort) \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff seen_problem = ISC_TRUE; \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff else { \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = r; \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff goto cleanup; \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff } \
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson } while (0)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic isc_result_t
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffgetquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int options)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff{
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_region_t r;
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int count;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name2;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_offsets_t *offsets;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdataset_t *rdataset;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff dns_rdatalist_t *rdatalist;
2196128fc212d8b871c1ce88707e57b7b2619097Brian Wellington isc_result_t result;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_rdatatype_t rdtype;
2196128fc212d8b871c1ce88707e57b7b2619097Brian Wellington dns_rdataclass_t rdclass;
2196128fc212d8b871c1ce88707e57b7b2619097Brian Wellington dns_namelist_t *section;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_boolean_t free_name;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_boolean_t best_effort;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_boolean_t seen_problem;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff section = &msg->sections[DNS_SECTION_QUESTION];
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff seen_problem = ISC_FALSE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff name = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence rdataset = NULL;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff rdatalist = NULL;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name = isc_mempool_get(msg->namepool);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (name == NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_R_NOMEMORY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff free_name = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff offsets = newoffsets(msg);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (offsets == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = ISC_R_NOMEMORY;
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_init(name, *offsets);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington /*
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * Parse the name out of this packet.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_buffer_remainingregion(source, &r);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_buffer_setactive(source, r.length);
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = getname(name, source, msg, dctx);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (result != ISC_R_SUCCESS)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington 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
e223094b2248afa2697c531f75e6f84855638becMichael Graff * name since we no longer need it, and set our name pointer
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * to point to the name we found.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff */
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff result = findname(&name2, name, section);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * If it is the first name in the section, accept it.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff *
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * If it is not, but is not the same as the name already
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * in the question section, append to the section. Note that
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * here in the question section this is illegal, so return
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * FORMERR. In the future, check the opcode to see if
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * this should be legal or not. In either case we no longer
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * need this name pointer.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (result != ISC_R_SUCCESS) {
8b791b4ee85d7926170438752aae9c76f35a056fMark Andrews if (!ISC_LIST_EMPTY(*section))
e223094b2248afa2697c531f75e6f84855638becMichael Graff DO_ERROR(DNS_R_FORMERR);
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_APPEND(*section, name, link);
e223094b2248afa2697c531f75e6f84855638becMichael Graff free_name = ISC_FALSE;
e223094b2248afa2697c531f75e6f84855638becMichael Graff } else {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_mempool_put(msg->namepool, name);
e223094b2248afa2697c531f75e6f84855638becMichael Graff name = name2;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff name2 = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff free_name = ISC_FALSE;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Get type and class.
97f75286ada13a1b06a424607e638bde5ebfb3caAndreas Gustafsson */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_buffer_remainingregion(source, &r);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (r.length < 4) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington result = ISC_R_UNEXPECTEDEND;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington goto cleanup;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff rdtype = isc_buffer_getuint16(source);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdclass = isc_buffer_getuint16(source);
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff /*
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * If this class is different than the one we already read,
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff * this is an error.
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff */
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (msg->rdclass_set == 0) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff msg->rdclass = rdclass;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff msg->rdclass_set = 1;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff } else if (msg->rdclass != rdclass)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff DO_ERROR(DNS_R_FORMERR);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Is this a TKEY query?
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (rdtype == dns_rdatatype_tkey)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews msg->tkey = 1;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews /*
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson * Can't ask the same question twice.
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson */
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson result = dns_message_find(name, rdclass, rdtype, 0, NULL);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (result == ISC_R_SUCCESS)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews DO_ERROR(DNS_R_FORMERR);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new rdatalist.
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = newrdatalist(msg);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdatalist == NULL) {
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = ISC_R_NOMEMORY;
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington rdataset = isc_mempool_get(msg->rdspool);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdataset == NULL) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = ISC_R_NOMEMORY;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff goto cleanup;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Convert rdatalist to rdataset, and attach the latter to
e223094b2248afa2697c531f75e6f84855638becMichael Graff * the name.
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington rdatalist->type = rdtype;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington rdatalist->rdclass = rdclass;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_rdataset_init(rdataset);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington result = dns_rdatalist_tordataset(rdatalist, rdataset);
d77d08780908c9dc30de7ffd76ca5407f7bf68f2Brian Wellington if (result != ISC_R_SUCCESS)
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff ISC_LIST_APPEND(name->list, rdataset, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff rdataset = NULL;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley if (seen_problem)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff return (DNS_R_RECOVERABLE);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff return (ISC_R_SUCCESS);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff cleanup:
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdataset != NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff INSIST(!dns_rdataset_isassociated(rdataset));
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_mempool_put(msg->rdspool, rdataset);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington#if 0
4ce1248f0937485c777af38af02442499effa409Brian Wellington if (rdatalist != NULL)
4ce1248f0937485c777af38af02442499effa409Brian Wellington isc_mempool_put(msg->rdlpool, rdatalist);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington#endif
4ce1248f0937485c777af38af02442499effa409Brian Wellington if (free_name)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington isc_mempool_put(msg->namepool, name);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencestatic isc_boolean_t
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffupdate(dns_section_t section, dns_rdataclass_t rdclass) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (section == DNS_SECTION_PREREQUISITE)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_TF(rdclass == dns_rdataclass_any ||
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff rdclass == dns_rdataclass_none));
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (section == DNS_SECTION_UPDATE)
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_TF(rdclass == dns_rdataclass_any));
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_FALSE);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graffstatic isc_result_t
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencegetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff dns_section_t sectionid, unsigned int options)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff{
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_region_t r;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff unsigned int count, rdatalen;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name2;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_offsets_t *offsets;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_rdataset_t *rdataset;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_rdatalist_t *rdatalist;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson isc_result_t result;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_rdatatype_t rdtype, covers;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_rdataclass_t rdclass;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_rdata_t *rdata;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_ttl_t ttl;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson dns_namelist_t *section;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_boolean_t free_name, free_rdataset;
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_boolean_t preserve_order, best_effort, seen_problem;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_boolean_t issigzero;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
991322a2ab96f2e2379e3bf8b2220cf89f494ad9Brian Wellington seen_problem = ISC_FALSE;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington for (count = 0; count < msg->counts[sectionid]; count++) {
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington int recstart = source->current;
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington isc_boolean_t skip_name_search, skip_type_search;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington section = &msg->sections[sectionid];
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff skip_name_search = ISC_FALSE;
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington skip_type_search = ISC_FALSE;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff free_rdataset = ISC_FALSE;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
bf555703f27295798de30fa8c04d727410788f66Bob Halley name = isc_mempool_get(msg->namepool);
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (name == NULL)
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington return (ISC_R_NOMEMORY);
bf555703f27295798de30fa8c04d727410788f66Bob Halley free_name = ISC_TRUE;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington offsets = newoffsets(msg);
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (offsets == NULL) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington result = ISC_R_NOMEMORY;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington goto cleanup;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley }
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley dns_name_init(name, *offsets);
bf555703f27295798de30fa8c04d727410788f66Bob Halley
bf555703f27295798de30fa8c04d727410788f66Bob Halley /*
bf555703f27295798de30fa8c04d727410788f66Bob Halley * Parse the name out of this packet.
bf555703f27295798de30fa8c04d727410788f66Bob Halley */
bf555703f27295798de30fa8c04d727410788f66Bob Halley isc_buffer_remainingregion(source, &r);
bf555703f27295798de30fa8c04d727410788f66Bob Halley isc_buffer_setactive(source, r.length);
bf555703f27295798de30fa8c04d727410788f66Bob Halley result = getname(name, source, msg, dctx);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (result != ISC_R_SUCCESS)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington goto cleanup;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley /*
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Get type, class, ttl, and rdatalen. Verify that at least
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * rdatalen bytes remain. (Some of this is deferred to
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * later.)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington isc_buffer_remainingregion(source, &r);
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington if (r.length < 2 + 2 + 4 + 2) {
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington result = ISC_R_UNEXPECTEDEND;
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington goto cleanup;
c0a868943801d6d5c764ee644a515b1a67d587edMichael Graff }
c0a868943801d6d5c764ee644a515b1a67d587edMichael Graff rdtype = isc_buffer_getuint16(source);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdclass = isc_buffer_getuint16(source);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * If there was no question section, we may not yet have
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington * established a class. Do so now.
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (msg->rdclass_set == 0 &&
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence rdtype != dns_rdatatype_tsig && /* class is ANY */
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype != dns_rdatatype_tkey) { /* class is undefined */
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->rdclass = rdclass;
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->rdclass_set = 1;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff /*
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * If this class is different than the one in the question
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * section, bail.
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (msg->opcode != dns_opcode_update
e223094b2248afa2697c531f75e6f84855638becMichael Graff && rdtype != dns_rdatatype_tsig
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley && rdtype != dns_rdatatype_opt
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence && rdtype != dns_rdatatype_key /* in a TKEY query */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley && rdtype != dns_rdatatype_sig /* SIG(0) */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley && msg->rdclass != dns_rdataclass_any
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley && msg->rdclass != rdclass)
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley DO_ERROR(DNS_R_FORMERR);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff /*
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * If this is not a TKEY query/response then the KEY
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * record's class needs to match.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (msg->opcode != dns_opcode_update && !msg->tkey &&
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdtype == dns_rdatatype_key &&
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews msg->rdclass != dns_rdataclass_any &&
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews msg->rdclass != rdclass)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews DO_ERROR(DNS_R_FORMERR);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews /*
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * Special type handling for TSIG, OPT, and TKEY.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (rdtype == dns_rdatatype_tsig) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews /*
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * If it is a tsig, verify that it is in the
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * additional data section.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (sectionid != DNS_SECTION_ADDITIONAL ||
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdclass != dns_rdataclass_any ||
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews count != msg->counts[sectionid] - 1)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews DO_ERROR(DNS_R_BADTSIG);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews msg->sigstart = recstart;
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence skip_name_search = ISC_TRUE;
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence skip_type_search = ISC_TRUE;
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson } else if (rdtype == dns_rdatatype_opt) {
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson /*
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson * The name of an OPT record must be ".", it
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * must be in the additional data section, and
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * it must be the first OPT we've seen.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley */
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (!dns_name_equal(dns_rootname, name) ||
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews sectionid != DNS_SECTION_ADDITIONAL ||
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley msg->opt != NULL)
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington DO_ERROR(DNS_R_FORMERR);
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington skip_name_search = ISC_TRUE;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington skip_type_search = ISC_TRUE;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington } else if (rdtype == dns_rdatatype_tkey) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington /*
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington * A TKEY must be in the additional section if this
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington * is a query, and the answer section if this is a
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * response. Unless it's a Win2000 client.
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington *
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * Its class is ignored.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley dns_section_t tkeysection;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington tkeysection = DNS_SECTION_ADDITIONAL;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington else
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff tkeysection = DNS_SECTION_ANSWER;
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (sectionid != tkeysection &&
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley sectionid != DNS_SECTION_ANSWER)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington DO_ERROR(DNS_R_FORMERR);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * ... now get ttl and rdatalen, and check buffer.
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff ttl = isc_buffer_getuint32(source);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff rdatalen = isc_buffer_getuint16(source);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff r.length -= (2 + 2 + 4 + 2);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (r.length < rdatalen) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff result = ISC_R_UNEXPECTEDEND;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff goto cleanup;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Read the rdata from the wire format. Interpret the
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * rdata according to its actual class, even if it had a
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * DynDNS meta-class in the packet (unless this is a TSIG).
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Then put the meta-class back into the finished rdata.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff rdata = newrdata(msg);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (rdata == NULL) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff result = ISC_R_NOMEMORY;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff goto cleanup;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (msg->opcode == dns_opcode_update &&
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff update(sectionid, rdclass)) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (rdatalen != 0) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = DNS_R_FORMERR;
e223094b2248afa2697c531f75e6f84855638becMichael Graff goto cleanup;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington }
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
bf555703f27295798de30fa8c04d727410788f66Bob Halley * When the rdata is empty, the data pointer is
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * never dereferenced, but it must still be non-NULL.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * Casting 1 rather than "" avoids warnings about
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff * discarding the const attribute of a string,
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * for compilers that would warn about such things.
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff */
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff rdata->data = (unsigned char *)1;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff rdata->length = 0;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington rdata->rdclass = rdclass;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington rdata->type = rdtype;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff rdata->flags = DNS_RDATA_UPDATE;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = ISC_R_SUCCESS;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff } else if (rdclass == dns_rdataclass_none &&
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff msg->opcode == dns_opcode_update &&
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff sectionid == DNS_SECTION_UPDATE) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = getrdata(source, msg, dctx, msg->rdclass,
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype, rdatalen, rdata);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = getrdata(source, msg, dctx, rdclass,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdtype, rdatalen, rdata);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result != ISC_R_SUCCESS)
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff goto cleanup;
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff rdata->rdclass = rdclass;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley issigzero = ISC_FALSE;
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff if (rdtype == dns_rdatatype_rrsig &&
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff rdata->flags == 0) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff covers = dns_rdata_covers(rdata);
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff if (covers == 0)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_ERROR(DNS_R_FORMERR);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff rdata->flags == 0) {
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff covers = dns_rdata_covers(rdata);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (covers == 0) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (sectionid != DNS_SECTION_ADDITIONAL ||
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff count != msg->counts[sectionid] - 1)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff DO_ERROR(DNS_R_BADSIG0);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff msg->sigstart = recstart;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff skip_name_search = ISC_TRUE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff skip_type_search = ISC_TRUE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff issigzero = ISC_TRUE;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (msg->rdclass != dns_rdataclass_any &&
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->rdclass != rdclass)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff DO_ERROR(DNS_R_FORMERR);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff } else
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff covers = 0;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Check the ownername of NSEC3 records
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdtype == dns_rdatatype_nsec3 &&
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff !dns_rdata_checkowner(name, msg->rdclass, rdtype,
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson ISC_FALSE)) {
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson result = DNS_R_BADOWNERNAME;
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson goto cleanup;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington /*
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * If we are doing a dynamic update or this is a meta-type,
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * don't bother searching for a name, just append this one
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * to the end of the message.
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (preserve_order || msg->opcode == dns_opcode_update ||
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff skip_name_search) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdtype != dns_rdatatype_opt &&
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype != dns_rdatatype_tsig &&
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley !issigzero)
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley {
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley ISC_LIST_APPEND(*section, name, link);
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley free_name = ISC_FALSE;
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley }
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley } else {
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * Run through the section, looking to see if this name
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * is already there. If it is found, put back the
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * allocated name since we no longer need it, and set
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * our name pointer to point to the name we found.
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = findname(&name2, name, section);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is a new name, append to the section.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff if (result == ISC_R_SUCCESS) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_mempool_put(msg->namepool, name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff name = name2;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(*section, name, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff free_name = ISC_FALSE;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Search name for the particular type and class.
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * Skip this stage if in update mode or this is a meta-type.
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
bf555703f27295798de30fa8c04d727410788f66Bob Halley skip_type_search)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = ISC_R_NOTFOUND;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff else {
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington /*
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson * If this is a type that can only occur in
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson * the question section, fail.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
7153a32ae99388656620b200e6f4ba6e170a208cMichael Graff if (dns_rdatatype_questiononly(rdtype))
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff DO_ERROR(DNS_R_FORMERR);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff rdataset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_message_find(name, rdclass, rdtype,
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington covers, &rdataset);
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington }
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * If we found an rdataset that matches, we need to
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * append this rdata to that set. If we did not, we need
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * to create a new rdatalist, store the important bits there,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * convert it to an rdataset, and link the latter to the name.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Yuck. When appending, make certain that the type isn't
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * a singleton type, such as SOA or CNAME.
5d727330e46c8073703aea7cc0771a456db86829Andreas Gustafsson *
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * Note that this check will be bypassed when preserving order,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * the opcode is an update, or the type search is skipped.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result == ISC_R_SUCCESS) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (dns_rdatatype_issingleton(rdtype)) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdata_t *first;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdatalist_fromrdataset(rdataset,
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff &rdatalist);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff first = ISC_LIST_HEAD(rdatalist->rdata);
e223094b2248afa2697c531f75e6f84855638becMichael Graff INSIST(first != NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence if (dns_rdata_compare(rdata, first) != 0)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_ERROR(DNS_R_FORMERR);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (result == ISC_R_NOTFOUND) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff rdataset = isc_mempool_get(msg->rdspool);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdataset == NULL) {
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_TRUE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = newrdatalist(msg);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (rdatalist == NULL) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = ISC_R_NOMEMORY;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist->type = rdtype;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff rdatalist->covers = covers;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->rdclass = rdclass;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington rdatalist->ttl = ttl;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_rdataset_init(rdataset);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdataset)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff == ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_rdataset_setownercase(rdataset, name);
d77d08780908c9dc30de7ffd76ca5407f7bf68f2Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (rdtype != dns_rdatatype_opt &&
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington rdtype != dns_rdatatype_tsig &&
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington !issigzero)
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley ISC_LIST_APPEND(name->list, rdataset, link);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley free_rdataset = ISC_FALSE;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Minimize TTLs.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff *
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Section 5.2 of RFC2181 says we should drop
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * nonauthoritative rrsets where the TTLs differ, but we
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington * currently treat them the as if they were authoritative and
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff * minimize them.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (ttl != rdataset->ttl) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (ttl < rdataset->ttl)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdataset->ttl = ttl;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley }
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff /* Append this rdata to the rdataset. */
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff dns_rdatalist_fromrdataset(rdataset, &rdatalist);
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
942d1a339b1fe617f7d17d66cb5fccce798d15aeBrian Wellington
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson * If this is an OPT, SIG(0) or TSIG record, remember it.
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * Also, set the extended rcode for TSIG.
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington *
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington * Note msg->opt, msg->sig0 and msg->tsig will only be
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington * already set if best-effort parsing is enabled otherwise
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington * there will only be at most one of each.
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rcode_t ercode;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msg->opt = rdataset;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington rdataset = NULL;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington free_rdataset = ISC_FALSE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ercode = (dns_rcode_t)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington >> 20);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->rcode |= ercode;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_mempool_put(msg->namepool, name);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff free_name = ISC_FALSE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } else if (issigzero && msg->sig0 == NULL) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->sig0 = rdataset;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->sig0name = name;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington rdataset = NULL;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington free_rdataset = ISC_FALSE;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff free_name = ISC_FALSE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msg->tsig = rdataset;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->tsigname = name;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington /* Windows doesn't like TSIG names to be compressed. */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington rdataset = NULL;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington free_rdataset = ISC_FALSE;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff free_name = ISC_FALSE;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence if (seen_problem) {
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson if (free_name)
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson isc_mempool_put(msg->namepool, name);
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson if (free_rdataset)
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson isc_mempool_put(msg->rdspool, rdataset);
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson free_name = free_rdataset = ISC_FALSE;
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff INSIST(free_name == ISC_FALSE);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington INSIST(free_rdataset == ISC_FALSE);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington }
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (seen_problem)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington return (DNS_R_RECOVERABLE);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington return (ISC_R_SUCCESS);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington cleanup:
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (free_name)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington isc_mempool_put(msg->namepool, name);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (free_rdataset)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_mempool_put(msg->rdspool, rdataset);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington return (result);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffisc_result_t
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffdns_message_parse(dns_message_t *msg, isc_buffer_t *source,
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington unsigned int options)
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington{
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington isc_region_t r;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff dns_decompress_t dctx;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_result_t ret;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_uint16_t tmpflags;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_t origsource;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_boolean_t seen_problem;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_boolean_t ignore_tc;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington REQUIRE(source != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff seen_problem = ISC_FALSE;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff origsource = *source;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->header_ok = 0;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->question_ok = 0;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence
59c85e163637936c8b28c3ec947618d7a807fe19Brian Wellington isc_buffer_remainingregion(source, &r);
59c85e163637936c8b28c3ec947618d7a807fe19Brian Wellington if (r.length < DNS_MESSAGE_HEADERLEN)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff return (ISC_R_UNEXPECTEDEND);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->id = isc_buffer_getuint16(source);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington tmpflags = isc_buffer_getuint16(source);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff >> DNS_MESSAGE_OPCODE_SHIFT);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->header_ok = 1;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff msg->state = DNS_SECTION_QUESTION;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * -1 means no EDNS.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = getquestions(source, msg, &dctx, options);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff goto truncated;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (ret == DNS_R_RECOVERABLE) {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff seen_problem = ISC_TRUE;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence ret = ISC_R_SUCCESS;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence }
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (ret != ISC_R_SUCCESS)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff return (ret);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->question_ok = 1;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff goto truncated;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff if (ret == DNS_R_RECOVERABLE) {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff seen_problem = ISC_TRUE;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ret = ISC_R_SUCCESS;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (ret != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (ret);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley goto truncated;
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (ret == DNS_R_RECOVERABLE) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff seen_problem = ISC_TRUE;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ret = ISC_R_SUCCESS;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff if (ret != ISC_R_SUCCESS)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ret);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto truncated;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (ret == DNS_R_RECOVERABLE) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington seen_problem = ISC_TRUE;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ret = ISC_R_SUCCESS;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (ret != ISC_R_SUCCESS)
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (ret);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_remainingregion(source, &r);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (r.length != 0) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
f9df80f4348ef68043903efa08299480324f4823Michael Graff DNS_LOGMODULE_MESSAGE, ISC_LOG_DEBUG(3),
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff "message has %u byte(s) of trailing garbage",
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence r.length);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff truncated:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_usedregion(&origsource, &msg->saved);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff else {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->saved.length = isc_buffer_usedlength(&origsource);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (msg->saved.base == NULL)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_R_NOMEMORY);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff memmove(msg->saved.base, isc_buffer_base(&origsource),
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->saved.length);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->free_saved = 1;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (DNS_R_RECOVERABLE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (seen_problem == ISC_TRUE)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (DNS_R_RECOVERABLE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_R_SUCCESS);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff}
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffisc_result_t
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffdns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_t *buffer)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff{
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_region_t r;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
a920f559c3689f52731519a9d5169ad5814866edMichael Graff REQUIRE(buffer != NULL);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff REQUIRE(msg->buffer == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff msg->cctx = cctx;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff /*
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * Erase the contents of this buffer.
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_clear(buffer);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews
a920f559c3689f52731519a9d5169ad5814866edMichael Graff /*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Make certain there is enough for at least the header in this
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * buffer.
a920f559c3689f52731519a9d5169ad5814866edMichael Graff */
a920f559c3689f52731519a9d5169ad5814866edMichael Graff isc_buffer_availableregion(buffer, &r);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff if (r.length < DNS_MESSAGE_HEADERLEN)
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff return (ISC_R_NOSPACE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (r.length < msg->reserved)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_R_NOSPACE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
41cc03374dc7fd58d3b099d6c921f192a7bbb5f7Michael Graff * Reserve enough space for the header in this buffer.
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff */
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff msg->buffer = buffer;
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff return (ISC_R_SUCCESS);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews}
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graffisc_result_t
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_region_t r, rn;
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington REQUIRE(buffer != NULL);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff REQUIRE(msg->buffer != NULL);
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff /*
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * Ensure that the new buffer is empty, and has enough space to
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * hold the current contents.
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_clear(buffer);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_availableregion(buffer, &rn);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_usedregion(msg->buffer, &r);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence REQUIRE(rn.length > r.length);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * Copy the contents from the old to the new buffer.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_buffer_add(buffer, r.length);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff memmove(rn.base, r.base, r.length);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->buffer = buffer;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_R_SUCCESS);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff}
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewsvoid
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewsdns_message_renderrelease(dns_message_t *msg, unsigned int space) {
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews REQUIRE(space <= msg->reserved);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->reserved -= space;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews}
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewsisc_result_t
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewsdns_message_renderreserve(dns_message_t *msg, unsigned int space) {
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews isc_region_t r;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington if (msg->buffer != NULL) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson isc_buffer_availableregion(msg->buffer, &r);
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson if (r.length < (space + msg->reserved))
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson return (ISC_R_NOSPACE);
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->reserved += space;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_R_SUCCESS);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence}
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffstatic inline isc_boolean_t
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffwrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff int pass_needed;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * If we are not rendering class IN, this ordering is bogus.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (rds->rdclass != dns_rdataclass_in)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_FALSE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews switch (rds->type) {
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews case dns_rdatatype_a:
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews case dns_rdatatype_aaaa:
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews if (preferred_glue == rds->type)
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews pass_needed = 4;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff else
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 3;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington break;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence case dns_rdatatype_rrsig:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_dnskey:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 2;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff break;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff default:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 1;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington if (pass_needed >= pass)
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington return (ISC_FALSE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington return (ISC_TRUE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff}
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff#ifdef ALLOW_FILTER_AAAA
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff/*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Decide whether to not answer with an AAAA record and its RRSIG
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffstatic inline isc_boolean_t
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffnorender_rdataset(const dns_rdataset_t *rdataset, unsigned int options,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff dns_section_t sectionid)
d070219e016b292a49f6f8ccd8975bcc18e46e40Michael Graff{
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff if (sectionid == DNS_SECTION_QUESTION)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_FALSE);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff switch (rdataset->type) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff case dns_rdatatype_ns:
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff sectionid != DNS_SECTION_AUTHORITY)
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff return (ISC_FALSE);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff break;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff case dns_rdatatype_aaaa:
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence return (ISC_FALSE);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff break;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff case dns_rdatatype_rrsig:
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington (rdataset->covers != dns_rdatatype_ns &&
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff rdataset->covers != dns_rdatatype_aaaa))
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence return (ISC_FALSE);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if ((rdataset->covers == dns_rdatatype_ns) &&
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff (sectionid != DNS_SECTION_AUTHORITY))
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington return (ISC_FALSE);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff break;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff default:
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (ISC_FALSE);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence if (rdataset->rdclass != dns_rdataclass_in)
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence return (ISC_FALSE);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (ISC_TRUE);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence}
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence#endif
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrenceisc_result_t
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrencedns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence unsigned int options)
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence{
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence dns_namelist_t *section;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_name_t *name, *next_name;
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence dns_rdataset_t *rdataset, *next_rdataset;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington unsigned int count, total;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_result_t result;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_buffer_t st; /* for rollbacks */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence int pass;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_boolean_t partial = ISC_FALSE;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington unsigned int rd_options;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington dns_rdatatype_t preferred_glue = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(msg->buffer != NULL);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(VALID_NAMED_SECTION(sectionid));
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley section = &msg->sections[sectionid];
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((sectionid == DNS_SECTION_ADDITIONAL)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley && (options & DNS_MESSAGERENDER_ORDERED) == 0) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley preferred_glue = dns_rdatatype_a;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley pass = 4;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley preferred_glue = dns_rdatatype_aaaa;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley pass = 4;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley } else
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley pass = 3;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley } else
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley pass = 1;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley rd_options = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley else
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley rd_options = DNS_RDATASETTOWIRE_OMITDNSSEC;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Shrink the space in the buffer by the reserved amount.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->buffer->length -= msg->reserved;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley total = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley partial = ISC_TRUE;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * Render required glue first. Set TC if it won't fit.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington */
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington name = ISC_LIST_HEAD(*section);
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington if (name != NULL) {
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington rdataset = ISC_LIST_HEAD(name->list);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (rdataset != NULL &&
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 &&
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington const void *order_arg = msg->order_arg;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington st = *(msg->buffer);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington count = 0;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (partial)
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_towirepartial(rdataset,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington name,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->cctx,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->buffer,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->order,
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington order_arg,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington rd_options,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington &count,
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington NULL);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington else
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_towiresorted(rdataset,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington name,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->cctx,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->buffer,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->order,
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington order_arg,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington rd_options,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington &count);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington total += count;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (partial && result == ISC_R_NOSPACE) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msg->flags |= DNS_MESSAGEFLAG_TC;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->buffer->length += msg->reserved;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->counts[sectionid] += total;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington return (result);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result == ISC_R_NOSPACE)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->flags |= DNS_MESSAGEFLAG_TC;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (result != ISC_R_SUCCESS) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington INSIST(st.used < 65536);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_compress_rollback(msg->cctx,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington (isc_uint16_t)st.used);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington *(msg->buffer) = st; /* rollback */
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->buffer->length += msg->reserved;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->counts[sectionid] += total;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff rdataset->attributes |= DNS_RDATASETATTR_RENDERED;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington do {
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington name = ISC_LIST_HEAD(*section);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington if (name == NULL) {
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington msg->buffer->length += msg->reserved;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[sectionid] += total;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington return (ISC_R_SUCCESS);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington while (name != NULL) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington next_name = ISC_LIST_NEXT(name, link);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence rdataset = ISC_LIST_HEAD(name->list);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence while (rdataset != NULL) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington next_rdataset = ISC_LIST_NEXT(rdataset, link);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff if ((rdataset->attributes &
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff DNS_RDATASETATTR_RENDERED) != 0)
f9df80f4348ef68043903efa08299480324f4823Michael Graff goto next;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (((options & DNS_MESSAGERENDER_ORDERED)
f9df80f4348ef68043903efa08299480324f4823Michael Graff == 0)
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley && (sectionid == DNS_SECTION_ADDITIONAL)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence && wrong_priority(rdataset, pass,
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley preferred_glue))
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley goto next;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley#ifdef ALLOW_FILTER_AAAA
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley /*
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Suppress AAAAs if asked and we are
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * not doing DNSSEC or are breaking DNSSEC.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Say so in the AD bit if we break DNSSEC.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley */
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley if (norender_rdataset(rdataset, options, sectionid)) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley if (sectionid == DNS_SECTION_ANSWER ||
acb0311b113e3729dd1ac78dd14c51dc2c010393Mark Andrews sectionid == DNS_SECTION_AUTHORITY)
acb0311b113e3729dd1ac78dd14c51dc2c010393Mark Andrews msg->flags &= ~DNS_MESSAGEFLAG_AD;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley if (OPTOUT(rdataset))
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley msg->flags &= ~DNS_MESSAGEFLAG_AD;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley goto next;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley#endif
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley st = *(msg->buffer);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley count = 0;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley if (partial)
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley result = dns_rdataset_towirepartial(
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rdataset,
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley name,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington msg->cctx,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington msg->buffer,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington msg->order,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington msg->order_arg,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington rd_options,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington &count,
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington NULL);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington else
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington result = dns_rdataset_towiresorted(
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington rdataset,
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley name,
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley msg->cctx,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff msg->buffer,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence msg->order,
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->order_arg,
f9df80f4348ef68043903efa08299480324f4823Michael Graff rd_options,
f9df80f4348ef68043903efa08299480324f4823Michael Graff &count);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff total += count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * If out of space, record stats on what we
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * rendered so far, and return that status.
f9df80f4348ef68043903efa08299480324f4823Michael Graff *
f9df80f4348ef68043903efa08299480324f4823Michael Graff * XXXMLG Need to change this when
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * dns_rdataset_towire() can render partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * sets starting at some arbitrary point in the
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * set. This will include setting a bit in the
f9df80f4348ef68043903efa08299480324f4823Michael Graff * rdataset to indicate that a partial
f9df80f4348ef68043903efa08299480324f4823Michael Graff * rendering was done, and some state saved
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * somewhere (probably in the message struct)
f9df80f4348ef68043903efa08299480324f4823Michael Graff * to indicate where to continue from.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (partial && result == ISC_R_NOSPACE) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->buffer->length += msg->reserved;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->counts[sectionid] += total;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (result);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (result != ISC_R_SUCCESS) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(st.used < 65536);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_compress_rollback(msg->cctx,
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)st.used);
f9df80f4348ef68043903efa08299480324f4823Michael Graff *(msg->buffer) = st; /* rollback */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->buffer->length += msg->reserved;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->counts[sectionid] += total;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * If we have rendered non-validated data,
f9df80f4348ef68043903efa08299480324f4823Michael Graff * ensure that the AD bit is not set.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (rdataset->trust != dns_trust_secure &&
f9df80f4348ef68043903efa08299480324f4823Michael Graff (sectionid == DNS_SECTION_ANSWER ||
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley sectionid == DNS_SECTION_AUTHORITY))
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley msg->flags &= ~DNS_MESSAGEFLAG_AD;
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (OPTOUT(rdataset))
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff msg->flags &= ~DNS_MESSAGEFLAG_AD;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff rdataset->attributes |=
f9df80f4348ef68043903efa08299480324f4823Michael Graff DNS_RDATASETATTR_RENDERED;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff next:
f9df80f4348ef68043903efa08299480324f4823Michael Graff rdataset = next_rdataset;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff name = next_name;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff } while (--pass != 0);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->buffer->length += msg->reserved;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->counts[sectionid] += total;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) {
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson isc_uint16_t tmp;
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson isc_region_t r;
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
a920f559c3689f52731519a9d5169ad5814866edMichael Graff REQUIRE(target != NULL);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff isc_buffer_availableregion(target, &r);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff isc_buffer_putuint16(target, msg->id);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT)
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff & DNS_MESSAGE_OPCODE_MASK);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff tmp |= (msg->rcode & DNS_MESSAGE_RCODE_MASK);
08d94b539a96857670540342df4d81ea55348d03Michael Graff tmp |= (msg->flags & DNS_MESSAGE_FLAG_MASK);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 &&
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff msg->counts[DNS_SECTION_ANSWER] < 65536 &&
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->counts[DNS_SECTION_AUTHORITY] < 65536 &&
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->counts[DNS_SECTION_ADDITIONAL] < 65536);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff isc_buffer_putuint16(target, tmp);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_putuint16(target,
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_putuint16(target,
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_putuint16(target,
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_putuint16(target,
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffisc_result_t
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_renderend(dns_message_t *msg) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_buffer_t tmpbuf;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_region_t r;
f9df80f4348ef68043903efa08299480324f4823Michael Graff int result;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->buffer != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * We have an extended rcode but are not using EDNS.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff return (DNS_R_FORMERR);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * If we're adding a OPT, TSIG or SIG(0) to a truncated message,
f9df80f4348ef68043903efa08299480324f4823Michael Graff * clear all rdatasets from the message except for the question
f9df80f4348ef68043903efa08299480324f4823Michael Graff * before adding the OPT, TSIG or SIG(0). If the question doesn't
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * fit, don't include it.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff */
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) &&
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley (msg->flags & DNS_MESSAGEFLAG_TC) != 0)
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff {
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff isc_buffer_t *buf;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msgresetnames(msg, DNS_SECTION_ANSWER);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff buf = msg->buffer;
fc0d37fa3a50c494e37fbed170f5d53e12778e2cBrian Wellington dns_message_renderreset(msg);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->buffer = buf;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff isc_buffer_clear(msg->buffer);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff dns_compress_rollback(msg->cctx, 0);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington 0);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (result);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington /*
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * If we've got an OPT record, render it.
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington */
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (msg->opt != NULL) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dns_message_renderrelease(msg, msg->opt_reserved);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff msg->opt_reserved = 0;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Set the extended rcode.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley */
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->opt->ttl |= ((msg->rcode << 20) &
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff DNS_MESSAGE_EDNSRCODE_MASK);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff /*
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * Render.
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff count = 0;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff result = dns_rdataset_towire(msg->opt, dns_rootname,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->cctx, msg->buffer, 0,
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff &count);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence msg->counts[DNS_SECTION_ADDITIONAL] += count;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (result != ISC_R_SUCCESS)
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff return (result);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff }
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff /*
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * If we're adding a TSIG record, generate and render it.
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff */
499371d17c34a5770af022f4aa15e764e957a803Michael Graff if (msg->tsigkey != NULL) {
499371d17c34a5770af022f4aa15e764e957a803Michael Graff dns_message_renderrelease(msg, msg->sig_reserved);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->sig_reserved = 0;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff result = dns_tsig_sign(msg);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (result != ISC_R_SUCCESS)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff return (result);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence count = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley result = dns_rdataset_towire(msg->tsig, msg->tsigname,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->cctx, msg->buffer, 0,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff &count);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->counts[DNS_SECTION_ADDITIONAL] += count;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (result != ISC_R_SUCCESS)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (result);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff /*
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * If we're adding a SIG(0) record, generate and render it.
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington */
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (msg->sig0key != NULL) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msg->sig_reserved = 0;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington result = dns_dnssec_signmessage(msg, msg->sig0key);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (result != ISC_R_SUCCESS)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (result);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington count = 0;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington /*
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * Note: dns_rootname is used here, not msg->sig0name, since
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * the owner name of a SIG(0) is irrelevant, and will not
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * be set in a message being rendered.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley result = dns_rdataset_towire(msg->sig0, dns_rootname,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->cctx, msg->buffer, 0,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff &count);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg->counts[DNS_SECTION_ADDITIONAL] += count;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (result != ISC_R_SUCCESS)
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff return (result);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff }
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence isc_buffer_usedregion(msg->buffer, &r);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley isc_buffer_init(&tmpbuf, r.base, r.length);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff dns_message_renderheader(msg, &tmpbuf);
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff msg->buffer = NULL; /* forget about this buffer only on success XXX */
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencevoid
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_renderreset(dns_message_t *msg) {
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff unsigned int i;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff dns_name_t *name;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff dns_rdataset_t *rds;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff /*
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff * Reset the message so that it may be rendered again.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff */
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff msg->buffer = NULL;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff for (i = 0; i < DNS_SECTION_MAX; i++) {
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff msg->cursors[i] = NULL;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff msg->counts[i] = 0;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff for (name = ISC_LIST_HEAD(msg->sections[i]);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff name != NULL;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff name = ISC_LIST_NEXT(name, link)) {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence for (rds = ISC_LIST_HEAD(name->list);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff rds != NULL;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff rds = ISC_LIST_NEXT(rds, link)) {
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff rds->attributes &= ~DNS_RDATASETATTR_RENDERED;
5039f2cad30410b47330c14c0d7ce4ca493a8712Michael Graff }
5039f2cad30410b47330c14c0d7ce4ca493a8712Michael Graff }
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff }
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (msg->tsigname != NULL)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff dns_message_puttempname(msg, &msg->tsigname);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (msg->tsig != NULL) {
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff dns_rdataset_disassociate(msg->tsig);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff dns_message_puttemprdataset(msg, &msg->tsig);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (msg->sig0 != NULL) {
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff dns_rdataset_disassociate(msg->sig0);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_message_puttemprdataset(msg, &msg->sig0);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff }
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_firstname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(VALID_NAMED_SECTION(section));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
271154eafd1111455030abc2997120228be55ef9Mark Andrews if (msg->cursors[section] == NULL)
271154eafd1111455030abc2997120228be55ef9Mark Andrews return (ISC_R_NOMORE);
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley return (ISC_R_SUCCESS);
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley}
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleyisc_result_t
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halleydns_message_nextname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(VALID_NAMED_SECTION(section));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(msg->cursors[section] != NULL);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (msg->cursors[section] == NULL)
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley return (ISC_R_NOMORE);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley return (ISC_R_SUCCESS);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleyvoid
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtondns_message_currentname(dns_message_t *msg, dns_section_t section,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_name_t **name)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington{
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
230aff0eac2d6694c6ca5925b663789e68f267c9Brian Wellington REQUIRE(VALID_NAMED_SECTION(section));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(name != NULL && *name == NULL);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(msg->cursors[section] != NULL);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *name = msg->cursors[section];
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_findname(dns_message_t *msg, dns_section_t section,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_name_t *target, dns_rdatatype_t type,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdatatype_t covers, dns_name_t **name,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdataset_t **rdataset)
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington{
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington dns_name_t *foundname;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington isc_result_t result;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington /*
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington * XXX These requirements are probably too intensive, especially
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington * where things can be NULL, but as they are they ensure that if
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington * something is NON-NULL, indicating that the caller expects it
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington * to be filled in, that we can in fact fill it in.
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff REQUIRE(msg != NULL);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(VALID_SECTION(section));
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(target != NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(name == NULL || *name == NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (type == dns_rdatatype_any) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(rdataset == NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley } else {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(rdataset == NULL || *rdataset == NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence result = findname(&foundname, target,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley &msg->sections[section]);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (result == ISC_R_NOTFOUND)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff return (DNS_R_NXDOMAIN);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley else if (result != ISC_R_SUCCESS)
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff return (result);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (name != NULL)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley *name = foundname;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * And now look for the type.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (ISC_UNLIKELY(type == dns_rdatatype_any))
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (ISC_R_SUCCESS);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_message_findtype(foundname, type, covers, rdataset);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (result == ISC_R_NOTFOUND)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (DNS_R_NXRRSET);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (result);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley}
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleyvoid
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_movename(dns_message_t *msg, dns_name_t *name,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley dns_section_t fromsection,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley dns_section_t tosection)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley{
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg != NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(name != NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(VALID_NAMED_SECTION(fromsection));
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley REQUIRE(VALID_NAMED_SECTION(tosection));
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Unlink the name from the old section
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley ISC_LIST_APPEND(msg->sections[tosection], name, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley}
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleyvoid
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafssondns_message_addname(dns_message_t *msg, dns_name_t *name,
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_section_t section)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley{
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg != NULL);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff REQUIRE(name != NULL);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson REQUIRE(VALID_NAMED_SECTION(section));
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson ISC_LIST_APPEND(msg->sections[section], name, link);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson}
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleyvoid
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graffdns_message_removename(dns_message_t *msg, dns_name_t *name,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_section_t section)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington{
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(msg != NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(name != NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(VALID_NAMED_SECTION(section));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington ISC_LIST_UNLINK(msg->sections[section], name, link);
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellingtonisc_result_t
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellingtondns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(item != NULL && *item == NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *item = isc_mempool_get(msg->namepool);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington if (*item == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOMEMORY);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington dns_name_init(*item, NULL);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington return (ISC_R_SUCCESS);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington}
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington REQUIRE(item != NULL && *item == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington *item = newoffsets(msg);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (*item == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOMEMORY);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(item != NULL && *item == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington *item = newrdata(msg);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington if (*item == NULL)
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington return (ISC_R_NOMEMORY);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington return (ISC_R_SUCCESS);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington}
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtonisc_result_t
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington REQUIRE(item != NULL && *item == NULL);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington *item = isc_mempool_get(msg->rdspool);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington if (*item == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOMEMORY);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdataset_init(*item);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington REQUIRE(item != NULL && *item == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *item = newrdatalist(msg);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (*item == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOMEMORY);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonvoid
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(item != NULL && *item != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (dns_name_dynamic(*item))
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_name_free(*item, msg->mctx);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_mempool_put(msg->namepool, *item);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *item = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonvoid
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(item != NULL && *item != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington releaserdata(msg, *item);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *item = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonvoid
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(item != NULL && *item != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(!dns_rdataset_isassociated(*item));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_mempool_put(msg->rdspool, *item);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *item = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonvoid
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(item != NULL && *item != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington releaserdatalist(msg, *item);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *item = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int *flagsp)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington{
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_region_t r;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_t buffer;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_messageid_t id;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int flags;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(source != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington buffer = *source;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_remainingregion(&buffer, &r);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (r.length < DNS_MESSAGE_HEADERLEN)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_UNEXPECTEDEND);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington id = isc_buffer_getuint16(&buffer);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington flags = isc_buffer_getuint16(&buffer);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington flags &= DNS_MESSAGE_FLAG_MASK;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (flagsp != NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *flagsp = flags;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (idp != NULL)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington *idp = id;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (ISC_R_SUCCESS);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtonisc_result_t
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington unsigned int clear_from;
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington isc_result_t result;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington if (!msg->header_ok)
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington return (DNS_R_FORMERR);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington if (msg->opcode != dns_opcode_query &&
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington msg->opcode != dns_opcode_notify)
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington want_question_section = ISC_FALSE;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington if (msg->opcode == dns_opcode_update)
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington clear_from = DNS_SECTION_PREREQUISITE;
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington else if (want_question_section) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (!msg->question_ok)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (DNS_R_FORMERR);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington clear_from = DNS_SECTION_ANSWER;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington } else
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington clear_from = DNS_SECTION_QUESTION;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msgresetnames(msg, clear_from);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msgresetopt(msg);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msgresetsigs(msg, ISC_TRUE);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msginitprivate(msg);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * We now clear most flags and then set QR, ensuring that the
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * reply's flags will be in a reasonable state.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->flags &= DNS_MESSAGE_REPLYPRESERVE;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->flags |= DNS_MESSAGEFLAG_QR;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * This saves the query TSIG status, if the query was signed, and
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * reserves space in the reply for the TSIG.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->tsigkey != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int otherlen = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->querytsigstatus = msg->tsigstatus;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->tsigstatus = dns_rcode_noerror;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->querytsigstatus == dns_tsigerror_badtime)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington otherlen = 6;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = spacefortsig(msg->tsigkey, otherlen);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_renderreserve(msg, msg->sig_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->saved.base != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->query.base = msg->saved.base;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->query.length = msg->saved.length;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->free_query = msg->free_saved;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->saved.base = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->saved.length = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->free_saved = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_rdataset_t *
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_getopt(dns_message_t *msg) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Get the OPT record for 'msg'.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (msg->opt);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_t rdata = DNS_RDATA_INIT;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Set the OPT record for 'msg'.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * The space required for an OPT record is:
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff *
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 1 byte for the name
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the type
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the class
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 4 bytes for the ttl
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the rdata length
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington * ---------------------------------
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington * 11 bytes
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington *
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington * plus the length of the rdata.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews */
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(opt->type == dns_rdatatype_opt);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(msg->state == DNS_SECTION_ANY);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington msgresetopt(msg);
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_first(opt);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result != ISC_R_SUCCESS)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington goto cleanup;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_rdataset_current(opt, &rdata);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->opt_reserved = 11 + rdata.length;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = dns_message_renderreserve(msg, msg->opt_reserved);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (result != ISC_R_SUCCESS) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->opt_reserved = 0;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington goto cleanup;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->opt = opt;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews return (ISC_R_SUCCESS);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington cleanup:
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_disassociate(opt);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_message_puttemprdataset(msg, &opt);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellingtondns_rdataset_t *
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington /*
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington * Get the TSIG record and owner for 'msg'.
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington */
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
b1a7fea53cb35baf4ca0c6841dce20ef1f90f259Andreas Gustafsson REQUIRE(owner == NULL || *owner == NULL);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (owner != NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *owner = msg->tsigname;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington return (msg->tsig);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_result_t result;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington * Set the TSIG key for 'msg'
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington */
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington REQUIRE(msg->state == DNS_SECTION_ANY);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington if (key == NULL && msg->tsigkey != NULL) {
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington if (msg->sig_reserved != 0) {
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington msg->sig_reserved = 0;
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington }
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington dns_tsigkey_detach(&msg->tsigkey);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington }
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (key != NULL) {
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington dns_tsigkey_attach(key, &msg->tsigkey);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) {
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington msg->sig_reserved = spacefortsig(msg->tsigkey, 0);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington result = dns_message_renderreserve(msg,
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington msg->sig_reserved);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (result != ISC_R_SUCCESS) {
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington dns_tsigkey_detach(&msg->tsigkey);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->sig_reserved = 0;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington }
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington }
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington }
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington return (ISC_R_SUCCESS);
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington}
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtondns_tsigkey_t *
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtondns_message_gettsigkey(dns_message_t *msg) {
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington /*
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington * Get the TSIG key for 'msg'
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington */
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington return (msg->tsigkey);
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington}
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellingtonisc_result_t
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellingtondns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t *rdata = NULL;
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews dns_rdatalist_t *list = NULL;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_t *set = NULL;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_t *buf = NULL;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_region_t r;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_result_t result;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington REQUIRE(msg->querytsig == NULL);
81b438273a0c3141144d169a7ccb110150757337Brian Wellington
81b438273a0c3141144d169a7ccb110150757337Brian Wellington if (querytsig == NULL)
81b438273a0c3141144d169a7ccb110150757337Brian Wellington return (ISC_R_SUCCESS);
81b438273a0c3141144d169a7ccb110150757337Brian Wellington
81b438273a0c3141144d169a7ccb110150757337Brian Wellington result = dns_message_gettemprdata(msg, &rdata);
81b438273a0c3141144d169a7ccb110150757337Brian Wellington if (result != ISC_R_SUCCESS)
81b438273a0c3141144d169a7ccb110150757337Brian Wellington goto cleanup;
c637772ac34b4abb76a250eca89930e6f2bc2ce9Brian Wellington
c637772ac34b4abb76a250eca89930e6f2bc2ce9Brian Wellington result = dns_message_gettemprdatalist(msg, &list);
81b438273a0c3141144d169a7ccb110150757337Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto cleanup;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_message_gettemprdataset(msg, &set);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto cleanup;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington isc_buffer_usedregion(querytsig, &r);
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington result = isc_buffer_allocate(msg->mctx, &buf, r.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto cleanup;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_putmem(buf, r.base, r.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_usedregion(buf, &r);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_init(rdata);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_message_takebuffer(msg, &buf);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington ISC_LIST_APPEND(list->rdata, rdata, link);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdatalist_tordataset(list, set);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto cleanup;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington msg->querytsig = set;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington cleanup:
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (rdata != NULL)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_message_puttemprdata(msg, &rdata);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (list != NULL)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_message_puttemprdatalist(msg, &list);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (set != NULL)
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence dns_message_puttemprdataset(msg, &set);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (ISC_R_NOMEMORY);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington}
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington
5c29047792191d6141f69b2684314d0b762fedebBrian Wellingtonisc_result_t
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellingtondns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_t **querytsig) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_result_t result;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_t rdata = DNS_RDATA_INIT;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_region_t r;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington REQUIRE(mctx != NULL);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington REQUIRE(querytsig != NULL && *querytsig == NULL);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (msg->tsig == NULL)
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington return (ISC_R_SUCCESS);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_first(msg->tsig);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_current(msg->tsig, &rdata);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_toregion(&rdata, &r);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington result = isc_buffer_allocate(mctx, querytsig, r.length);
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_putmem(*querytsig, r.base, r.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (ISC_R_SUCCESS);
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_rdataset_t *
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer /*
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * Get the SIG(0) record for 'msg'.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(owner == NULL || *owner == NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (msg->sig0 != NULL && owner != NULL) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer /* If dns_message_getsig0 is called on a rendered message
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * after the SIG(0) has been applied, we need to return the
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer * root name, not NULL.
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff */
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (msg->sig0name == NULL)
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer *owner = dns_rootname;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer else
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer *owner = msg->sig0name;
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer }
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer return (msg->sig0);
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer}
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyerisc_result_t
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_setsig0key(dns_message_t *msg, dst_key_t *key) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_region_t r;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer unsigned int x;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_result_t result;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer /*
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington * Set the SIG(0) key for 'msg'
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer /*
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * The space required for an SIG(0) record is:
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer *
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * 1 byte for the name
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * 2 bytes for the type
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 2 bytes for the class
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington * 4 bytes for the ttl
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 2 bytes for the type covered
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 1 byte for the algorithm
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington * 1 bytes for the labels
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 4 bytes for the original ttl
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 4 bytes for the signature expiration
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 4 bytes for the signature inception
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 2 bytes for the key tag
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington * n bytes for the signer's name
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * x bytes for the signature
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * ---------------------------------
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington * 27 + n + x bytes
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington */
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(msg->state == DNS_SECTION_ANY);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if (key != NULL) {
194de894f0697562f94e048f573d99260a18a639Michael Sawyer REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_toregion(dst_key_name(key), &r);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dst_key_sigsize(key, &x);
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington if (result != ISC_R_SUCCESS) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer msg->sig_reserved = 0;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->sig_reserved = 27 + r.length + x;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_renderreserve(msg, msg->sig_reserved);
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington if (result != ISC_R_SUCCESS) {
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer msg->sig_reserved = 0;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->sig0key = key;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
90ad126bb363ad419b1348dea2b8613b21b4ded8Andreas Gustafsson return (ISC_R_SUCCESS);
8db2b65318b72e3ee477d6f6a346b525dd2db53aAndreas Gustafsson}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdst_key_t *
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_getsig0key(dns_message_t *msg) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer /*
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer * Get the SIG(0) key for 'msg'
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer */
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson return (msg->sig0key);
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson}
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafssonvoid
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafssondns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson REQUIRE(DNS_MESSAGE_VALID(msg));
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson REQUIRE(buffer != NULL);
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson REQUIRE(ISC_BUFFER_VALID(*buffer));
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ISC_LIST_APPEND(msg->cleanup, *buffer, link);
9066d09c3ef804b997945d34c709e4d2a72d7318Andreas Gustafsson *buffer = NULL;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerisc_result_t
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_signer(dns_message_t *msg, dns_name_t *signer) {
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer isc_result_t result = ISC_R_SUCCESS;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_rdata_t rdata = DNS_RDATA_INIT;
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer REQUIRE(signer != NULL);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (msg->tsig == NULL && msg->sig0 == NULL)
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington return (ISC_R_NOTFOUND);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (msg->verify_attempted == 0)
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer return (DNS_R_NOTVERIFIEDYET);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington if (!dns_name_hasbuffer(signer)) {
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer isc_buffer_t *dynbuf = NULL;
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
194de894f0697562f94e048f573d99260a18a639Michael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_name_setbuffer(signer, dynbuf);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_message_takebuffer(msg, &dynbuf);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (msg->sig0 != NULL) {
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington dns_rdata_sig_t sig;
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson result = dns_rdataset_first(msg->sig0);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer INSIST(result == ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdataset_current(msg->sig0, &rdata);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdata_tostruct(&rdata, &sig, NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS)
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = ISC_R_SUCCESS;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer else
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = DNS_R_SIGINVALID;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_clone(&sig.signer, signer);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdata_freestruct(&sig);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer } else {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_t *identity;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdata_any_tsig_t tsig;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdataset_first(msg->tsig);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer INSIST(result == ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdataset_current(msg->tsig, &rdata);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdata_tostruct(&rdata, &tsig, NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer INSIST(result == ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (msg->tsigstatus != dns_rcode_noerror)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = DNS_R_TSIGVERIFYFAILURE;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer else if (tsig.error != dns_rcode_noerror)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = DNS_R_TSIGERRORSET;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer else
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer result = ISC_R_SUCCESS;
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer dns_rdata_freestruct(&tsig);
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer if (msg->tsigkey == NULL) {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer /*
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer * If msg->tsigstatus & tsig.error are both
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * dns_rcode_noerror, the message must have been
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer * verified, which means msg->tsigkey will be
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer * non-NULL.
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff */
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer INSIST(result != ISC_R_SUCCESS);
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer } else {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer identity = dns_tsigkey_identity(msg->tsigkey);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (identity == NULL) {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer if (result == ISC_R_SUCCESS)
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer result = DNS_R_NOIDENTITY;
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff identity = &msg->tsigkey->name;
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer }
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer dns_name_clone(identity, signer);
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyervoid
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_resetsig(dns_message_t *msg) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington msg->verified_sig = 0;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->verify_attempted = 0;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->tsigstatus = dns_rcode_noerror;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->sig0status = dns_rcode_noerror;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->timeadjust = 0;
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington if (msg->tsigkey != NULL) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_tsigkey_detach(&msg->tsigkey);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer msg->tsigkey = NULL;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerisc_result_t
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_rechecksig(dns_message_t *msg, dns_view_t *view) {
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington dns_message_resetsig(msg);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (dns_message_checksig(msg, view));
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington#ifdef SKAN_MSG_DEBUG
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyervoid
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_dumpsig(dns_message_t *msg, char *txt1) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_rdata_any_tsig_t querytsig;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer isc_result_t result;
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (msg->tsig != NULL) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_rdataset_first(msg->tsig);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer RUNTIME_CHECK(result == ISC_R_SUCCESS);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_rdataset_current(msg->tsig, &querytsigrdata);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington RUNTIME_CHECK(result == ISC_R_SUCCESS);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer hexdump(txt1, "TSIG", querytsig.signature,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer querytsig.siglen);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (msg->querytsig != NULL) {
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews result = dns_rdataset_first(msg->querytsig);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews dns_rdataset_current(msg->querytsig, &querytsigrdata);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington RUNTIME_CHECK(result == ISC_R_SUCCESS);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews hexdump(txt1, "QUERYTSIG", querytsig.signature,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson querytsig.siglen);
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson }
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson}
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson#endif
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrewsisc_result_t
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafssondns_message_checksig(dns_message_t *msg, dns_view_t *view) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson isc_buffer_t b, msgb;
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL)
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews return (ISC_R_SUCCESS);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews INSIST(msg->saved.base != NULL);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews isc_buffer_add(&msgb, msg->saved.length);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews if (msg->tsigkey != NULL || msg->tsig != NULL) {
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews#ifdef SKAN_MSG_DEBUG
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews dns_message_dumpsig(msg, "dns_message_checksig#1");
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews#endif
if (view != NULL)
return (dns_view_checksig(view, &msgb, msg));
else
return (dns_tsig_verify(&msgb, msg, NULL, NULL));
} else {
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_sig_t sig;
dns_rdataset_t keyset;
isc_result_t result;
result = dns_rdataset_first(msg->sig0);
INSIST(result == ISC_R_SUCCESS);
dns_rdataset_current(msg->sig0, &rdata);
/*
* This can occur when the message is a dynamic update, since
* the rdata length checking is relaxed. This should not
* happen in a well-formed message, since the SIG(0) is only
* looked for in the additional section, and the dynamic update
* meta-records are in the prerequisite and update sections.
*/
if (rdata.length == 0)
return (ISC_R_UNEXPECTEDEND);
result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
if (result != ISC_R_SUCCESS)
return (result);
dns_rdataset_init(&keyset);
if (view == NULL)
return (DNS_R_KEYUNAUTHORIZED);
result = dns_view_simplefind(view, &sig.signer,
dns_rdatatype_key /* SIG(0) */,
0, 0, ISC_FALSE, &keyset, NULL);
if (result != ISC_R_SUCCESS) {
/* XXXBEW Should possibly create a fetch here */
result = DNS_R_KEYUNAUTHORIZED;
goto freesig;
} else if (keyset.trust < dns_trust_secure) {
/* XXXBEW Should call a validator here */
result = DNS_R_KEYUNAUTHORIZED;
goto freesig;
}
result = dns_rdataset_first(&keyset);
INSIST(result == ISC_R_SUCCESS);
for (;
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&keyset))
{
dst_key_t *key = NULL;
dns_rdata_reset(&rdata);
dns_rdataset_current(&keyset, &rdata);
isc_buffer_init(&b, rdata.data, rdata.length);
isc_buffer_add(&b, rdata.length);
result = dst_key_fromdns(&sig.signer, rdata.rdclass,
&b, view->mctx, &key);
if (result != ISC_R_SUCCESS)
continue;
if (dst_key_alg(key) != sig.algorithm ||
dst_key_id(key) != sig.keyid ||
!(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
dst_key_proto(key) == DNS_KEYPROTO_ANY))
{
dst_key_free(&key);
continue;
}
result = dns_dnssec_verifymessage(&msgb, msg, key);
dst_key_free(&key);
if (result == ISC_R_SUCCESS)
break;
}
if (result == ISC_R_NOMORE)
result = DNS_R_KEYUNAUTHORIZED;
freesig:
if (dns_rdataset_isassociated(&keyset))
dns_rdataset_disassociate(&keyset);
dns_rdata_freestruct(&sig);
return (result);
}
}
isc_result_t
dns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
const dns_master_style_t *style,
dns_messagetextflag_t flags,
isc_buffer_t *target) {
dns_name_t *name, empty_name;
dns_rdataset_t *rdataset;
isc_result_t result;
isc_boolean_t seensoa = ISC_FALSE;
unsigned int sflags = dns_master_styleflags(style);
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_SECTION(section));
if (ISC_LIST_EMPTY(msg->sections[section]))
return (ISC_R_SUCCESS);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, ";; ");
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, sectiontext[section]);
} else {
ADD_STRING(target, updsectiontext[section]);
}
ADD_STRING(target, " SECTION:\n");
}
dns_name_init(&empty_name, NULL);
result = dns_message_firstname(msg, section);
if (result != ISC_R_SUCCESS) {
return (result);
}
do {
name = NULL;
dns_message_currentname(msg, section, &name);
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
if (section == DNS_SECTION_ANSWER &&
rdataset->type == dns_rdatatype_soa) {
if ((flags & DNS_MESSAGETEXTFLAG_OMITSOA) != 0)
continue;
if (seensoa &&
(flags & DNS_MESSAGETEXTFLAG_ONESOA) != 0)
continue;
seensoa = ISC_TRUE;
}
if (section == DNS_SECTION_QUESTION) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target,
dns_master_indentstr);
ADD_STRING(target, ";");
result = dns_master_questiontotext(name,
rdataset,
style,
target);
} else {
result = dns_master_rdatasettotext(name,
rdataset,
style,
target);
}
if (result != ISC_R_SUCCESS)
return (result);
}
result = dns_message_nextname(msg, section);
} while (result == ISC_R_SUCCESS);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, "\n");
}
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
return (result);
}
static isc_result_t
render_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
int i;
char addr[16], addr_text[64];
isc_uint16_t family;
isc_uint8_t addrlen, addrbytes, scopelen;
/*
* Note: This routine needs to handle malformed ECS options.
*/
if (isc_buffer_remaininglength(ecsbuf) < 4)
return (DNS_R_OPTERR);
family = isc_buffer_getuint16(ecsbuf);
addrlen = isc_buffer_getuint8(ecsbuf);
scopelen = isc_buffer_getuint8(ecsbuf);
addrbytes = (addrlen + 7) / 8;
if (isc_buffer_remaininglength(ecsbuf) < addrbytes)
return (DNS_R_OPTERR);
if (addrbytes > sizeof(addr))
return (DNS_R_OPTERR);
ADD_STRING(target, ": ");
memset(addr, 0, sizeof(addr));
for (i = 0; i < addrbytes; i ++)
addr[i] = isc_buffer_getuint8(ecsbuf);
if (family == 1) {
if (addrlen > 32 || scopelen > 32)
return (DNS_R_OPTERR);
inet_ntop(AF_INET, addr, addr_text, sizeof(addr_text));
} else if (family == 2) {
if (addrlen > 128 || scopelen > 128)
return (DNS_R_OPTERR);
inet_ntop(AF_INET6, addr, addr_text, sizeof(addr_text));
} else {
snprintf(addr_text, sizeof(addr_text),
"Unsupported family %u", family);
ADD_STRING(target, addr_text);
return (ISC_R_SUCCESS);
}
ADD_STRING(target, addr_text);
snprintf(addr_text, sizeof(addr_text), "/%d/%d", addrlen, scopelen);
ADD_STRING(target, addr_text);
return (ISC_R_SUCCESS);
}
isc_result_t
dns_message_pseudosectiontotext(dns_message_t *msg,
dns_pseudosection_t section,
const dns_master_style_t *style,
dns_messagetextflag_t flags,
isc_buffer_t *target)
{
dns_rdataset_t *ps = NULL;
dns_name_t *name = NULL;
isc_result_t result;
char buf[sizeof("1234567890")];
isc_uint32_t mbz;
dns_rdata_t rdata;
isc_buffer_t optbuf;
isc_uint16_t optcode, optlen;
unsigned char *optdata;
unsigned int sflags = dns_master_styleflags(style);
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
REQUIRE(VALID_PSEUDOSECTION(section));
switch (section) {
case DNS_PSEUDOSECTION_OPT:
ps = dns_message_getopt(msg);
if (ps == NULL)
return (ISC_R_SUCCESS);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
}
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, "; EDNS: version: ");
snprintf(buf, sizeof(buf), "%u",
(unsigned int)((ps->ttl & 0x00ff0000) >> 16));
ADD_STRING(target, buf);
ADD_STRING(target, ", flags:");
if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0)
ADD_STRING(target, " do");
mbz = ps->ttl & 0xffff;
mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */
if (mbz != 0) {
ADD_STRING(target, "; MBZ: ");
snprintf(buf, sizeof(buf), "0x%.4x", mbz);
ADD_STRING(target, buf);
ADD_STRING(target, ", udp: ");
} else
ADD_STRING(target, "; udp: ");
snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
ADD_STRING(target, buf);
result = dns_rdataset_first(ps);
if (result != ISC_R_SUCCESS)
return (ISC_R_SUCCESS);
/*
* Print EDNS info, if any.
*
* WARNING: The option contents may be malformed as
* dig +ednsopt=value:<content> does not validity
* checking.
*/
dns_rdata_init(&rdata);
dns_rdataset_current(ps, &rdata);
isc_buffer_init(&optbuf, rdata.data, rdata.length);
isc_buffer_add(&optbuf, rdata.length);
while (isc_buffer_remaininglength(&optbuf) != 0) {
INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
optcode = isc_buffer_getuint16(&optbuf);
optlen = isc_buffer_getuint16(&optbuf);
INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
if (optcode == DNS_OPT_NSID) {
ADD_STRING(target, "; NSID");
} else if (optcode == DNS_OPT_COOKIE) {
ADD_STRING(target, "; COOKIE");
} else if (optcode == DNS_OPT_CLIENT_SUBNET) {
isc_buffer_t ecsbuf;
ADD_STRING(target, "; CLIENT-SUBNET");
isc_buffer_init(&ecsbuf,
isc_buffer_current(&optbuf),
optlen);
isc_buffer_add(&ecsbuf, optlen);
result = render_ecs(&ecsbuf, target);
if (result == ISC_R_NOSPACE)
return (result);
if (result == ISC_R_SUCCESS) {
isc_buffer_forward(&optbuf, optlen);
ADD_STRING(target, "\n");
continue;
}
} else if (optcode == DNS_OPT_EXPIRE) {
if (optlen == 4) {
isc_uint32_t secs;
secs = isc_buffer_getuint32(&optbuf);
ADD_STRING(target, "; EXPIRE: ");
snprintf(buf, sizeof(buf), "%u", secs);
ADD_STRING(target, buf);
ADD_STRING(target, " (");
result = dns_ttl_totext(secs,
ISC_TRUE,
target);
if (result != ISC_R_SUCCESS)
return (result);
ADD_STRING(target, ")\n");
continue;
}
ADD_STRING(target, "; EXPIRE");
} else if (optcode == DNS_OPT_PAD) {
ADD_STRING(target, "; PAD");
} else {
ADD_STRING(target, "; OPT=");
snprintf(buf, sizeof(buf), "%u", optcode);
ADD_STRING(target, buf);
}
if (optlen != 0) {
int i;
ADD_STRING(target, ": ");
optdata = isc_buffer_current(&optbuf);
for (i = 0; i < optlen; i++) {
const char *sep;
switch (optcode) {
case DNS_OPT_COOKIE:
sep = "";
break;
default:
sep = " ";
break;
}
snprintf(buf, sizeof(buf), "%02x%s",
optdata[i], sep);
ADD_STRING(target, buf);
}
isc_buffer_forward(&optbuf, optlen);
if (optcode == DNS_OPT_COOKIE) {
if (msg->cc_ok)
ADD_STRING(target, " (good)");
if (msg->cc_bad)
ADD_STRING(target, " (bad)");
ADD_STRING(target, "\n");
continue;
}
if (optcode == DNS_OPT_CLIENT_SUBNET) {
ADD_STRING(target, "\n");
continue;
}
/*
* For non-COOKIE options, add a printable
* version
*/
ADD_STRING(target, "(\"");
if (isc_buffer_availablelength(target) < optlen)
return (ISC_R_NOSPACE);
for (i = 0; i < optlen; i++) {
if (isprint(optdata[i]))
isc_buffer_putmem(target,
&optdata[i],
1);
else
isc_buffer_putstr(target, ".");
}
ADD_STRING(target, "\")");
}
ADD_STRING(target, "\n");
}
return (ISC_R_SUCCESS);
case DNS_PSEUDOSECTION_TSIG:
ps = dns_message_gettsig(msg, &name);
if (ps == NULL)
return (ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, "\n");
return (result);
case DNS_PSEUDOSECTION_SIG0:
ps = dns_message_getsig0(msg, &name);
if (ps == NULL)
return (ISC_R_SUCCESS);
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n");
result = dns_master_rdatasettotext(name, ps, style, target);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
(flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ADD_STRING(target, "\n");
return (result);
}
return (ISC_R_UNEXPECTED);
}
isc_result_t
dns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
dns_messagetextflag_t flags, isc_buffer_t *target)
{
unsigned int sflags = dns_master_styleflags(style);
char buf[sizeof("1234567890")];
isc_result_t result;
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(target != NULL);
if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
ADD_STRING(target, opcodetext[msg->opcode]);
ADD_STRING(target, ", status: ");
result = dns_rcode_totext(msg->rcode, target);
if (result != ISC_R_SUCCESS)
return (result);
ADD_STRING(target, ", id: ");
snprintf(buf, sizeof(buf), "%6u", msg->id);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, ";; flags:");
if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
ADD_STRING(target, " qr");
if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
ADD_STRING(target, " aa");
if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
ADD_STRING(target, " tc");
if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
ADD_STRING(target, " rd");
if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
ADD_STRING(target, " ra");
if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
ADD_STRING(target, " ad");
if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
ADD_STRING(target, " cd");
/*
* The final unnamed flag must be zero.
*/
if ((msg->flags & 0x0040U) != 0) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, "; MBZ: 0x4");
}
if (msg->opcode != dns_opcode_update) {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, "; QUESTION: ");
} else {
if ((sflags & DNS_STYLEFLAG_INDENT) != 0)
ADD_STRING(target, dns_master_indentstr);
ADD_STRING(target, "; ZONE: ");
}
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_QUESTION]);
ADD_STRING(target, buf);
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, ", ANSWER: ");
} else {
ADD_STRING(target, ", PREREQ: ");
}
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_ANSWER]);
ADD_STRING(target, buf);
if (msg->opcode != dns_opcode_update) {
ADD_STRING(target, ", AUTHORITY: ");
} else {
ADD_STRING(target, ", UPDATE: ");
}
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_AUTHORITY]);
ADD_STRING(target, buf);
ADD_STRING(target, ", ADDITIONAL: ");
snprintf(buf, sizeof(buf), "%1u",
msg->counts[DNS_SECTION_ADDITIONAL]);
ADD_STRING(target, buf);
ADD_STRING(target, "\n");
}
result = dns_message_pseudosectiontotext(msg,
DNS_PSEUDOSECTION_OPT,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_pseudosectiontotext(msg,
DNS_PSEUDOSECTION_TSIG,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_pseudosectiontotext(msg,
DNS_PSEUDOSECTION_SIG0,
style, flags, target);
if (result != ISC_R_SUCCESS)
return (result);
return (ISC_R_SUCCESS);
}
isc_region_t *
dns_message_getrawmessage(dns_message_t *msg) {
REQUIRE(DNS_MESSAGE_VALID(msg));
return (&msg->saved);
}
void
dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
const void *order_arg)
{
REQUIRE(DNS_MESSAGE_VALID(msg));
msg->order = order;
msg->order_arg = order_arg;
}
void
dns_message_settimeadjust(dns_message_t *msg, int timeadjust) {
REQUIRE(DNS_MESSAGE_VALID(msg));
msg->timeadjust = timeadjust;
}
int
dns_message_gettimeadjust(dns_message_t *msg) {
REQUIRE(DNS_MESSAGE_VALID(msg));
return (msg->timeadjust);
}
isc_result_t
dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) {
REQUIRE(opcode < 16);
if (isc_buffer_availablelength(target) < strlen(opcodetext[opcode]))
return (ISC_R_NOSPACE);
isc_buffer_putstr(target, opcodetext[opcode]);
return (ISC_R_SUCCESS);
}
void
dns_message_logpacket(dns_message_t *message, const char *description,
isc_logcategory_t *category, isc_logmodule_t *module,
int level, isc_mem_t *mctx)
{
logfmtpacket(message, description, NULL, category, module,
&dns_master_style_debug, level, mctx);
}
void
dns_message_logpacket2(dns_message_t *message,
const char *description, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module,
int level, isc_mem_t *mctx)
{
REQUIRE(address != NULL);
logfmtpacket(message, description, address, category, module,
&dns_master_style_debug, level, mctx);
}
void
dns_message_logfmtpacket(dns_message_t *message, const char *description,
isc_logcategory_t *category, isc_logmodule_t *module,
const dns_master_style_t *style, int level,
isc_mem_t *mctx)
{
logfmtpacket(message, description, NULL, category, module, style,
level, mctx);
}
void
dns_message_logfmtpacket2(dns_message_t *message,
const char *description, isc_sockaddr_t *address,
isc_logcategory_t *category, isc_logmodule_t *module,
const dns_master_style_t *style, int level,
isc_mem_t *mctx)
{
REQUIRE(address != NULL);
logfmtpacket(message, description, address, category, module, style,
level, mctx);
}
static void
logfmtpacket(dns_message_t *message, const char *description,
isc_sockaddr_t *address, isc_logcategory_t *category,
isc_logmodule_t *module, const dns_master_style_t *style,
int level, isc_mem_t *mctx)
{
char addrbuf[ISC_SOCKADDR_FORMATSIZE] = { 0 };
const char *newline = "\n";
const char *space = " ";
isc_buffer_t buffer;
char *buf = NULL;
int len = 1024;
isc_result_t result;
if (! isc_log_wouldlog(dns_lctx, level))
return;
/*
* Note that these are multiline debug messages. We want a newline
* to appear in the log after each message.
*/
if (address != NULL)
isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
else
newline = space = "";
do {
buf = isc_mem_get(mctx, len);
if (buf == NULL)
break;
isc_buffer_init(&buffer, buf, len);
result = dns_message_totext(message, style, 0, &buffer);
if (result == ISC_R_NOSPACE) {
isc_mem_put(mctx, buf, len);
len += 1024;
} else if (result == ISC_R_SUCCESS)
isc_log_write(dns_lctx, category, module, level,
"%s%s%s%s%.*s", description, space,
addrbuf, newline,
(int)isc_buffer_usedlength(&buffer),
buf);
} while (result == ISC_R_NOSPACE);
if (buf != NULL)
isc_mem_put(mctx, buf, len);
}
isc_result_t
dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp,
unsigned int version, isc_uint16_t udpsize,
unsigned int flags, dns_ednsopt_t *ednsopts, size_t count)
{
dns_rdataset_t *rdataset = NULL;
dns_rdatalist_t *rdatalist = NULL;
dns_rdata_t *rdata = NULL;
isc_result_t result;
unsigned int len = 0, i;
REQUIRE(DNS_MESSAGE_VALID(message));
REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
result = dns_message_gettemprdatalist(message, &rdatalist);
if (result != ISC_R_SUCCESS)
return (result);
result = dns_message_gettemprdata(message, &rdata);
if (result != ISC_R_SUCCESS)
goto cleanup;
result = dns_message_gettemprdataset(message, &rdataset);
if (result != ISC_R_SUCCESS)
goto cleanup;
rdatalist->type = dns_rdatatype_opt;
/*
* Set Maximum UDP buffer size.
*/
rdatalist->rdclass = udpsize;
/*
* Set EXTENDED-RCODE and Z to 0.
*/
rdatalist->ttl = (version << 16);
rdatalist->ttl |= (flags & 0xffff);
/*
* Set EDNS options if applicable
*/
if (count != 0U) {
isc_buffer_t *buf = NULL;
for (i = 0; i < count; i++)
len += ednsopts[i].length + 4;
if (len > 0xffffU) {
result = ISC_R_NOSPACE;
goto cleanup;
}
result = isc_buffer_allocate(message->mctx, &buf, len);
if (result != ISC_R_SUCCESS)
goto cleanup;
for (i = 0; i < count; i++) {
isc_buffer_putuint16(buf, ednsopts[i].code);
isc_buffer_putuint16(buf, ednsopts[i].length);
isc_buffer_putmem(buf, ednsopts[i].value,
ednsopts[i].length);
}
rdata->data = isc_buffer_base(buf);
rdata->length = len;
dns_message_takebuffer(message, &buf);
} else {
rdata->data = NULL;
rdata->length = 0;
}
rdata->rdclass = rdatalist->rdclass;
rdata->type = rdatalist->type;
rdata->flags = 0;
ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
*rdatasetp = rdataset;
return (ISC_R_SUCCESS);
cleanup:
if (rdata != NULL)
dns_message_puttemprdata(message, &rdata);
if (rdataset != NULL)
dns_message_puttemprdataset(message, &rdataset);
if (rdatalist != NULL)
dns_message_puttemprdatalist(message, &rdatalist);
return (result);
}
void
dns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) {
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
REQUIRE(msg->state == DNS_SECTION_ANY);
REQUIRE(msg->rdclass_set == 0);
msg->rdclass = rdclass;
msg->rdclass_set = 1;
}