message.c revision 2047977ce2dfcfe3a0fa2d638c3242841310fad3
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
a7038d1a0513c8e804937ebc95fc9cb3a46c04f5Mark Andrews * Copyright (C) 1999-2002 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15a44745412679c30a6d022733925af70a38b715David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews/* $Id: message.c,v 1.220 2004/02/27 20:41:43 marka Exp $ */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/***
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *** Imports
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ***/
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <config.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
ce24330566b66a5ca8522fa948fb36b94a4d6981Mark Andrews#include <isc/buffer.h>
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence#include <isc/mem.h>
ce24330566b66a5ca8522fa948fb36b94a4d6981Mark Andrews#include <isc/print.h>
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/string.h> /* Required for HP/UX (and others?) */
364a82f7c25b62967678027043425201a5e5171aBob Halley#include <isc/util.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/dnssec.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/keyvalues.h>
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson#include <dns/log.h>
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson#include <dns/masterdump.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <dns/message.h>
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews#include <dns/opcode.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/rdata.h>
f9df80f4348ef68043903efa08299480324f4823Michael Graff#include <dns/rdatalist.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/rdataset.h>
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington#include <dns/rdatastruct.h>
09f22ac5b09e70bc526015f37168ba33e21ea91fDavid Lawrence#include <dns/result.h>
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington#include <dns/tsig.h>
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington#include <dns/view.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
75ec9bc9c7b4f2485647414330122e7b8e188097Andreas Gustafsson#define DNS_MESSAGE_OPCODE_MASK 0x7800U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_OPCODE_SHIFT 11
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#define DNS_MESSAGE_RCODE_MASK 0x000fU
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff#define DNS_MESSAGE_FLAG_MASK 0x8ff0U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSRCODE_SHIFT 24
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley#define DNS_MESSAGE_EDNSVERSION_SHIFT 16
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
f9df80f4348ef68043903efa08299480324f4823Michael Graff && ((s) < DNS_SECTION_MAX))
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
f9df80f4348ef68043903efa08299480324f4823Michael Graff && ((s) < DNS_SECTION_MAX))
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington#define ADD_STRING(b, s) {if (strlen(s) >= \
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington isc_buffer_availablelength(b)) \
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington return(ISC_R_NOSPACE); else \
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington isc_buffer_putstr(b, s);}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer && ((s) < DNS_PSEUDOSECTION_MAX))
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * This is the size of each individual scratchpad buffer, and the numbers
f9df80f4348ef68043903efa08299480324f4823Michael Graff * of various block allocations used within the server.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * XXXMLG These should come from a config setting.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff#define SCRATCHPAD_SIZE 512
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define NAME_COUNT 8
be066f0629a12e11bc17f27671036b3f451bd5eaBrian Wellington#define OFFSET_COUNT 4
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATA_COUNT 8
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATALIST_COUNT 8
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATASET_COUNT RDATALIST_COUNT
f9df80f4348ef68043903efa08299480324f4823Michael Graff
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer/*
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * Text representation of the different items, for message_totext
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * functions.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer */
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *sectiontext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "QUESTION",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ANSWER",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "AUTHORITY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "ADDITIONAL"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyerstatic const char *updsectiontext[] = {
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer "ZONE",
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer "PREREQUISITE",
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer "UPDATE",
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer "ADDITIONAL"
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer};
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *opcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "QUERY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "IQUERY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "STATUS",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED3",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTIFY",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "UPDATE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED6",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED7",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED8",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED9",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED10",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED15"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *rcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOERROR",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "FORMERR",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "SERVFAIL",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NXDOMAIN",
da5d1cf1b1aa29ae53a0427be49291b04bd60549Mark Andrews "NOTIMP",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "REFUSED",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "YXDOMAIN",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "YXRRSET",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NXRRSET",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTAUTH",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "NOTZONE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED15",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "BADVERS"
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer};
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * "helper" type, which consists of a block of some type, and is linkable.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
f9df80f4348ef68043903efa08299480324f4823Michael Graff * size, or the allocated elements will not be alligned correctly.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graffstruct dns_msgblock {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int remaining;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LINK(dns_msgblock_t) link;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}; /* dynamically sized */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic inline dns_msgblock_t *
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define msgblock_get(block, type) \
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ((type *)msgblock_internalget(block, sizeof(type)))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_internalget(dns_msgblock_t *, unsigned int);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_reset(dns_msgblock_t *);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * is free, return NULL.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline dns_msgblock_t *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int count)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff dns_msgblock_t *block;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int length;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * count);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block = isc_mem_get(mctx, length);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff if (block == NULL)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff return (NULL);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff block->count = count;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block->remaining = count;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ISC_LINK_INIT(block, link);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (block);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Return an element from the msgblock. If no more are available, return
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * NULL.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff void *ptr;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
8c55a67a6d185de7036e39da30561a5c1637d22bAndreas Gustafsson if (block == NULL || block->remaining == 0)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (NULL);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff block->remaining--;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ptr = (((unsigned char *)block)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff + sizeof(dns_msgblock_t)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff + (sizeof_type * block->remaining));
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff return (ptr);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_reset(dns_msgblock_t *block) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff block->remaining = block->count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Release memory associated with a message block.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff{
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int length;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_mem_put(mctx, block, length);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff/*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new dynamic buffer, and attach it to this message as the
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * "current" buffer. (which is always the last on the list, for our
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * uses)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic inline isc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewbuffer(dns_message_t *msg, unsigned int size) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_result_t result;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dynbuf = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (result != ISC_R_SUCCESS)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline isc_buffer_t *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencecurrentbuffer(dns_message_t *msg) {
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dynbuf = ISC_LIST_TAIL(msg->scratchpad);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(dynbuf != NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff return (dynbuf);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencereleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_PREPEND(msg->freerdata, rdata, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdata_t *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewrdata(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_msgblock_t *msgblock;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdata_t *rdata;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (rdata != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdata, rdata, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock = ISC_LIST_TAIL(msg->rdatas);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = msgblock_get(msgblock, dns_rdata_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (rdata == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RDATA_COUNT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (msgblock == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->rdatas, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdata = msgblock_get(msgblock, dns_rdata_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
5e589b5356a4125b5af32605dead82ab8b467c88Mark Andrews dns_rdata_init(rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdata);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencereleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdatalist_t *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewrdatalist(dns_message_t *msg) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_msgblock_t *msgblock;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdatalist_t *rdatalist;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff if (rdatalist != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdatalist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock = ISC_LIST_TAIL(msg->rdatalists);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (rdatalist == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff sizeof(dns_rdatalist_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff RDATALIST_COUNT);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (msgblock == NULL)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (rdatalist);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtonstatic inline dns_offsets_t *
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtonnewoffsets(dns_message_t *msg) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_msgblock_t *msgblock;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_offsets_t *offsets;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = ISC_LIST_TAIL(msg->offsets);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington offsets = msgblock_get(msgblock, dns_offsets_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (offsets == NULL) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = msgblock_allocate(msg->mctx,
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington sizeof(dns_offsets_t),
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington OFFSET_COUNT);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (msgblock == NULL)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (NULL);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_APPEND(msg->offsets, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington offsets = msgblock_get(msgblock, dns_offsets_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (offsets);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington}
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginitheader(dns_message_t *m) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->id = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->flags = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->rcode = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->opcode = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff m->rdclass = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginitprivate(dns_message_t *m) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley unsigned int i;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley for (i = 0; i < DNS_SECTION_MAX; i++) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff m->cursors[i] = NULL;
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff m->counts[i] = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff m->opt = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington m->sig0 = NULL;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington m->sig0name = NULL;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington m->tsig = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington m->tsigname = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley m->opt_reserved = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington m->sig_reserved = 0;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff m->reserved = 0;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff m->buffer = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginittsig(dns_message_t *m) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington m->tsigstatus = dns_rcode_noerror;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington m->querytsigstatus = dns_rcode_noerror;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington m->tsigkey = NULL;
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellington m->tsigctx = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->sigstart = -1;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->sig0key = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington m->sig0status = dns_rcode_noerror;
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews m->timeadjust = 0;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington}
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
f9df80f4348ef68043903efa08299480324f4823Michael Graff/*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Init elements to default state. Used both when allocating a new element
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * and when resetting one.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsginit(dns_message_t *m) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msginitheader(m);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msginitprivate(m);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msginittsig(m);
996028142c5f95492fcd42e69186b95641320c7bBob Halley m->header_ok = 0;
996028142c5f95492fcd42e69186b95641320c7bBob Halley m->question_ok = 0;
24694ab18a48bcc9c50304bd8b7eb6b9c7650129Brian Wellington m->tcp_continuation = 0;
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington m->verified_sig = 0;
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington m->verify_attempted = 0;
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson m->order = NULL;
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson m->order_arg = NULL;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->query.base = NULL;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->query.length = 0;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->free_query = 0;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->saved.base = NULL;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->saved.length = 0;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->free_saved = 0;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington m->querytsig = NULL;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleymsgresetnames(dns_message_t *msg, unsigned int first_section) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_name_t *name, *next_name;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_rdataset_t *rds, *next_rds;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up name lists by calling the rdataset disassociate function.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley for (i = first_section; i < DNS_SECTION_MAX; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff name = ISC_LIST_HEAD(msg->sections[i]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (name != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_name = ISC_LIST_NEXT(name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[i], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff rds = ISC_LIST_HEAD(name->list);
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (rds != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_rds = ISC_LIST_NEXT(rds, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(name->list, rds, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff INSIST(dns_rdataset_isassociated(rds));
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_rdataset_disassociate(rds);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdspool, rds);
f9df80f4348ef68043903efa08299480324f4823Michael Graff rds = next_rds;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff if (dns_name_dynamic(name))
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff dns_name_free(name, msg->mctx);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff name = next_name;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleystatic void
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleymsgresetopt(dns_message_t *msg)
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley{
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley if (msg->opt != NULL) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley if (msg->opt_reserved > 0) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_message_renderrelease(msg, msg->opt_reserved);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 0;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley }
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley INSIST(dns_rdataset_isassociated(msg->opt));
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_rdataset_disassociate(msg->opt);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley isc_mempool_put(msg->rdspool, msg->opt);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt = NULL;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley }
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley}
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtonstatic void
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonmsgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->sig_reserved > 0) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->tsig != NULL) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington INSIST(dns_rdataset_isassociated(msg->tsig));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(msg->namepool != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (replying) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington INSIST(msg->querytsig == NULL);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->querytsig = msg->tsig;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington } else {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_rdataset_disassociate(msg->tsig);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_mempool_put(msg->rdspool, msg->tsig);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->querytsig != NULL) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_rdataset_disassociate(msg->querytsig);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_mempool_put(msg->rdspool, msg->querytsig);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington if (dns_name_dynamic(msg->tsigname))
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington dns_name_free(msg->tsigname, msg->mctx);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->namepool, msg->tsigname);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->tsig = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->tsigname = NULL;
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington } else if (msg->querytsig != NULL && !replying) {
22057930cd2a71e1073781b650c7296739c869a6Brian Wellington dns_rdataset_disassociate(msg->querytsig);
22057930cd2a71e1073781b650c7296739c869a6Brian Wellington isc_mempool_put(msg->rdspool, msg->querytsig);
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington msg->querytsig = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->sig0 != NULL) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(dns_rdataset_isassociated(msg->sig0));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_disassociate(msg->sig0);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->rdspool, msg->sig0);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington if (msg->sig0name != NULL) {
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington if (dns_name_dynamic(msg->sig0name))
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington dns_name_free(msg->sig0name, msg->mctx);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington isc_mempool_put(msg->namepool, msg->sig0name);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->sig0 = NULL;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington msg->sig0name = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley/*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Free all but one (or everything) for this message. This is used by
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson * both dns_message_reset() and dns_message_destroy().
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgreset(dns_message_t *msg, isc_boolean_t everything) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_msgblock_t *msgblock, *next_msgblock;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf, *next_dynbuf;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_rdata_t *rdata;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley dns_rdatalist_t *rdatalist;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msgresetnames(msg, 0);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msgresetopt(msg);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msgresetsigs(msg, ISC_FALSE);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up linked lists.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff /*
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * Run through the free lists, and just unlink anything found there.
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * The memory isn't lost since these are part of message blocks we
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * have allocated.
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff */
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff while (rdata != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdata, rdata, link);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdata = ISC_LIST_HEAD(msg->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff while (rdatalist != NULL) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff }
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_HEAD(msg->scratchpad);
f9df80f4348ef68043903efa08299480324f4823Michael Graff INSIST(dynbuf != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything) {
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_clear(dynbuf);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_NEXT(dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (dynbuf != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_free(&dynbuf);
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = next_dynbuf;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = ISC_LIST_HEAD(msg->rdatas);
5f8b996a813e3e0adfbba2abf7671f631e21e056Brian Wellington if (!everything && msgblock != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_reset(msgblock);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = ISC_LIST_NEXT(msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff while (msgblock != NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->rdatas, msgblock, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = next_msgblock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * rdatalists could be empty.
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff */
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msgblock = ISC_LIST_HEAD(msg->rdatalists);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything && msgblock != NULL) {
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_reset(msgblock);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msgblock = ISC_LIST_NEXT(msgblock, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff }
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff while (msgblock != NULL) {
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t));
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msgblock = next_msgblock;
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = ISC_LIST_HEAD(msg->offsets);
5f8b996a813e3e0adfbba2abf7671f631e21e056Brian 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->offsets, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t));
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock = next_msgblock;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (msg->tsigkey != NULL) {
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington dns_tsigkey_detach(&msg->tsigkey);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->tsigkey = NULL;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington if (msg->query.base != NULL) {
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (msg->free_query != 0)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington isc_mem_put(msg->mctx, msg->query.base,
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->query.length);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->query.base = NULL;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->query.length = 0;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington if (msg->saved.base != NULL) {
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (msg->free_saved != 0)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington isc_mem_put(msg->mctx, msg->saved.base,
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->saved.length);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->saved.base = NULL;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->saved.length = 0;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington }
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * cleanup the buffer cleanup list
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dynbuf = ISC_LIST_HEAD(msg->cleanup);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff while (dynbuf != NULL) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
069104dd6a1bba610d0c3a413459accf73f3921bBrian Wellington ISC_LIST_UNLINK(msg->cleanup, dynbuf, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_buffer_free(&dynbuf);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dynbuf = next_dynbuf;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Set other bits to normal default values.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (!everything)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msginit(msg);
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington ENSURE(isc_mempool_getallocated(msg->namepool) == 0);
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington ENSURE(isc_mempool_getallocated(msg->rdspool) == 0);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonstatic unsigned int
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonspacefortsig(dns_tsigkey_t *key, int otherlen) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_region_t r1, r2;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int x;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * The space required for an TSIG record is:
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * n1 bytes for the name
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the type
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the class
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 4 bytes for the ttl
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * 2 bytes for the rdlength
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * n2 bytes for the algorithm name
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 6 bytes for the time signed
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the fudge
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the MAC size
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * x bytes for the MAC
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the original id
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the error
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the other data length
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * y bytes for the other data (at most)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * ---------------------------------
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * 26 + n1 + n2 + x + y bytes
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_name_toregion(&key->name, &r1);
f2338a0d6aa0327372eb20ab5dc29502bc8c71efBrian Wellington dns_name_toregion(key->algorithm, &r2);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (key->key == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington x = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington else {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dst_key_sigsize(key->key, &x);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington x = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington return (26 + r1.length + r2.length + x + otherlen);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_message_t *m;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_result_t result;
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff isc_buffer_t *dynbuf;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(mctx != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(msgp != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(*msgp == NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff || intent == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff m = isc_mem_get(mctx, sizeof(dns_message_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (m == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * No allocations until further notice. Just initialize all lists
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * and other members that are freed in the cleanup phase here.
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley m->magic = DNS_MESSAGE_MAGIC;
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->from_to_wire = intent;
f9df80f4348ef68043903efa08299480324f4823Michael Graff msginit(m);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (i = 0; i < DNS_SECTION_MAX; i++)
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->sections[i]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->mctx = mctx;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->scratchpad);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_INIT(m->cleanup);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff m->namepool = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff m->rdspool = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->rdatas);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_INIT(m->rdatalists);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_INIT(m->offsets);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_INIT(m->freerdata);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_INIT(m->freerdatalist);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff /*
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * Ok, it is safe to allocate (and then "goto cleanup" if failure)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (result != ISC_R_SUCCESS)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_setfreemax(m->namepool, NAME_COUNT);
0583bf2d0affe0a90ca2284cc27840b160029ff9Michael Graff isc_mempool_setname(m->namepool, "msg:names");
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t),
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff &m->rdspool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (result != ISC_R_SUCCESS)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_setfreemax(m->rdspool, NAME_COUNT);
0583bf2d0affe0a90ca2284cc27840b160029ff9Michael Graff isc_mempool_setname(m->rdspool, "msg:rdataset");
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (result != ISC_R_SUCCESS)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff goto cleanup;
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington m->cctx = NULL;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *msgp = m;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Cleanup for error returns.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff cleanup:
f9df80f4348ef68043903efa08299480324f4823Michael Graff dynbuf = ISC_LIST_HEAD(m->scratchpad);
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington if (dynbuf != NULL) {
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington ISC_LIST_UNLINK(m->scratchpad, dynbuf, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_buffer_free(&dynbuf);
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (m->namepool != NULL)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_destroy(&m->namepool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (m->rdspool != NULL)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_destroy(&m->rdspool);
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->magic = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(mctx, m, sizeof(dns_message_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_reset(dns_message_t *msg, unsigned int intent) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley || intent == DNS_MESSAGE_INTENTRENDER);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgreset(msg, ISC_FALSE);
c610d78e6773b57a1ead6db210c29355ba0bda19Brian Wellington msg->from_to_wire = intent;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_destroy(dns_message_t **msgp) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_message_t *msg;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(msgp != NULL);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(*msgp));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff msg = *msgp;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *msgp = NULL;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgreset(msg, ISC_TRUE);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_destroy(&msg->namepool);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_destroy(&msg->rdspool);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->magic = 0;
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(msg->mctx, msg, sizeof(dns_message_t));
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafssonstatic isc_result_t
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafssonfindname(dns_name_t **foundname, dns_name_t *target,
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson dns_namelist_t *section)
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson{
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson dns_name_t *curr;
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (curr = ISC_LIST_TAIL(*section);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson curr != NULL;
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson curr = ISC_LIST_PREV(curr, link)) {
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson if (dns_name_equal(curr, target)) {
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson if (foundname != NULL)
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson *foundname = curr;
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson return (ISC_R_SUCCESS);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson }
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson }
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson return (ISC_R_NOTFOUND);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson}
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graffdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff dns_rdatatype_t covers, dns_rdataset_t **rdataset)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataset_t *curr;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff if (rdataset != NULL) {
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff REQUIRE(*rdataset == NULL);
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff }
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (curr = ISC_LIST_TAIL(name->list);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson curr != NULL;
e223094b2248afa2697c531f75e6f84855638becMichael Graff curr = ISC_LIST_PREV(curr, link)) {
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley if (curr->type == type && curr->covers == covers) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (rdataset != NULL)
e223094b2248afa2697c531f75e6f84855638becMichael Graff *rdataset = curr;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOTFOUND);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff/*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Read a name from buffer "source".
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
e223094b2248afa2697c531f75e6f84855638becMichael Graffgetname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_decompress_t *dctx)
e223094b2248afa2697c531f75e6f84855638becMichael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_buffer_t *scratch;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int tries;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff scratch = currentbuffer(msg);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * First try: use current buffer.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Second try: allocate a new buffer and use that.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff tries = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff while (tries < 2) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
e223094b2248afa2697c531f75e6f84855638becMichael Graff scratch);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOSPACE) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff tries++;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = newbuffer(msg, SCRATCHPAD_SIZE);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff scratch = currentbuffer(msg);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_name_reset(name);
e223094b2248afa2697c531f75e6f84855638becMichael Graff } else {
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (result);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff INSIST(0); /* Cannot get here... */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTED);
e223094b2248afa2697c531f75e6f84855638becMichael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrencegetrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence unsigned int rdatalen, dns_rdata_t *rdata)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff{
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_t *scratch;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int tries;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson unsigned int trysize;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch = currentbuffer(msg);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_setactive(source, rdatalen);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * First try: use current buffer.
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Second try: allocate a new buffer of size
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * (the data will fit if it was not more than 50% compressed)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Subsequent tries: double buffer size on each try.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tries = 0;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize = 0;
9dee95b41cfe1d33d542cc2ec0337d66b28b75abBrian Wellington /* XXX possibly change this to a while (tries < 2) loop */
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson for (;;) {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = dns_rdata_fromwire(rdata, rdclass, rdtype,
2047977ce2dfcfe3a0fa2d638c3242841310fad3Mark Andrews source, dctx, 0,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOSPACE) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (tries == 0) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize = 2 * rdatalen;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (trysize < SCRATCHPAD_SIZE)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize = SCRATCHPAD_SIZE;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson } else {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson INSIST(trysize != 0);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (trysize >= 65535)
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson return (ISC_R_NOSPACE);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson /* XXX DNS_R_RRTOOLONG? */
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson trysize *= 2;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tries++;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = newbuffer(msg, trysize);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff scratch = currentbuffer(msg);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (result);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff}
e223094b2248afa2697c531f75e6f84855638becMichael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington#define DO_FORMERR \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington do { \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (best_effort) \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington seen_problem = ISC_TRUE; \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington else { \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington result = DNS_R_FORMERR; \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington goto cleanup; \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } while (0)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellingtongetquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington unsigned int options)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_region_t r;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int count;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_name_t *name;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_name_t *name2;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_offsets_t *offsets;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdataset_t *rdataset;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_rdatalist_t *rdatalist;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdatatype_t rdtype;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataclass_t rdclass;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_namelist_t *section;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_boolean_t free_name;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington isc_boolean_t best_effort;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington isc_boolean_t seen_problem;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff section = &msg->sections[DNS_SECTION_QUESTION];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
d77d08780908c9dc30de7ffd76ca5407f7bf68f2Brian Wellington seen_problem = ISC_FALSE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff name = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdataset = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdatalist = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name = isc_mempool_get(msg->namepool);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff if (name == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff free_name = ISC_TRUE;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington offsets = newoffsets(msg);
4ce1248f0937485c777af38af02442499effa409Brian Wellington if (offsets == NULL) {
4ce1248f0937485c777af38af02442499effa409Brian Wellington result = ISC_R_NOMEMORY;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington goto cleanup;
4ce1248f0937485c777af38af02442499effa409Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_name_init(name, *offsets);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Parse the name out of this packet.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_setactive(source, r.length);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = getname(name, source, msg, dctx);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Run through the section, looking to see if this name
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * is already there. If it is found, put back the allocated
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * name since we no longer need it, and set our name pointer
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * to point to the name we found.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = findname(&name2, name, section);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is the first name in the section, accept it.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff *
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is not, but is not the same as the name already
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * in the question section, append to the section. Note that
e223094b2248afa2697c531f75e6f84855638becMichael Graff * here in the question section this is illegal, so return
e223094b2248afa2697c531f75e6f84855638becMichael Graff * FORMERR. In the future, check the opcode to see if
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this should be legal or not. In either case we no longer
e223094b2248afa2697c531f75e6f84855638becMichael Graff * need this name pointer.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS) {
2196128fc212d8b871c1ce88707e57b7b2619097Brian Wellington if (!ISC_LIST_EMPTY(*section))
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
2196128fc212d8b871c1ce88707e57b7b2619097Brian Wellington ISC_LIST_APPEND(*section, name, link);
2196128fc212d8b871c1ce88707e57b7b2619097Brian Wellington free_name = ISC_FALSE;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff } else {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff name = name2;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name2 = NULL;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff free_name = ISC_FALSE;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Get type and class.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (r.length < 4) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_UNEXPECTEDEND;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdclass = isc_buffer_getuint16(source);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If this class is different than the one we already read,
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this is an error.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (msg->state == DNS_SECTION_ANY) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->state = DNS_SECTION_QUESTION;
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->rdclass = rdclass;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } else if (msg->rdclass != rdclass)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Can't ask the same question twice.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(name, rdtype, 0, NULL);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (result == ISC_R_SUCCESS)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new rdatalist.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist = newrdatalist(msg);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (rdatalist == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdataset = isc_mempool_get(msg->rdspool);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (rdataset == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Convert rdatalist to rdataset, and attach the latter to
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * the name.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->type = rdtype;
8b791b4ee85d7926170438752aae9c76f35a056fMark Andrews rdatalist->covers = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->rdclass = rdclass;
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->ttl = 0;
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_INIT(rdatalist->rdata);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdataset_init(rdataset);
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_rdatalist_tordataset(rdatalist, rdataset);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff goto cleanup;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_APPEND(name->list, rdataset, link);
97f75286ada13a1b06a424607e638bde5ebfb3caAndreas Gustafsson rdataset = NULL;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff }
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (seen_problem)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington return (DNS_R_RECOVERABLE);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff cleanup:
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff if (rdataset != NULL) {
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff INSIST(!dns_rdataset_isassociated(rdataset));
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdspool, rdataset);
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff }
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff#if 0
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (rdatalist != NULL)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdlpool, rdatalist);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff#endif
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff if (free_name)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->namepool, name);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsstatic isc_boolean_t
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsupdate(dns_section_t section, dns_rdataclass_t rdclass) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (section == DNS_SECTION_PREREQUISITE)
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_TF(rdclass == dns_rdataclass_any ||
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson rdclass == dns_rdataclass_none));
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson if (section == DNS_SECTION_UPDATE)
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson return (ISC_TF(rdclass == dns_rdataclass_any));
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_FALSE);
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews}
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffstatic isc_result_t
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_section_t sectionid, unsigned int options)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff{
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_region_t r;
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson unsigned int count, rdatalen;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_name_t *name2;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_offsets_t *offsets;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataset_t *rdataset;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdatalist_t *rdatalist;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t rdtype, covers;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdataclass_t rdclass;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdata_t *rdata;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_ttl_t ttl;
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_namelist_t *section;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_boolean_t free_name, free_rdataset;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington isc_boolean_t preserve_order, best_effort, seen_problem;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington isc_boolean_t issigzero;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
d77d08780908c9dc30de7ffd76ca5407f7bf68f2Brian Wellington seen_problem = ISC_FALSE;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (count = 0; count < msg->counts[sectionid]; count++) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington int recstart = source->current;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley isc_boolean_t skip_name_search, skip_type_search;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff section = &msg->sections[sectionid];
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_FALSE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff name = isc_mempool_get(msg->namepool);
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (name == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_TRUE;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington offsets = newoffsets(msg);
4ce1248f0937485c777af38af02442499effa409Brian Wellington if (offsets == NULL) {
4ce1248f0937485c777af38af02442499effa409Brian Wellington result = ISC_R_NOMEMORY;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington goto cleanup;
4ce1248f0937485c777af38af02442499effa409Brian Wellington }
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_name_init(name, *offsets);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Parse the name out of this packet.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_buffer_setactive(source, r.length);
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = getname(name, source, msg, dctx);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Get type, class, ttl, and rdatalen. Verify that at least
e223094b2248afa2697c531f75e6f84855638becMichael Graff * rdatalen bytes remain. (Some of this is deferred to
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * later.)
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (r.length < 2 + 2 + 4 + 2) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_UNEXPECTEDEND;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdclass = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson /*
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson * If there was no question section, we may not yet have
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson * established a class. Do so now.
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson */
43733a83ed92359555c0dcc766e04216ba858309Mark Andrews if (msg->state == DNS_SECTION_ANY &&
43733a83ed92359555c0dcc766e04216ba858309Mark Andrews rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
43733a83ed92359555c0dcc766e04216ba858309Mark Andrews rdtype != dns_rdatatype_tsig && /* class is ANY */
43733a83ed92359555c0dcc766e04216ba858309Mark Andrews rdtype != dns_rdatatype_tkey) { /* class is undefined */
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson msg->rdclass = rdclass;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson msg->state = DNS_SECTION_QUESTION;
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If this class is different than the one in the question
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * section, bail.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (msg->opcode != dns_opcode_update
991322a2ab96f2e2379e3bf8b2220cf89f494ad9Brian Wellington && rdtype != dns_rdatatype_tsig
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley && rdtype != dns_rdatatype_opt
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews && rdtype != dns_rdatatype_dnskey /* in a TKEY query */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_sig /* SIG(0) */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington && msg->rdclass != rdclass)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Special type handling for TSIG, OPT, and TKEY.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff if (rdtype == dns_rdatatype_tsig) {
bf555703f27295798de30fa8c04d727410788f66Bob Halley /*
bf555703f27295798de30fa8c04d727410788f66Bob Halley * If it is a tsig, verify that it is in the
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * additional data section.
bf555703f27295798de30fa8c04d727410788f66Bob Halley */
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (sectionid != DNS_SECTION_ADDITIONAL ||
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington rdclass != dns_rdataclass_any ||
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington count != msg->counts[sectionid] - 1)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->sigstart = recstart;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_TRUE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = ISC_TRUE;
bf555703f27295798de30fa8c04d727410788f66Bob Halley } else if (rdtype == dns_rdatatype_opt) {
bf555703f27295798de30fa8c04d727410788f66Bob Halley /*
bf555703f27295798de30fa8c04d727410788f66Bob Halley * The name of an OPT record must be ".", it
bf555703f27295798de30fa8c04d727410788f66Bob Halley * must be in the additional data section, and
bf555703f27295798de30fa8c04d727410788f66Bob Halley * it must be the first OPT we've seen.
bf555703f27295798de30fa8c04d727410788f66Bob Halley */
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (!dns_name_equal(dns_rootname, name) ||
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->opt != NULL)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_TRUE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = ISC_TRUE;
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington } else if (rdtype == dns_rdatatype_tkey) {
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * A TKEY must be in the additional section if this
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * is a query, and the answer section if this is a
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington * response. Unless it's a Win2000 client.
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington *
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Its class is ignored.
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington */
c0a868943801d6d5c764ee644a515b1a67d587edMichael Graff dns_section_t tkeysection;
c0a868943801d6d5c764ee644a515b1a67d587edMichael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington tkeysection = DNS_SECTION_ADDITIONAL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington else
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington tkeysection = DNS_SECTION_ANSWER;
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington if (sectionid != tkeysection &&
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington sectionid != DNS_SECTION_ANSWER)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * ... now get ttl and rdatalen, and check buffer.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
e223094b2248afa2697c531f75e6f84855638becMichael Graff ttl = isc_buffer_getuint32(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalen = isc_buffer_getuint16(source);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff r.length -= (2 + 2 + 4 + 2);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (r.length < rdatalen) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_UNEXPECTEDEND;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley /*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Read the rdata from the wire format. Interpret the
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * rdata according to its actual class, even if it had a
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * DynDNS meta-class in the packet (unless this is a TSIG).
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * Then put the meta-class back into the finished rdata.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley rdata = newrdata(msg);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdata == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (msg->opcode == dns_opcode_update &&
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews update(sectionid, rdclass)) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (rdatalen != 0) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews result = DNS_R_FORMERR;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews goto cleanup;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews }
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews /*
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * When the rdata is empty, the data pointer is
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * never dereferenced, but it must still be non-NULL.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * Casting 1 rather than "" avoids warnings about
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * discarding the const attribute of a string,
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * for compilers that would warn about such things.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews */
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdata->data = (unsigned char *)1;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdata->length = 0;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdata->rdclass = rdclass;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdata->type = rdtype;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews rdata->flags = DNS_RDATA_UPDATE;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews result = ISC_R_SUCCESS;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews } else if (rdtype == dns_rdatatype_tsig)
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence result = getrdata(source, msg, dctx, rdclass,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence rdtype, rdatalen, rdata);
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson else
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = getrdata(source, msg, dctx, msg->rdclass,
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson rdtype, rdatalen, rdata);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley rdata->rdclass = rdclass;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (rdtype == dns_rdatatype_rrsig &&
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews rdata->flags == 0) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley covers = dns_rdata_covers(rdata);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (covers == 0)
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews DO_FORMERR;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews } else
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews covers = 0;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews issigzero = ISC_FALSE;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews rdata->flags == 0) {
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (dns_rdata_covers(rdata) == 0) {
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (sectionid != DNS_SECTION_ADDITIONAL ||
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington count != msg->counts[sectionid] - 1)
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington DO_FORMERR;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->sigstart = recstart;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington skip_name_search = ISC_TRUE;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington skip_type_search = ISC_TRUE;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington issigzero = ISC_TRUE;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews }
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
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
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * to the end of the message.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (rdtype != dns_rdatatype_opt &&
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdtype != dns_rdatatype_tsig &&
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington !issigzero)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ISC_LIST_APPEND(*section, name, link);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff } else {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Run through the section, looking to see if this name
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * is already there. If it is found, put back the
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * allocated name since we no longer need it, and set
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * our name pointer to point to the name we found.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = findname(&name2, name, section);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If it is a new name, append to the section.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_SUCCESS) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff isc_mempool_put(msg->namepool, name);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff name = name2;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff } else {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff ISC_LIST_APPEND(*section, name, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff }
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Search name for the particular type and class.
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * Skip this stage if in update mode or this is a meta-type.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOTFOUND;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff else {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff /*
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * If this is a type that can only occur in
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * the question section, fail.
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff */
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (dns_rdatatype_questiononly(rdtype))
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington DO_FORMERR;
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff rdataset = NULL;
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(name, rdtype, covers,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff &rdataset);
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If we found an rdataset that matches, we need to
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * append this rdata to that set. If we did not, we need
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * to create a new rdatalist, store the important bits there,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * convert it to an rdataset, and link the latter to the name.
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * Yuck. When appending, make certain that the type isn't
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * a singleton type, such as SOA or CNAME.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley *
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * Note that this check will be bypassed when preserving order,
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff * the opcode is an update, or the type search is skipped.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff if (result == ISC_R_SUCCESS) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (dns_rdatatype_issingleton(rdtype))
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington DO_FORMERR;
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff }
3bb3b7ac462a90c2b8b1fb783324d800e2ba748cMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOTFOUND) {
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff rdataset = isc_mempool_get(msg->rdspool);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdataset == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_TRUE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist = newrdatalist(msg);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (rdatalist == NULL) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff result = ISC_R_NOMEMORY;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->type = rdtype;
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley rdatalist->covers = covers;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->rdclass = rdclass;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist->ttl = ttl;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_INIT(rdatalist->rdata);
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdataset_init(rdataset);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson rdataset)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson == ISC_R_SUCCESS);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (rdtype != dns_rdatatype_opt &&
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington rdtype != dns_rdatatype_tsig &&
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington !issigzero)
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ISC_LIST_APPEND(name->list, rdataset, link);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_FALSE;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
e223094b2248afa2697c531f75e6f84855638becMichael Graff /*
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * Minimize TTLs.
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley *
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * Section 5.2 of RFC 2181 says we should drop
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * nonauthoritative rrsets where the TTLs differ, but we
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * currently treat them the as if they were authoritative and
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * minimize them.
e223094b2248afa2697c531f75e6f84855638becMichael Graff */
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff if (ttl != rdataset->ttl) {
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff if (ttl < rdataset->ttl)
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff rdataset->ttl = ttl;
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff }
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff /*
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * XXXMLG Perform a totally ugly hack here to pull
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * the rdatalist out of the private field in the rdataset,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * and append this rdata to the rdatalist's linked list
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * of rdata.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist = (dns_rdatalist_t *)(rdataset->private1);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * If this is an OPT record, remember it. Also, set
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * the extended rcode. Note that msg->opt will only be set
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * if best-effort parsing is enabled.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff */
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington dns_rcode_t ercode;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
bf555703f27295798de30fa8c04d727410788f66Bob Halley msg->opt = rdataset;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff rdataset = NULL;
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_rdataset = ISC_FALSE;
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington ercode = (dns_rcode_t)
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson >> 20);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->rcode |= ercode;
7153a32ae99388656620b200e6f4ba6e170a208cMichael Graff isc_mempool_put(msg->namepool, name);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff free_name = ISC_FALSE;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * If this is an SIG(0) or TSIG record, remember it. Note
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * that msg->sig0 or msg->tsig will only be set if best-effort
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * parsing is enabled.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (issigzero && msg->sig0 == NULL) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->sig0 = rdataset;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington msg->sig0name = name;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdataset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_rdataset = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_name = ISC_FALSE;
5d727330e46c8073703aea7cc0771a456db86829Andreas Gustafsson } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->tsig = rdataset;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->tsigname = name;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdataset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_rdataset = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_name = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff INSIST(free_name == ISC_FALSE);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff INSIST(free_rdataset == ISC_FALSE);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (seen_problem)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington return (DNS_R_RECOVERABLE);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff cleanup:
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (free_name)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_mempool_put(msg->namepool, name);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (free_rdataset)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff isc_mempool_put(msg->rdspool, rdataset);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff return (result);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff}
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafssondns_message_parse(dns_message_t *msg, isc_buffer_t *source,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington unsigned int options)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff isc_region_t r;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff dns_decompress_t dctx;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t ret;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff isc_uint16_t tmpflags;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_buffer_t origsource;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington isc_boolean_t seen_problem;
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews isc_boolean_t ignore_tc;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff REQUIRE(source != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d77d08780908c9dc30de7ffd76ca5407f7bf68f2Brian Wellington seen_problem = ISC_FALSE;
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington origsource = *source;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->header_ok = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->question_ok = 0;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff if (r.length < DNS_MESSAGE_HEADERLEN)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTEDEND);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msg->id = isc_buffer_getuint16(source);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff tmpflags = isc_buffer_getuint16(source);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff >> DNS_MESSAGE_OPCODE_SHIFT);
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK);
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->header_ok = 1;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff /*
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * -1 means no EDNS.
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff */
942d1a339b1fe617f7d17d66cb5fccce798d15aeBrian Wellington dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getquestions(source, msg, &dctx, options);
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews goto truncated;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (ret == DNS_R_RECOVERABLE) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington seen_problem = ISC_TRUE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = ISC_R_SUCCESS;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->question_ok = 1;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews goto truncated;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (ret == DNS_R_RECOVERABLE) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington seen_problem = ISC_TRUE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = ISC_R_SUCCESS;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews goto truncated;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (ret == DNS_R_RECOVERABLE) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington seen_problem = ISC_TRUE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = ISC_R_SUCCESS;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews goto truncated;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (ret == DNS_R_RECOVERABLE) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington seen_problem = ISC_TRUE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = ISC_R_SUCCESS;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (ret != ISC_R_SUCCESS)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff return (ret);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(source, &r);
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson if (r.length != 0) {
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
4f39334027e6048e8a0e45030e9f46c2de0d2ecbMichael Graff DNS_LOGMODULE_MESSAGE, ISC_LOG_DEBUG(3),
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson "message has %u byte(s) of trailing garbage",
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson r.length);
7d823f705d9d3a8cb4d43fcf11249515e2845364Andreas Gustafsson }
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews truncated:
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington isc_buffer_usedregion(&origsource, &msg->saved);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington else {
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->saved.length = isc_buffer_usedlength(&origsource);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if (msg->saved.base == NULL)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington return (ISC_R_NOMEMORY);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington memcpy(msg->saved.base, isc_buffer_base(&origsource),
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->saved.length);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->free_saved = 1;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington }
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews if (ret == ISC_R_UNEXPECTEDEND && ignore_tc)
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews return (DNS_R_RECOVERABLE);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (seen_problem == ISC_TRUE)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington return (DNS_R_RECOVERABLE);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellingtondns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington isc_buffer_t *buffer)
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington{
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_region_t r;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(buffer != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer == NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington msg->cctx = cctx;
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Erase the contents of this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_clear(buffer);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Make certain there is enough for at least the header in this
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(buffer, &r);
59c85e163637936c8b28c3ec947618d7a807fe19Brian Wellington if (r.length < DNS_MESSAGE_HEADERLEN)
59c85e163637936c8b28c3ec947618d7a807fe19Brian Wellington return (ISC_R_NOSPACE);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (r.length < msg->reserved)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOSPACE);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Reserve enough space for the header in this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->buffer = buffer;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff}
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_region_t r, rn;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(buffer != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Ensure that the new buffer is empty, and has enough space to
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * hold the current contents.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_clear(buffer);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(buffer, &rn);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(msg->buffer, &r);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(rn.length > r.length);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff /*
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Copy the contents from the old to the new buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff */
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_add(buffer, r.length);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff memcpy(rn.base, r.base, r.length);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->buffer = buffer;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halleyvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderrelease(dns_message_t *msg, unsigned int space) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley REQUIRE(space <= msg->reserved);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->reserved -= space;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderreserve(dns_message_t *msg, unsigned int space) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_region_t r;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->buffer != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_availableregion(msg->buffer, &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (r.length < (space + msg->reserved))
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOSPACE);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->reserved += space;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffstatic inline isc_boolean_t
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrewswrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff int pass_needed;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * If we are not rendering class IN, this ordering is bogus.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (rds->rdclass != dns_rdataclass_in)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_FALSE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff switch (rds->type) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_a:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff case dns_rdatatype_aaaa:
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews if (preferred_glue == rds->type)
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews pass_needed = 4;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews else
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews pass_needed = 3;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff break;
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews case dns_rdatatype_rrsig:
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews case dns_rdatatype_dnskey:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 2;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff break;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff default:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass_needed = 1;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if (pass_needed >= pass)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_FALSE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (ISC_TRUE);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff}
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
a920f559c3689f52731519a9d5169ad5814866edMichael Graffdns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff unsigned int options)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
a920f559c3689f52731519a9d5169ad5814866edMichael Graff dns_namelist_t *section;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff dns_name_t *name, *next_name;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff dns_rdataset_t *rdataset, *next_rdataset;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff unsigned int count, total;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff isc_buffer_t st; /* for rollbacks */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff int pass;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews isc_boolean_t partial = ISC_FALSE;
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington unsigned int rd_options;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews dns_rdatatype_t preferred_glue = 0;
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->buffer != NULL);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff REQUIRE(VALID_NAMED_SECTION(sectionid));
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
a920f559c3689f52731519a9d5169ad5814866edMichael Graff section = &msg->sections[sectionid];
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if ((sectionid == DNS_SECTION_ADDITIONAL)
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews && (options & DNS_MESSAGERENDER_ORDERED) == 0) {
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) {
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews preferred_glue = dns_rdatatype_a;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews pass = 4;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) {
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews preferred_glue = dns_rdatatype_aaaa;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews pass = 4;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews } else
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews pass = 3;
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews } else
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff pass = 1;
41cc03374dc7fd58d3b099d6c921f192a7bbb5f7Michael Graff
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0)
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington rd_options = 0;
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington else
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington rd_options = DNS_RDATASETTOWIRE_OMITDNSSEC;
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff /*
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff * Shrink the space in the buffer by the reserved amount.
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff */
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff msg->buffer->length -= msg->reserved;
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff total = 0;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews partial = ISC_TRUE;
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff do {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff name = ISC_LIST_HEAD(*section);
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington if (name == NULL) {
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington msg->buffer->length += msg->reserved;
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington msg->counts[sectionid] += total;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
b6e9d91ff0621aec03cbc51421408074a0291b1eBrian Wellington }
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff while (name != NULL) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next_name = ISC_LIST_NEXT(name, link);
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff rdataset = ISC_LIST_HEAD(name->list);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff while (rdataset != NULL) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next_rdataset = ISC_LIST_NEXT(rdataset, link);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if ((rdataset->attributes &
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence DNS_RDATASETATTR_RENDERED) != 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff goto next;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if (((options & DNS_MESSAGERENDER_ORDERED)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence == 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff && (sectionid == DNS_SECTION_ADDITIONAL)
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews && wrong_priority(rdataset, pass,
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews preferred_glue))
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff goto next;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff st = *(msg->buffer);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff count = 0;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews if (partial)
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews result = dns_rdataset_towirepartial(
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews rdataset,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews name,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->cctx,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->buffer,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->order,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->order_arg,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington rd_options,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews &count,
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews NULL);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews else
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews result = dns_rdataset_towiresorted(
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews rdataset,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson name,
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington msg->cctx,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson msg->buffer,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson msg->order,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson msg->order_arg,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington rd_options,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson &count);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff total += count;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * If out of space, record stats on what we
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rendered so far, and return that status.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff *
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * XXXMLG Need to change this when
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * dns_rdataset_towire() can render partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * sets starting at some arbitary point in the
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * set. This will include setting a bit in the
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rdataset to indicate that a partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rendering was done, and some state saved
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * somewhere (probably in the message struct)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * to indicate where to continue from.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff */
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews if (partial && result == ISC_R_NOSPACE) {
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->buffer->length += msg->reserved;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews msg->counts[sectionid] += total;
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews return (result);
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews }
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff INSIST(st.used < 65536);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington dns_compress_rollback(msg->cctx,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)st.used);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff *(msg->buffer) = st; /* rollback */
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->buffer->length += msg->reserved;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->counts[sectionid] += total;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff return (result);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff /*
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington * If we have rendered non-validated data,
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington * ensure that the AD bit is not set.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff */
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington if (rdataset->trust != dns_trust_secure &&
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff (sectionid == DNS_SECTION_ANSWER ||
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff sectionid == DNS_SECTION_AUTHORITY))
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->flags &= ~DNS_MESSAGEFLAG_AD;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence rdataset->attributes |=
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence DNS_RDATASETATTR_RENDERED;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next:
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff rdataset = next_rdataset;
d070219e016b292a49f6f8ccd8975bcc18e46e40Michael Graff }
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff name = next_name;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff }
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff } while (--pass != 0);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff msg->buffer->length += msg->reserved;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->counts[sectionid] += total;
823e45c1273512a8048cd5e7e57f31f58c964f7fMichael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) {
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff isc_uint16_t tmp;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_region_t r;
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(target != NULL);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_availableregion(target, &r);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_buffer_putuint16(target, msg->id);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT)
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff & DNS_MESSAGE_OPCODE_MASK);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley tmp |= (msg->rcode & DNS_MESSAGE_RCODE_MASK);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff tmp |= (msg->flags & DNS_MESSAGE_FLAG_MASK);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence msg->counts[DNS_SECTION_ANSWER] < 65536 &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence msg->counts[DNS_SECTION_AUTHORITY] < 65536 &&
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] < 65536);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_buffer_putuint16(target, tmp);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]);
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_buffer_putuint16(target,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington}
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderend(dns_message_t *msg) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_buffer_t tmpbuf;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington isc_region_t r;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington int result;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley unsigned int count;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(msg->buffer != NULL);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * We have an extended rcode but are not using EDNS.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (DNS_R_FORMERR);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * If we've got an OPT record, render it.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (msg->opt != NULL) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_message_renderrelease(msg, msg->opt_reserved);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Set the extended rcode.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->opt->ttl &= ~DNS_MESSAGE_EDNSRCODE_MASK;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->opt->ttl |= ((msg->rcode << 20) &
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley DNS_MESSAGE_EDNSRCODE_MASK);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Render.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley count = 0;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_rdataset_towire(msg->opt, dns_rootname,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington msg->cctx, msg->buffer, 0,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington &count);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->counts[DNS_SECTION_ADDITIONAL] += count;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (result != ISC_R_SUCCESS)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (result);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington /*
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a TSIG or SIG(0) to a truncated message,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * clear all rdatasets from the message except for the question
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington * before adding the TSIG or SIG(0). If the question doesn't fit,
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington * don't include it.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington */
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if ((msg->tsigkey != NULL || msg->sig0key != NULL) &&
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington (msg->flags & DNS_MESSAGEFLAG_TC) != 0)
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_buffer_t *buf;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msgresetnames(msg, DNS_SECTION_ANSWER);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington buf = msg->buffer;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_message_renderreset(msg);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->buffer = buf;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_buffer_clear(msg->buffer);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellington dns_compress_rollback(msg->cctx, 0);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington 0);
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington return (result);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington }
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington /*
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a TSIG record, generate and render it.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington */
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (msg->tsigkey != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 0;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington result = dns_tsig_sign(msg);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington return (result);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington count = 0;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_towire(msg->tsig, msg->tsigname,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington msg->cctx, msg->buffer, 0,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington &count);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] += count;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington }
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington /*
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a SIG(0) record, generate and render it.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington */
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->sig0key != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 0;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = dns_dnssec_signmessage(msg, msg->sig0key);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington count = 0;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington /*
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * Note: dns_rootname is used here, not msg->sig0name, since
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * the owner name of a SIG(0) is irrelevant, and will not
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * be set in a message being rendered.
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_towire(msg->sig0, dns_rootname,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington msg->cctx, msg->buffer, 0,
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington &count);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] += count;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (result != ISC_R_SUCCESS)
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington return (result);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_usedregion(msg->buffer, &r);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&tmpbuf, r.base, r.length);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington dns_message_renderheader(msg, &tmpbuf);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->buffer = NULL; /* forget about this buffer only on success XXX */
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halleyvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderreset(dns_message_t *msg) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley unsigned int i;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley dns_name_t *name;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley dns_rdataset_t *rds;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley /*
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Reset the message so that it may be rendered again.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley */
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
acb0311b113e3729dd1ac78dd14c51dc2c010393Mark Andrews msg->buffer = NULL;
acb0311b113e3729dd1ac78dd14c51dc2c010393Mark Andrews
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (i = 0; i < DNS_SECTION_MAX; i++) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley msg->cursors[i] = NULL;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley msg->counts[i] = 0;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (name = ISC_LIST_HEAD(msg->sections[i]);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley name != NULL;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley name = ISC_LIST_NEXT(name, link)) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (rds = ISC_LIST_HEAD(name->list);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rds != NULL;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rds = ISC_LIST_NEXT(rds, link)) {
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley rds->attributes &= ~DNS_RDATASETATTR_RENDERED;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley }
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington if (msg->tsigname != NULL)
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_message_puttempname(msg, &msg->tsigname);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington if (msg->tsig != NULL) {
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_rdataset_disassociate(msg->tsig);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_message_puttemprdataset(msg, &msg->tsig);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington }
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington if (msg->sig0 != NULL) {
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_rdataset_disassociate(msg->sig0);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_message_puttemprdataset(msg, &msg->sig0);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington }
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley}
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_firstname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msg->cursors[section] == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMORE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_nextname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->cursors[section] != NULL);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msg->cursors[section] == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMORE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_currentname(dns_message_t *msg, dns_section_t section,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_name_t **name)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff REQUIRE(name != NULL && *name == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->cursors[section] != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff *name = msg->cursors[section];
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_findname(dns_message_t *msg, dns_section_t section,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_name_t *target, dns_rdatatype_t type,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdatatype_t covers, dns_name_t **name,
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley dns_rdataset_t **rdataset)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff dns_name_t *foundname;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * XXX These requirements are probably too intensive, especially
f9df80f4348ef68043903efa08299480324f4823Michael Graff * where things can be NULL, but as they are they ensure that if
f9df80f4348ef68043903efa08299480324f4823Michael Graff * something is NON-NULL, indicating that the caller expects it
f9df80f4348ef68043903efa08299480324f4823Michael Graff * to be filled in, that we can in fact fill it in.
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(target != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (name != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(*name == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (type == dns_rdatatype_any) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(rdataset == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff } else {
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (rdataset != NULL)
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(*rdataset == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff }
f9df80f4348ef68043903efa08299480324f4823Michael Graff
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = findname(&foundname, target,
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson &msg->sections[section]);
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOTFOUND)
a920f559c3689f52731519a9d5169ad5814866edMichael Graff return (DNS_R_NXDOMAIN);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff else if (result != ISC_R_SUCCESS)
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff return (result);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff if (name != NULL)
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff *name = foundname;
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff /*
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff * And now look for the type.
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff */
08d94b539a96857670540342df4d81ea55348d03Michael Graff if (type == dns_rdatatype_any)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(foundname, type, covers, rdataset);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result == ISC_R_NOTFOUND)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (DNS_R_NXRRSET);
a920f559c3689f52731519a9d5169ad5814866edMichael Graff
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff return (result);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_movename(dns_message_t *msg, dns_name_t *name,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_section_t fromsection,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_section_t tosection)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(name != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(fromsection));
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(tosection));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff /*
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Unlink the name from the old section
f9df80f4348ef68043903efa08299480324f4823Michael Graff */
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(msg->sections[tosection], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graffvoid
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_addname(dns_message_t *msg, dns_name_t *name,
f9df80f4348ef68043903efa08299480324f4823Michael Graff dns_section_t section)
f9df80f4348ef68043903efa08299480324f4823Michael Graff{
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg != NULL);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(name != NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(VALID_NAMED_SECTION(section));
f9df80f4348ef68043903efa08299480324f4823Michael Graff
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(msg->sections[section], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff *item = isc_mempool_get(msg->namepool);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
fc0d37fa3a50c494e37fbed170f5d53e12778e2cBrian Wellington dns_name_init(*item, NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtonisc_result_t
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtondns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington REQUIRE(item != NULL && *item == NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington *item = newoffsets(msg);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (*item == NULL)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (ISC_R_NOMEMORY);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington return (ISC_R_SUCCESS);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff}
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = newrdata(msg);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff *item = isc_mempool_get(msg->rdspool);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
499371d17c34a5770af022f4aa15e764e957a803Michael Graff dns_rdataset_init(*item);
499371d17c34a5770af022f4aa15e764e957a803Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item == NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = newrdatalist(msg);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff if (*item == NULL)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_NOMEMORY);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtonvoid
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtondns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington REQUIRE(item != NULL && *item != NULL);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington if (dns_name_dynamic(*item))
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_name_free(*item, msg->mctx);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington isc_mempool_put(msg->namepool, *item);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington *item = NULL;
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington}
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff releaserdata(msg, *item);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = NULL;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff REQUIRE(!dns_rdataset_isassociated(*item));
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_put(msg->rdspool, *item);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = NULL;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff REQUIRE(item != NULL && *item != NULL);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff releaserdatalist(msg, *item);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff *item = NULL;
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff}
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graffdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff unsigned int *flagsp)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff{
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff isc_region_t r;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff isc_buffer_t buffer;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff dns_messageid_t id;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff unsigned int flags;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff REQUIRE(source != NULL);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff buffer = *source;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_remainingregion(&buffer, &r);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (r.length < DNS_MESSAGE_HEADERLEN)
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_UNEXPECTEDEND);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
5039f2cad30410b47330c14c0d7ce4ca493a8712Michael Graff id = isc_buffer_getuint16(&buffer);
5039f2cad30410b47330c14c0d7ce4ca493a8712Michael Graff flags = isc_buffer_getuint16(&buffer);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff flags &= DNS_MESSAGE_FLAG_MASK;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (flagsp != NULL)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff *flagsp = flags;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff if (idp != NULL)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff *idp = id;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff}
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley unsigned int first_section;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if (!msg->header_ok)
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley return (DNS_R_FORMERR);
271154eafd1111455030abc2997120228be55ef9Mark Andrews if (msg->opcode != dns_opcode_query &&
271154eafd1111455030abc2997120228be55ef9Mark Andrews msg->opcode != dns_opcode_notify)
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley want_question_section = ISC_FALSE;
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley if (want_question_section) {
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley if (!msg->question_ok)
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley return (DNS_R_FORMERR);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley first_section = DNS_SECTION_ANSWER;
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley } else
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley first_section = DNS_SECTION_QUESTION;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msgresetnames(msg, first_section);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msgresetopt(msg);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msgresetsigs(msg, ISC_TRUE);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msginitprivate(msg);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley /*
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * We now clear most flags and then set QR, ensuring that the
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * reply's flags will be in a reasonable state.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley */
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->flags &= DNS_MESSAGE_REPLYPRESERVE;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->flags |= DNS_MESSAGEFLAG_QR;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * This saves the query TSIG status, if the query was signed, and
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * reserves space in the reply for the TSIG.
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington */
230aff0eac2d6694c6ca5925b663789e68f267c9Brian Wellington if (msg->tsigkey != NULL) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int otherlen = 0;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington msg->querytsigstatus = msg->tsigstatus;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian 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 }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington }
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington if (msg->saved.base != NULL) {
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->query.base = msg->saved.base;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->query.length = msg->saved.length;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->free_query = msg->free_saved;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->saved.base = NULL;
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington msg->saved.length = 0;
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->free_saved = 0;
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington }
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley}
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_rdataset_t *
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_getopt(dns_message_t *msg) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Get the OPT record for 'msg'.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley return (msg->opt);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley}
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffisc_result_t
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff isc_result_t result;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Set the OPT record for 'msg'.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley /*
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * The space required for an OPT record is:
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley *
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 1 byte for the name
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 2 bytes for the type
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 2 bytes for the class
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 4 bytes for the ttl
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 2 bytes for the rdata length
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * ---------------------------------
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * 11 bytes
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley *
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * plus the length of the rdata.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(DNS_MESSAGE_VALID(msg));
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(opt->type == dns_rdatatype_opt);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->state == DNS_SECTION_ANY);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msgresetopt(msg);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_rdataset_first(opt);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (result != ISC_R_SUCCESS)
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson goto cleanup;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley dns_rdataset_current(opt, &rdata);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 11 + rdata.length;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley result = dns_message_renderreserve(msg, msg->opt_reserved);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley if (result != ISC_R_SUCCESS) {
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley msg->opt_reserved = 0;
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson goto cleanup;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley }
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley msg->opt = opt;
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_R_SUCCESS);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson cleanup:
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson dns_message_puttemprdataset(msg, &opt);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson return (result);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley}
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_rdataset_t *
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Get the TSIG record and owner for 'msg'.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington REQUIRE(owner == NULL || *owner == NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington if (owner != NULL)
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington *owner = msg->tsigname;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington return (msg->tsig);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington /*
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington * Set the TSIG key for 'msg'
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington */
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(msg->state == DNS_SECTION_ANY);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (key != NULL) {
97527fc03cdb061759e2c9529c670ac1c190ef84Brian Wellington REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington dns_tsigkey_attach(key, &msg->tsigkey);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = spacefortsig(msg->tsigkey, 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_renderreserve(msg,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS) {
97527fc03cdb061759e2c9529c670ac1c190ef84Brian Wellington dns_tsigkey_detach(&msg->tsigkey);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington}
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_tsigkey_t *
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_message_gettsigkey(dns_message_t *msg) {
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington /*
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington * Get the TSIG key for 'msg'
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington */
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington return (msg->tsigkey);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington}
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_t *rdata = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdatalist_t *list = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdataset_t *set = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_t *buf = NULL;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_region_t r;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington REQUIRE(msg->querytsig == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (querytsig == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_gettemprdata(msg, &rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington goto cleanup;
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_gettemprdatalist(msg, &list);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington goto cleanup;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_gettemprdataset(msg, &set);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington goto cleanup;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_usedregion(querytsig, &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = isc_buffer_allocate(msg->mctx, &buf, r.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington goto cleanup;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_putmem(buf, r.base, r.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_usedregion(buf, &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_init(rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_takebuffer(msg, &buf);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ISC_LIST_INIT(list->rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ISC_LIST_APPEND(list->rdata, rdata, link);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_rdatalist_tordataset(list, set);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington goto cleanup;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington msg->querytsig = set;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington cleanup:
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (rdata != NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_puttemprdata(msg, &rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (list != NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_puttemprdatalist(msg, &list);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (set != NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_puttemprdataset(msg, &set);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_NOMEMORY);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_t **querytsig) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_region_t r;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(mctx != NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(querytsig != NULL && *querytsig == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->tsig == NULL)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_first(msg->tsig);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_rdataset_current(msg->tsig, &rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_toregion(&rdata, &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = isc_buffer_allocate(mctx, querytsig, r.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_putmem(*querytsig, r.base, r.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_rdataset_t *
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellingtondns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington /*
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Get the SIG(0) record for 'msg'.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington */
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington REQUIRE(owner == NULL || *owner == NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington if (msg->sig0 != NULL && owner != NULL) {
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington /* If dns_message_getsig0 is called on a rendered message
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * after the SIG(0) has been applied, we need to return the
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * root name, not NULL.
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington */
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington if (msg->sig0name == NULL)
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington *owner = dns_rootname;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington else
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington *owner = msg->sig0name;
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington }
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellington return (msg->sig0);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington}
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonisc_result_t
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_setsig0key(dns_message_t *msg, dst_key_t *key) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_region_t r;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int x;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_result_t result;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Set the SIG(0) key for 'msg'
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * The space required for an SIG(0) record is:
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington *
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 1 byte for the name
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the type
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the class
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 4 bytes for the ttl
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the type covered
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 1 byte for the algorithm
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 1 bytes for the labels
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 4 bytes for the original ttl
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 4 bytes for the signature expiration
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 4 bytes for the signature inception
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 2 bytes for the key tag
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * n bytes for the signer's name
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * x bytes for the signature
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * ---------------------------------
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * 27 + n + x bytes
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(msg->state == DNS_SECTION_ANY);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (key != NULL) {
97527fc03cdb061759e2c9529c670ac1c190ef84Brian Wellington REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_name_toregion(dst_key_name(key), &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dst_key_sigsize(key, &x);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (result != ISC_R_SUCCESS) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 0;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (result);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = 27 + r.length + x;
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 }
97527fc03cdb061759e2c9529c670ac1c190ef84Brian Wellington msg->sig0key = key;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington }
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (ISC_R_SUCCESS);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondst_key_t *
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_getsig0key(dns_message_t *msg) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington /*
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Get the SIG(0) key for 'msg'
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington */
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington return (msg->sig0key);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington}
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graffvoid
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(DNS_MESSAGE_VALID(msg));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(buffer != NULL);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff REQUIRE(ISC_BUFFER_VALID(*buffer));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_APPEND(msg->cleanup, *buffer, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff *buffer = NULL;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff}
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellingtonisc_result_t
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellingtondns_message_signer(dns_message_t *msg, dns_name_t *signer) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_result_t result = ISC_R_SUCCESS;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington REQUIRE(signer != NULL);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->tsig == NULL && msg->sig0 == NULL)
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington return (ISC_R_NOTFOUND);
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->verify_attempted == 0)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington return (DNS_R_NOTVERIFIEDYET);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (!dns_name_hasbuffer(signer)) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington isc_buffer_t *dynbuf = NULL;
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_setbuffer(signer, dynbuf);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_message_takebuffer(msg, &dynbuf);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->sig0 != NULL) {
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews dns_rdata_sig_t sig;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_first(msg->sig0);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(result == ISC_R_SUCCESS);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_rdataset_current(msg->sig0, &rdata);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_rdata_tostruct(&rdata, &sig, NULL);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington if (result != ISC_R_SUCCESS)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington return (result);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = ISC_R_SUCCESS;
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington else
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington result = DNS_R_SIGINVALID;
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington dns_name_clone(&sig.signer, signer);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_rdata_freestruct(&sig);
b1a7fea53cb35baf4ca0c6841dce20ef1f90f259Andreas Gustafsson } else {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington dns_name_t *identity;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_any_tsig_t tsig;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_first(msg->tsig);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington INSIST(result == ISC_R_SUCCESS);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington dns_rdataset_current(msg->tsig, &rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_rdata_tostruct(&rdata, &tsig, NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->tsigstatus != dns_rcode_noerror)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_TSIGVERIFYFAILURE;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington else if (tsig.error != dns_rcode_noerror)
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_TSIGERRORSET;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington else
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = ISC_R_SUCCESS;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_freestruct(&tsig);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (msg->tsigkey == NULL) {
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington /*
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington * If msg->tsigstatus & tsig.error are both
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington * dns_rcode_noerror, the message must have been
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington * verified, which means msg->tsigkey will be
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington * non-NULL.
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington */
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington INSIST(result != ISC_R_SUCCESS);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington } else {
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington identity = dns_tsigkey_identity(msg->tsigkey);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (identity == NULL) {
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (result == ISC_R_SUCCESS)
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington result = DNS_R_NOIDENTITY;
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington identity = &msg->tsigkey->name;
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington }
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington dns_name_clone(identity, signer);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington
06f9d6486eab16895ab1538f5530445cb665ba9cBrian Wellington return (result);
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington}
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
880723fb130841459d45695b387651cacd6c9bb8Mark Andrewsvoid
880723fb130841459d45695b387651cacd6c9bb8Mark Andrewsdns_message_resetsig(dns_message_t *msg) {
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews msg->verified_sig = 0;
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews msg->verify_attempted = 0;
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews msg->tsigstatus = dns_rcode_noerror;
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews msg->sig0status = dns_rcode_noerror;
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews msg->timeadjust = 0;
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews if (msg->tsigkey != NULL) {
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews dns_tsigkey_detach(&msg->tsigkey);
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews msg->tsigkey = NULL;
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews }
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews}
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews
880723fb130841459d45695b387651cacd6c9bb8Mark Andrewsisc_result_t
880723fb130841459d45695b387651cacd6c9bb8Mark Andrewsdns_message_rechecksig(dns_message_t *msg, dns_view_t *view) {
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews dns_message_resetsig(msg);
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews return (dns_message_checksig(msg, view));
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews}
880723fb130841459d45695b387651cacd6c9bb8Mark Andrews
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtonisc_result_t
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtondns_message_checksig(dns_message_t *msg, dns_view_t *view) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_t b, msgb;
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington REQUIRE(DNS_MESSAGE_VALID(msg));
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL)
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington return (ISC_R_SUCCESS);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington INSIST(msg->saved.base != NULL);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington isc_buffer_add(&msgb, msg->saved.length);
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington if (msg->tsigkey != NULL || msg->tsig != NULL) {
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington if (view != NULL)
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington return (dns_view_checksig(view, &msgb, msg));
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington else
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington return (dns_tsig_verify(&msgb, msg, NULL, NULL));
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington } else {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews dns_rdata_t rdata = DNS_RDATA_INIT;
b8dd48ecf83142f6ee7238cbd68fec455e527fc8Mark Andrews dns_rdata_sig_t sig;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_t keyset;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_result_t result;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_first(msg->sig0);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(result == ISC_R_SUCCESS);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_current(msg->sig0, &rdata);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
81b438273a0c3141144d169a7ccb110150757337Brian Wellington /*
81b438273a0c3141144d169a7ccb110150757337Brian Wellington * This can occur when the message is a dynamic update, since
81b438273a0c3141144d169a7ccb110150757337Brian Wellington * the rdata length checking is relaxed. This should not
81b438273a0c3141144d169a7ccb110150757337Brian Wellington * happen in a well-formed message, since the SIG(0) is only
81b438273a0c3141144d169a7ccb110150757337Brian Wellington * looked for in the additional section, and the dynamic update
81b438273a0c3141144d169a7ccb110150757337Brian Wellington * meta-records are in the prerequisite and update sections.
81b438273a0c3141144d169a7ccb110150757337Brian Wellington */
c637772ac34b4abb76a250eca89930e6f2bc2ce9Brian Wellington if (rdata.length == 0)
c637772ac34b4abb76a250eca89930e6f2bc2ce9Brian Wellington return (ISC_R_UNEXPECTEDEND);
81b438273a0c3141144d169a7ccb110150757337Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_init(&keyset);
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington if (view == NULL)
930ecd3756ce0a2f9d9a48a0c6eb98f4a4375824Brian Wellington return (DNS_R_KEYUNAUTHORIZED);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_view_simplefind(view, &sig.signer,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews dns_rdatatype_key /* SIG(0) */,
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews 0, 0, ISC_FALSE, &keyset, NULL);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /* XXXBEW Should possibly create a fetch here */
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = DNS_R_KEYUNAUTHORIZED;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto freesig;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington } else if (keyset.trust < dns_trust_secure) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /* XXXBEW Should call a validator here */
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = DNS_R_KEYUNAUTHORIZED;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington goto freesig;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_first(&keyset);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington INSIST(result == ISC_R_SUCCESS);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington for (;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result == ISC_R_SUCCESS;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdataset_next(&keyset))
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_t *key = NULL;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdataset_current(&keyset, &rdata);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&b, rdata.data, rdata.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_add(&b, rdata.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington result = dst_key_fromdns(&sig.signer, rdata.rdclass,
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington &b, view->mctx, &key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result != ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington continue;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (dst_key_alg(key) != sig.algorithm ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_id(key) != sig.keyid ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dst_key_proto(key) == DNS_KEYPROTO_ANY))
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington {
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington dst_key_free(&key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington continue;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_dnssec_verifymessage(&msgb, msg, key);
c50936eb40263b65ebf6afe4e6556e2dc67c10e4Brian Wellington dst_key_free(&key);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result == ISC_R_SUCCESS)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington break;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington if (result == ISC_R_NOMORE)
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = DNS_R_KEYUNAUTHORIZED;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington freesig:
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington if (dns_rdataset_isassociated(&keyset))
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington dns_rdataset_disassociate(&keyset);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_freestruct(&sig);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington return (result);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington }
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerisc_result_t
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington const dns_master_style_t *style,
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer dns_messagetextflag_t flags,
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_buffer_t *target) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_t *name, empty_name;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_rdataset_t *rdataset;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_result_t result;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(target != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(VALID_SECTION(section));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (ISC_LIST_EMPTY(msg->sections[section]))
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff return (ISC_R_SUCCESS);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ");
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer if (msg->opcode != dns_opcode_update) {
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer ADD_STRING(target, sectiontext[section]);
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer }
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer else {
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer ADD_STRING(target, updsectiontext[section]);
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, " SECTION:\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_name_init(&empty_name, NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_firstname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result != ISC_R_SUCCESS) {
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer do {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer name = NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_message_currentname(msg, section, &name);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer for (rdataset = ISC_LIST_HEAD(name->list);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer rdataset != NULL;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer rdataset = ISC_LIST_NEXT(rdataset, link)) {
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson if (section == DNS_SECTION_QUESTION) {
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington ADD_STRING(target, ";");
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson result = dns_master_questiontotext(name,
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson rdataset,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style,
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson target);
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson } else {
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson result = dns_master_rdatasettotext(name,
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson rdataset,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style,
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson target);
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson }
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington if (result != ISC_R_SUCCESS)
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_nextname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer } while (result == ISC_R_SUCCESS);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
194de894f0697562f94e048f573d99260a18a639Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result == ISC_R_NOMORE)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = ISC_R_SUCCESS;
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerisc_result_t
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_pseudosectiontotext(dns_message_t *msg,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_pseudosection_t section,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington const dns_master_style_t *style,
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer dns_messagetextflag_t flags,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer isc_buffer_t *target) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_rdataset_t *ps = NULL;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_name_t *name = NULL;
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer isc_result_t result;
90ad126bb363ad419b1348dea2b8613b21b4ded8Andreas Gustafsson char buf[sizeof("1234567890")];
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews isc_uint32_t mbz;
8db2b65318b72e3ee477d6f6a346b525dd2db53aAndreas Gustafsson
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(target != NULL);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(VALID_PSEUDOSECTION(section));
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer switch (section) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer case DNS_PSEUDOSECTION_OPT:
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer ps = dns_message_getopt(msg);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (ps == NULL)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (ISC_R_SUCCESS);
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, "; EDNS: version: ");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews snprintf(buf, sizeof(buf), "%u",
a207a2835e37de52e11d4c143c0425e749409c46Mark Andrews (unsigned int)((ps->ttl & 0x00ff0000) >> 16));
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, buf);
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, ", flags:");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0)
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, " do");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews mbz = ps->ttl & ~DNS_MESSAGEEXTFLAG_DO & 0xffff;
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews if (mbz != 0) {
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, "; MBZ: ");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews snprintf(buf, sizeof(buf), "%.4x ", mbz);
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, buf);
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, ", udp: ");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews } else
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, "; udp: ");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, buf);
9066d09c3ef804b997945d34c709e4d2a72d7318Andreas Gustafsson return (ISC_R_SUCCESS);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer case DNS_PSEUDOSECTION_TSIG:
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer ps = dns_message_gettsig(msg, &name);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (ps == NULL)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (ISC_R_SUCCESS);
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer ADD_STRING(target, ";; TSIG PSEUDOSECTION:\n");
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington result = dns_master_rdatasettotext(name, ps, style, target);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer ADD_STRING(target, "\n");
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer case DNS_PSEUDOSECTION_SIG0:
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington ps = dns_message_getsig0(msg, &name);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (ps == NULL)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (ISC_R_SUCCESS);
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer ADD_STRING(target, ";; SIG0 PSEUDOSECTION:\n");
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington result = dns_master_rdatasettotext(name, ps, style, target);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
194de894f0697562f94e048f573d99260a18a639Michael Sawyer ADD_STRING(target, "\n");
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer }
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (ISC_R_UNEXPECTED);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerisc_result_t
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellingtondns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington dns_messagetextflag_t flags, isc_buffer_t *target) {
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson char buf[sizeof("1234567890")];
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer isc_result_t result;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(target != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, opcodetext[msg->opcode]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", status: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, rcodetext[msg->rcode]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", id: ");
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews snprintf(buf, sizeof(buf), "%6u", msg->id);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n;; flags: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "qr ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "aa ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "tc ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "rd ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "ra ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "ad ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "cd ");
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer if (msg->opcode != dns_opcode_update) {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, "; QUESTION: ");
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff } else {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, "; ZONE: ");
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer }
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews snprintf(buf, sizeof(buf), "%1u",
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews msg->counts[DNS_SECTION_QUESTION]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer if (msg->opcode != dns_opcode_update) {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, ", ANSWER: ");
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff } else {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, ", PREREQ: ");
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer }
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews snprintf(buf, sizeof(buf), "%1u",
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews msg->counts[DNS_SECTION_ANSWER]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer if (msg->opcode != dns_opcode_update) {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, ", AUTHORITY: ");
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff } else {
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, ", UPDATE: ");
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer }
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews snprintf(buf, sizeof(buf), "%1u",
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews msg->counts[DNS_SECTION_AUTHORITY]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", ADDITIONAL: ");
cc083bb7031c04d57cbad41b2f5a796a4fd1865cMark Andrews snprintf(buf, sizeof(buf), "%1u",
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews msg->counts[DNS_SECTION_ADDITIONAL]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, "\n");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_pseudosectiontotext(msg,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer DNS_PSEUDOSECTION_OPT,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_pseudosectiontotext(msg,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer DNS_PSEUDOSECTION_TSIG,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_pseudosectiontotext(msg,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer DNS_PSEUDOSECTION_SIG0,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington style, flags, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (result != ISC_R_SUCCESS)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington return (ISC_R_SUCCESS);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrewsisc_region_t *
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrewsdns_message_getrawmessage(dns_message_t *msg) {
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington return (&msg->saved);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews}
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafssonvoid
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafssondns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson void *order_arg)
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson{
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson msg->order = order;
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson msg->order_arg = order_arg;
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson}
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrewsvoid
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrewsdns_message_settimeadjust(dns_message_t *msg, int timeadjust) {
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews msg->timeadjust = timeadjust;
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews}
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrewsint
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrewsdns_message_gettimeadjust(dns_message_t *msg) {
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews return (msg->timeadjust);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews}
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrewsisc_result_t
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrewsdns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) {
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews REQUIRE(opcode < 16);
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews if (isc_buffer_availablelength(target) < strlen(opcodetext[opcode]))
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews return (ISC_R_NOSPACE);
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews isc_buffer_putstr(target, opcodetext[opcode]);
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews return (ISC_R_SUCCESS);
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews}