9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/*
3b7f610bec248f85e25a52a0ad7dec9894389ca5Tinderbox User * Copyright (C) 1999-2017 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * This Source Code Form is subject to the terms of the Mozilla Public
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * License, v. 2.0. If a copy of the MPL was not distributed with this
0c27b3fe77ac1d5094ba3521e8142d9e7973133fMark Andrews * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*! \file */
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff/***
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff *** Imports
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ***/
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <config.h>
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews#include <ctype.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>
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews#include <dns/rcode.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>
6cba0b8e61859e37cbf16818cc95ba1da85d68fdEvan Hunt#include <dns/ttl.h>
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington#include <dns/view.h>
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#ifdef SKAN_MSG_DEBUG
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsstatic void
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshexdump(const char *msg, const char *msg2, void *base, size_t len) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char *p;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned int cnt;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews p = base;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews cnt = 0;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews while (cnt < len) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (cnt % 16 == 0)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf("%p: ", p);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews else if (cnt % 8 == 0)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf(" |");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf(" %02x %c", *p, (isprint(*p) ? *p : ' '));
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews p++;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews cnt++;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (cnt % 16 == 0)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf("\n");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (cnt % 16 != 0)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf("\n");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#endif
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
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) >= \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_availablelength(b)) { \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_NOSPACE; \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup; \
2a2618356ecdf5962230fe11606d2b106a638295Tinderbox User } 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
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
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
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman#define NAME_COUNT 64
be066f0629a12e11bc17f27671036b3f451bd5eaBrian Wellington#define OFFSET_COUNT 4
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATA_COUNT 8
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff#define RDATALIST_COUNT 8
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman#define RDATASET_COUNT 64
f9df80f4348ef68043903efa08299480324f4823Michael Graff
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
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
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein/*%
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
47b7dfffe5d806c6a5e99ef17f07bcde812c2132Francis Dupont * size, or the allocated elements will not be aligned 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
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewsstatic void
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewslogfmtpacket(dns_message_t *message, const char *description,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_sockaddr_t *address, isc_logcategory_t *category,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_logmodule_t *module, const dns_master_style_t *style,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews int level, isc_mem_t *mctx);
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
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);
29d52c001ff976561669375cf0c866b815a90c49Mark Andrews goto out;
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 }
29d52c001ff976561669375cf0c866b815a90c49Mark Andrews out:
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrews if (rdatalist != NULL)
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrews dns_rdatalist_init(rdatalist);
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;
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews m->cc_ok = 0;
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews m->cc_bad = 0;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews m->tkey = 0;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews m->rdclass_set = 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;
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews msg->cc_ok = 0;
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews msg->cc_bad = 0;
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
481e9b573b8233f8678c1dd4549c8c949312e81dMark Andrews if (msg->tsigctx != NULL)
481e9b573b8233f8678c1dd4549c8c949312e81dMark Andrews dst_context_destroy(&msg->tsigctx);
481e9b573b8233f8678c1dd4549c8c949312e81dMark Andrews
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]);
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt m->mctx = NULL;
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt isc_mem_attach(mctx, &m->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;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman isc_mempool_setfillcount(m->namepool, NAME_COUNT);
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;
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman isc_mempool_setfillcount(m->rdspool, RDATASET_COUNT);
16f43564c6875e2bedd346c18c494933ad51e4faMukund Sivaraman isc_mempool_setfreemax(m->rdspool, RDATASET_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;
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt isc_mem_putanddetach(&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;
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt isc_mem_putanddetach(&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
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrewsisc_result_t
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrewsdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews dns_rdatatype_t type, dns_rdatatype_t covers,
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews dns_rdataset_t **rdataset)
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews{
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews dns_rdataset_t *curr;
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(name != NULL);
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(rdataset == NULL || *rdataset == NULL);
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews for (curr = ISC_LIST_TAIL(name->list);
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews curr != NULL;
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews curr = ISC_LIST_PREV(curr, link)) {
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews if (curr->rdclass == rdclass &&
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews curr->type == type && curr->covers == covers) {
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews if (rdataset != NULL)
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews *rdataset = curr;
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews return (ISC_R_SUCCESS);
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews }
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews }
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews return (ISC_R_NOTFOUND);
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews}
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews
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
2674e1a455d4f71de09b2b60e7a8304b9a305588Mark Andrews REQUIRE(name != NULL);
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(rdataset == NULL || *rdataset == NULL);
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) {
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman if (ISC_UNLIKELY(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
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews#define DO_ERROR(r) \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington do { \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (best_effort) \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington seen_problem = ISC_TRUE; \
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington else { \
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews result = r; \
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;
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater
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))
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_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 */
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews if (msg->rdclass_set == 0) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->rdclass = rdclass;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass_set = 1;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } else if (msg->rdclass != rdclass)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_FORMERR);
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews /*
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews * Is this a TKEY query?
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews */
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews if (rdtype == dns_rdatatype_tkey)
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->tkey = 1;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /*
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Can't ask the same question twice.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff */
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews result = dns_message_find(name, rdclass, rdtype, 0, NULL);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington if (result == ISC_R_SUCCESS)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_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;
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdatalist->rdclass = rdclass;
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
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews/*
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * covering RRSIGs.
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews */
2595d1da358cc7391e001894d45471509976e7d5Mark Andrewsstatic isc_boolean_t
2595d1da358cc7391e001894d45471509976e7d5Mark Andrewsauth_signed(dns_namelist_t *section) {
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews dns_name_t *name;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews for (name = ISC_LIST_HEAD(*section);
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews name != NULL;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews name = ISC_LIST_NEXT(name, link))
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews {
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews int auth_dnssec = 0, auth_rrsig = 0;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews dns_rdataset_t *rds;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews for (rds = ISC_LIST_HEAD(name->list);
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews rds != NULL;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews rds = ISC_LIST_NEXT(rds, link))
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews {
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews switch (rds->type) {
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_ds:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews auth_dnssec |= 0x1;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_nsec:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews auth_dnssec |= 0x2;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_nsec3:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews auth_dnssec |= 0x4;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_rrsig:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews default:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews continue;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews }
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews switch (rds->covers) {
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_ds:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews auth_rrsig |= 0x1;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_nsec:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews auth_rrsig |= 0x2;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews case dns_rdatatype_nsec3:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews auth_rrsig |= 0x4;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews default:
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews break;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews }
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews }
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews if (auth_dnssec != auth_rrsig)
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews return (ISC_FALSE);
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews }
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews return (ISC_TRUE);
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews}
2595d1da358cc7391e001894d45471509976e7d5Mark 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;
7fa388dac3ff85315ced069f657bbebfc0828df8Evan Hunt dns_name_t *name = NULL;
7fa388dac3ff85315ced069f657bbebfc0828df8Evan Hunt dns_name_t *name2 = NULL;
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;
7fa388dac3ff85315ced069f657bbebfc0828df8Evan Hunt isc_boolean_t free_name = ISC_FALSE, free_rdataset = ISC_FALSE;
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
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews section = &msg->sections[sectionid];
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
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
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_name_search = ISC_FALSE;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley skip_type_search = 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 */
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews if (msg->rdclass_set == 0 &&
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;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass_set = 1;
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
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews && rdtype != dns_rdatatype_key /* in a TKEY query */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_sig /* SIG(0) */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews && msg->rdclass != dns_rdataclass_any
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington && msg->rdclass != rdclass)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_FORMERR);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews /*
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews * If this is not a TKEY query/response then the KEY
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews * record's class needs to match.
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews */
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews if (msg->opcode != dns_opcode_update && !msg->tkey &&
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews rdtype == dns_rdatatype_key &&
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass != dns_rdataclass_any &&
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass != rdclass)
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews DO_ERROR(DNS_R_FORMERR);
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews
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)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_BADTSIG);
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) ||
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews sectionid != DNS_SECTION_ADDITIONAL ||
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->opt != NULL)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_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)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_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
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater * 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;
5059b393e80cda6beffb74f2f30d7329502c41e6Mark Andrews } else if (rdclass == dns_rdataclass_none &&
5059b393e80cda6beffb74f2f30d7329502c41e6Mark Andrews msg->opcode == dns_opcode_update &&
5059b393e80cda6beffb74f2f30d7329502c41e6Mark Andrews sectionid == DNS_SECTION_UPDATE) {
5059b393e80cda6beffb74f2f30d7329502c41e6Mark Andrews result = getrdata(source, msg, dctx, msg->rdclass,
5059b393e80cda6beffb74f2f30d7329502c41e6Mark Andrews rdtype, rdatalen, rdata);
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews } else
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence result = getrdata(source, msg, dctx, rdclass,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence rdtype, rdatalen, rdata);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (result != ISC_R_SUCCESS)
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff goto cleanup;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley rdata->rdclass = rdclass;
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews issigzero = ISC_FALSE;
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews if (rdtype == dns_rdatatype_rrsig &&
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews rdata->flags == 0) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley covers = dns_rdata_covers(rdata);
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews if (covers == 0)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_FORMERR);
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews rdata->flags == 0) {
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews covers = dns_rdata_covers(rdata);
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews if (covers == 0) {
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (sectionid != DNS_SECTION_ADDITIONAL ||
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington count != msg->counts[sectionid] - 1)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_BADSIG0);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington msg->sigstart = recstart;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington skip_name_search = ISC_TRUE;
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington skip_type_search = ISC_TRUE;
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington issigzero = ISC_TRUE;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews } else {
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews if (msg->rdclass != dns_rdataclass_any &&
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass != rdclass)
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews DO_ERROR(DNS_R_FORMERR);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington }
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews } else
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews covers = 0;
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews /*
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews * Check the ownername of NSEC3 records
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews */
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews if (rdtype == dns_rdatatype_nsec3 &&
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews !dns_rdata_checkowner(name, msg->rdclass, rdtype,
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews ISC_FALSE)) {
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews result = DNS_R_BADOWNERNAME;
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews goto cleanup;
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews }
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews
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))
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_FORMERR);
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff rdataset = NULL;
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews result = dns_message_find(name, rdclass, rdtype,
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews covers, &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) {
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews if (dns_rdatatype_issingleton(rdtype)) {
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews dns_rdata_t *first;
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews dns_rdatalist_fromrdataset(rdataset,
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews &rdatalist);
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews first = ISC_LIST_HEAD(rdatalist->rdata);
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews INSIST(first != NULL);
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews if (dns_rdata_compare(rdata, first) != 0)
8475bed9de77920f884f1ae296f581efbd1e42f8Mark Andrews DO_ERROR(DNS_R_FORMERR);
c9cecf7bb509b1c860d0b6deba7fccd85b9feb68Mark Andrews }
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;
e223094b2248afa2697c531f75e6f84855638becMichael Graff
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdataset_init(rdataset);
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson rdataset)
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson == ISC_R_SUCCESS);
a8da00ef95ba37b9d071c2b8db1a0c967e060106Mark Andrews dns_rdataset_setownercase(rdataset, name);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff
2f012d936b5ccdf6520c96a4de23721dc58a2221Automatic Updater 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 *
ab023a65562e62b85a824509d829b6fad87e00b1Rob Austein * Section 5.2 of RFC2181 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
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews /* Append this rdata to the rdataset. */
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews dns_rdatalist_fromrdataset(rdataset, &rdatalist);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff /*
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews * If this is an OPT, SIG(0) or TSIG record, remember it.
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews * Also, set the extended rcode for TSIG.
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews *
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews * Note msg->opt, msg->sig0 and msg->tsig will only be
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews * already set if best-effort parsing is enabled otherwise
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews * there will only be at most one of each.
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;
f43e5c8ed2e68b7064c909b1fece6d976799b8dbMark Andrews } else 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;
c19f322914f380404b613fbb31f5ac2582098f9dMark Andrews /* Windows doesn't like TSIG names to be compressed. */
c19f322914f380404b613fbb31f5ac2582098f9dMark Andrews msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington rdataset = NULL;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_rdataset = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington free_name = ISC_FALSE;
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington }
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews if (seen_problem) {
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews if (free_name)
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews isc_mempool_put(msg->namepool, name);
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews if (free_rdataset)
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews isc_mempool_put(msg->rdspool, rdataset);
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews free_name = free_rdataset = ISC_FALSE;
2fa0485e9e969dd42dd10339354d7949db46111aMark Andrews }
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff INSIST(free_name == ISC_FALSE);
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff INSIST(free_rdataset == ISC_FALSE);
e223094b2248afa2697c531f75e6f84855638becMichael Graff }
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews /*
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * If any of DS, NSEC or NSEC3 appeared in the
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * authority section of a query response without
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * a covering RRSIG, FORMERR
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews */
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews if (sectionid == DNS_SECTION_AUTHORITY &&
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews msg->opcode == dns_opcode_query &&
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews ((msg->flags & DNS_MESSAGEFLAG_QR) != 0) &&
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews ((msg->flags & DNS_MESSAGEFLAG_TC) == 0) &&
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews !preserve_order &&
2a2618356ecdf5962230fe11606d2b106a638295Tinderbox User !auth_signed(section))
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews DO_ERROR(DNS_R_FORMERR);
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews
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;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->state = DNS_SECTION_QUESTION;
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);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(msg->saved.base, isc_buffer_base(&origsource),
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt 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
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews if (r.length - DNS_MESSAGE_HEADERLEN < 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);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(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
d878b8d87c3f46a25ccae9f5cfe6e39af67562e0Evan Hunt#ifdef ALLOW_FILTER_AAAA
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt/*
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt * Decide whether to not answer with an AAAA record and its RRSIG
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt */
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Huntstatic inline isc_boolean_t
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrewsnorender_rdataset(const dns_rdataset_t *rdataset, unsigned int options,
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews dns_section_t sectionid)
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt{
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews if (sectionid == DNS_SECTION_QUESTION)
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews return (ISC_FALSE);
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt switch (rdataset->type) {
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews case dns_rdatatype_ns:
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews sectionid != DNS_SECTION_AUTHORITY)
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews return (ISC_FALSE);
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews break;
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt case dns_rdatatype_aaaa:
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0)
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt return (ISC_FALSE);
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt break;
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt case dns_rdatatype_rrsig:
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews (rdataset->covers != dns_rdatatype_ns &&
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews rdataset->covers != dns_rdatatype_aaaa))
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews return (ISC_FALSE);
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews if ((rdataset->covers == dns_rdatatype_ns) &&
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews (sectionid != DNS_SECTION_AUTHORITY))
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt return (ISC_FALSE);
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt break;
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt default:
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt return (ISC_FALSE);
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt }
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if (rdataset->rdclass != dns_rdataclass_in)
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt return (ISC_FALSE);
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt return (ISC_TRUE);
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt}
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt#endif
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrewsstatic isc_result_t
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrewsrenderset(dns_rdataset_t *rdataset, dns_name_t *owner_name,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews dns_compress_t *cctx, isc_buffer_t *target,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews unsigned int reserved, unsigned int options, unsigned int *countp)
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews{
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews isc_result_t result;
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews /*
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews * Shrink the space in the buffer by the reserved amount.
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews */
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews if (target->length - target->used < reserved)
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews return (ISC_R_NOSPACE);
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews target->length -= reserved;
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = dns_rdataset_towire(rdataset, owner_name,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews cctx, target, options, countp);
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews target->length += reserved;
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews return (result);
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews}
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews
ac9072210cea5283e554f1787876b647a08fda96Mark Andrewsstatic void
ac9072210cea5283e554f1787876b647a08fda96Mark Andrewsmaybe_clear_ad(dns_message_t *msg, dns_section_t sectionid) {
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews if (msg->counts[sectionid] == 0 &&
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews (sectionid == DNS_SECTION_ANSWER ||
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews (sectionid == DNS_SECTION_AUTHORITY &&
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews msg->counts[DNS_SECTION_ANSWER] == 0)))
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews msg->flags &= ~DNS_MESSAGEFLAG_AD;
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews}
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews
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 */
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews if (msg->buffer->length - msg->buffer->used < msg->reserved)
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews return (ISC_R_NOSPACE);
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
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews /*
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews * Render required glue first. Set TC if it won't fit.
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews */
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews name = ISC_LIST_HEAD(*section);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews if (name != NULL) {
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews rdataset = ISC_LIST_HEAD(name->list);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews if (rdataset != NULL &&
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 &&
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) {
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews const void *order_arg = msg->order_arg;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews st = *(msg->buffer);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews count = 0;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews if (partial)
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews result = dns_rdataset_towirepartial(rdataset,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews name,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->cctx,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->buffer,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->order,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews order_arg,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews rd_options,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews &count,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews NULL);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews else
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews result = dns_rdataset_towiresorted(rdataset,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews name,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->cctx,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->buffer,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->order,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews order_arg,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews rd_options,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews &count);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews total += count;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews if (partial && result == ISC_R_NOSPACE) {
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->flags |= DNS_MESSAGEFLAG_TC;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->buffer->length += msg->reserved;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->counts[sectionid] += total;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews return (result);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews }
9dd2ee95f11de29e358cc01059861e724dbb5807Mark Andrews if (result == ISC_R_NOSPACE)
9dd2ee95f11de29e358cc01059861e724dbb5807Mark Andrews msg->flags |= DNS_MESSAGEFLAG_TC;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews if (result != ISC_R_SUCCESS) {
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews INSIST(st.used < 65536);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews dns_compress_rollback(msg->cctx,
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews (isc_uint16_t)st.used);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews *(msg->buffer) = st; /* rollback */
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->buffer->length += msg->reserved;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews msg->counts[sectionid] += total;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews return (result);
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews }
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews rdataset->attributes |= DNS_RDATASETATTR_RENDERED;
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews }
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews }
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews
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
d878b8d87c3f46a25ccae9f5cfe6e39af67562e0Evan Hunt#ifdef ALLOW_FILTER_AAAA
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt /*
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt * Suppress AAAAs if asked and we are
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt * not doing DNSSEC or are breaking DNSSEC.
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt * Say so in the AD bit if we break DNSSEC.
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt */
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews if (norender_rdataset(rdataset, options, sectionid)) {
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if (sectionid == DNS_SECTION_ANSWER ||
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt sectionid == DNS_SECTION_AUTHORITY)
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt msg->flags &= ~DNS_MESSAGEFLAG_AD;
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if (OPTOUT(rdataset))
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt msg->flags &= ~DNS_MESSAGEFLAG_AD;
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt goto next;
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt }
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt#endif
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
47b7dfffe5d806c6a5e99ef17f07bcde812c2132Francis Dupont * sets starting at some arbitrary 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;
ac9072210cea5283e554f1787876b647a08fda96Mark Andrews maybe_clear_ad(msg, sectionid);
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;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews if (OPTOUT(rdataset))
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews 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
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews /*
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews * If we're adding a OPT, TSIG or SIG(0) to a truncated message,
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews * clear all rdatasets from the message except for the question
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews * before adding the OPT, TSIG or SIG(0). If the question doesn't
c37fbb91e37b771bb0fad908ad78ddd12ac07538Tinderbox User * fit, don't include it.
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews */
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) &&
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews (msg->flags & DNS_MESSAGEFLAG_TC) != 0)
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews {
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews isc_buffer_t *buf;
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews msgresetnames(msg, DNS_SECTION_ANSWER);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews buf = msg->buffer;
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews dns_message_renderreset(msg);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews msg->buffer = buf;
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews isc_buffer_clear(msg->buffer);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews dns_compress_rollback(msg->cctx, 0);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews 0);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews return (result);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews }
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews
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;
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = renderset(msg->opt, dns_rootname, msg->cctx,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews msg->buffer, msg->reserved, 0, &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 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;
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = renderset(msg->tsig, msg->tsigname, msg->cctx,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews msg->buffer, msg->reserved, 0, &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 */
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = renderset(msg->sig0, dns_rootname, msg->cctx,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews msg->buffer, msg->reserved, 0, &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);
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(name == NULL || *name == NULL);
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (type == dns_rdatatype_any) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(rdataset == NULL);
f9df80f4348ef68043903efa08299480324f4823Michael Graff } else {
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(rdataset == NULL || *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 */
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman if (ISC_UNLIKELY(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
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrewsvoid
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrewsdns_message_removename(dns_message_t *msg, dns_name_t *name,
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews dns_section_t section)
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews{
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews REQUIRE(msg != NULL);
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews REQUIRE(name != NULL);
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews REQUIRE(VALID_NAMED_SECTION(section));
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews ISC_LIST_UNLINK(msg->sections[section], name, link);
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews}
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews
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) {
1acfed3dac1e02f4cbac811a06147377ecfac4c4Mark Andrews unsigned int clear_from;
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;
b7bc86a4d3d78fae33577682cea7d1449abb7b33Mark Andrews if (msg->opcode == dns_opcode_update)
1acfed3dac1e02f4cbac811a06147377ecfac4c4Mark Andrews clear_from = DNS_SECTION_PREREQUISITE;
b7bc86a4d3d78fae33577682cea7d1449abb7b33Mark Andrews else if (want_question_section) {
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley if (!msg->question_ok)
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley return (DNS_R_FORMERR);
1acfed3dac1e02f4cbac811a06147377ecfac4c4Mark Andrews clear_from = DNS_SECTION_ANSWER;
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halley } else
1acfed3dac1e02f4cbac811a06147377ecfac4c4Mark Andrews clear_from = DNS_SECTION_QUESTION;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
1acfed3dac1e02f4cbac811a06147377ecfac4c4Mark Andrews msgresetnames(msg, clear_from);
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 */
348d80fb8490f4547aaa569e5f7ea2a032543bacMark Andrews if (msg->opcode == dns_opcode_query)
348d80fb8490f4547aaa569e5f7ea2a032543bacMark Andrews msg->flags &= DNS_MESSAGE_REPLYPRESERVE;
348d80fb8490f4547aaa569e5f7ea2a032543bacMark Andrews else
348d80fb8490f4547aaa569e5f7ea2a032543bacMark Andrews msg->flags = 0;
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:
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_rdataset_disassociate(opt);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson dns_message_puttemprdataset(msg, &opt);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson return (result);
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
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews if (key == NULL && msg->tsigkey != NULL) {
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews if (msg->sig_reserved != 0) {
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews dns_message_renderrelease(msg, msg->sig_reserved);
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews msg->sig_reserved = 0;
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews }
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews dns_tsigkey_detach(&msg->tsigkey);
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews }
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_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);
0874abad14e3e9ecfc3dc1a1a2b9969f2f027724Mark Andrews INSIST(result == ISC_R_SUCCESS);
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt if (msg->verified_sig &&
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt msg->tsigstatus == dns_rcode_noerror &&
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt tsig.error == dns_rcode_noerror)
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt {
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt result = ISC_R_SUCCESS;
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt } else if ((!msg->verified_sig) ||
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt (msg->tsigstatus != dns_rcode_noerror))
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_TSIGVERIFYFAILURE;
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt } else {
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt INSIST(tsig.error != dns_rcode_noerror);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = DNS_R_TSIGERRORSET;
a03f4b1ea4f1a4a70963fbeb606841c217f9e5f3Evan Hunt }
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
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#ifdef SKAN_MSG_DEBUG
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsvoid
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsdns_message_dumpsig(dns_message_t *msg, char *txt1) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdata_t querytsigrdata = DNS_RDATA_INIT;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdata_any_tsig_t querytsig;
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews isc_result_t result;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (msg->tsig != NULL) {
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdataset_first(msg->tsig);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_current(msg->tsig, &querytsigrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews hexdump(txt1, "TSIG", querytsig.signature,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews querytsig.siglen);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews if (msg->querytsig != NULL) {
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdataset_first(msg->querytsig);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_current(msg->querytsig, &querytsigrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews hexdump(txt1, "QUERYTSIG", querytsig.signature,
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews querytsig.siglen);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews }
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews}
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#endif
289ae548d52bc8f982d9823af64cafda7bd92232Mark 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);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews
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) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#ifdef SKAN_MSG_DEBUG
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_message_dumpsig(msg, "dns_message_checksig#1");
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews#endif
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
3f42cf2f3e4dc7e740b4609ba7d7430292348f2bMark Andrews dns_rdata_reset(&rdata);
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
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk#define INDENT(sp) \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk do { \
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews unsigned int __i; \
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews dns_masterstyle_flags_t __flags = dns_master_styleflags(sp); \
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews if ((__flags & DNS_STYLEFLAG_INDENT) == 0ULL && \
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews (__flags & DNS_STYLEFLAG_YAML) == 0ULL) \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk break; \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk for (__i = 0; __i < dns_master_indent; __i++) { \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, dns_master_indentstr); \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } while (0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
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;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_result_t result = ISC_R_SUCCESS;
13396661f46572d7b94703a25721aad040fbd91aMark Andrews isc_boolean_t seensoa = ISC_FALSE;
e63d63dc8510c669e1575b2762265842e8783822Evan Hunt unsigned int saveindent;
e63d63dc8510c669e1575b2762265842e8783822Evan Hunt dns_masterstyle_flags_t sflags;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(target != NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(VALID_SECTION(section));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk saveindent = dns_master_indent;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk sflags = dns_master_styleflags(style);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer if (ISC_LIST_EMPTY(msg->sections[section]))
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->opcode != dns_opcode_update) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, sectiontext[section]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, updsectiontext[section]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "_SECTION:\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else 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]);
77397daf05511dc737eeec159badc05f11bfadddMark Andrews } 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) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_master_indent++;
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)) {
4d42b714be10e6f163d23507e4e3a396a8ac0364Automatic Updater if (section == DNS_SECTION_ANSWER &&
13396661f46572d7b94703a25721aad040fbd91aMark Andrews rdataset->type == dns_rdatatype_soa) {
13396661f46572d7b94703a25721aad040fbd91aMark Andrews if ((flags & DNS_MESSAGETEXTFLAG_OMITSOA) != 0)
13396661f46572d7b94703a25721aad040fbd91aMark Andrews continue;
13396661f46572d7b94703a25721aad040fbd91aMark Andrews if (seensoa &&
13396661f46572d7b94703a25721aad040fbd91aMark Andrews (flags & DNS_MESSAGETEXTFLAG_ONESOA) != 0)
13396661f46572d7b94703a25721aad040fbd91aMark Andrews continue;
13396661f46572d7b94703a25721aad040fbd91aMark Andrews seensoa = ISC_TRUE;
13396661f46572d7b94703a25721aad040fbd91aMark Andrews }
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson if (section == DNS_SECTION_QUESTION) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "- ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, ";");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
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)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_nextname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer } while (result == ISC_R_SUCCESS);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((sflags & DNS_STYLEFLAG_YAML) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_master_indent--;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0 &&
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk (sflags & DNS_STYLEFLAG_YAML) == 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
194de894f0697562f94e048f573d99260a18a639Michael Sawyer ADD_STRING(target, "\n");
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt }
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (result == ISC_R_NOMORE)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk cleanup:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_master_indent = saveindent;
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer}
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Huntstatic isc_result_t
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrewsrender_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt int i;
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt char addr[16], addr_text[64];
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt isc_uint16_t family;
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt isc_uint8_t addrlen, addrbytes, scopelen;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_result_t result;
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews /*
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * Note: This routine needs to handle malformed ECS options.
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews */
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews if (isc_buffer_remaininglength(ecsbuf) < 4)
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews return (DNS_R_OPTERR);
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews family = isc_buffer_getuint16(ecsbuf);
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews addrlen = isc_buffer_getuint8(ecsbuf);
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews scopelen = isc_buffer_getuint8(ecsbuf);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt addrbytes = (addrlen + 7) / 8;
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews if (isc_buffer_remaininglength(ecsbuf) < addrbytes)
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews return (DNS_R_OPTERR);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt
1330ae5fc207ce2db4c1e0670a43f3c9e654152eEvan Hunt if (addrbytes > sizeof(addr))
1330ae5fc207ce2db4c1e0670a43f3c9e654152eEvan Hunt return (DNS_R_OPTERR);
1330ae5fc207ce2db4c1e0670a43f3c9e654152eEvan Hunt
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt memset(addr, 0, sizeof(addr));
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt for (i = 0; i < addrbytes; i ++)
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews addr[i] = isc_buffer_getuint8(ecsbuf);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt switch (family) {
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt case 0:
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt if (addrlen != 0U || scopelen != 0U)
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt return (DNS_R_OPTERR);
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt strlcpy(addr_text, "0", sizeof(addr_text));
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt break;
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt case 1:
0302fcbf7e41fdbcf55f70cc040e3e55f448c06cEvan Hunt if (addrlen > 32 || scopelen > 32)
0302fcbf7e41fdbcf55f70cc040e3e55f448c06cEvan Hunt return (DNS_R_OPTERR);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt inet_ntop(AF_INET, addr, addr_text, sizeof(addr_text));
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt break;
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt case 2:
0302fcbf7e41fdbcf55f70cc040e3e55f448c06cEvan Hunt if (addrlen > 128 || scopelen > 128)
0302fcbf7e41fdbcf55f70cc040e3e55f448c06cEvan Hunt return (DNS_R_OPTERR);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt inet_ntop(AF_INET6, addr, addr_text, sizeof(addr_text));
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt break;
395e6865d5b0ec13c1e4cc3947598153aa4e4914Evan Hunt default:
db9781d4a2ed15c4b34bb5c97ea68b8f598992fcMark Andrews return (DNS_R_OPTERR);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt }
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt
db9781d4a2ed15c4b34bb5c97ea68b8f598992fcMark Andrews ADD_STRING(target, ": ");
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt ADD_STRING(target, addr_text);
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt snprintf(addr_text, sizeof(addr_text), "/%d/%d", addrlen, scopelen);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt ADD_STRING(target, addr_text);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk cleanup:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (result);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk}
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpkstatic isc_result_t
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpkdns_message_pseudosectiontoyaml(dns_message_t *msg,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_pseudosection_t section,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk const dns_master_style_t *style,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_messagetextflag_t flags,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_t *target)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk{
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_rdataset_t *ps = NULL;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_name_t *name = NULL;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_result_t result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk char buf[sizeof("1234567890")];
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_uint32_t mbz;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_rdata_t rdata;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_t optbuf;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_uint16_t optcode, optlen;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk unsigned char *optdata;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk unsigned int saveindent = dns_master_indent;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk REQUIRE(DNS_MESSAGE_VALID(msg));
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk REQUIRE(target != NULL);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk REQUIRE(VALID_PSEUDOSECTION(section));
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk switch (section) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk case DNS_PSEUDOSECTION_OPT:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ps = dns_message_getopt(msg);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (ps == NULL) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "OPT_PSEUDOSECTION:\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_master_indent++;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "EDNS:\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_master_indent++;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "version: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%u",
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk (unsigned int)((ps->ttl & 0x00ff0000) >> 16));
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "flags:");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((ps->ttl & DNS_MESSAGEEXTFLAG_DO) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " do");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk mbz = ps->ttl & 0xffff;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (mbz != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "MBZ: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "0x%.4x", mbz);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "udp: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_rdataset_first(ps);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (result != ISC_R_SUCCESS) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk /*
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * Print EDNS info, if any.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk *
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * WARNING: The option contents may be malformed as
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * dig +ednsopt=value:<content> does not validity
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * checking.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_rdata_init(&rdata);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_rdataset_current(ps, &rdata);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_init(&optbuf, rdata.data, rdata.length);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_add(&optbuf, rdata.length);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk while (isc_buffer_remaininglength(&optbuf) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk optcode = isc_buffer_getuint16(&optbuf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk optlen = isc_buffer_getuint16(&optbuf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (optcode == DNS_OPT_NSID) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "NSID");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if (optcode == DNS_OPT_COOKIE) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "COOKIE");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if (optcode == DNS_OPT_CLIENT_SUBNET) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_t ecsbuf;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "CLIENT-SUBNET");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_init(&ecsbuf,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_current(&optbuf),
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk optlen);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_add(&ecsbuf, optlen);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = render_ecs(&ecsbuf, target);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (result == ISC_R_NOSPACE)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (result == ISC_R_SUCCESS) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_forward(&optbuf, optlen);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk continue;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if (optcode == DNS_OPT_EXPIRE) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (optlen == 4) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_uint32_t secs;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk secs = isc_buffer_getuint32(&optbuf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "EXPIRE: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%u", secs);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " (");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_ttl_totext(secs,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ISC_TRUE,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk target);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (result != ISC_R_SUCCESS)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, ")\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk continue;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "EXPIRE");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if (optcode == DNS_OPT_PAD) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "PAD");
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews } else if (optcode == DNS_OPT_KEY_TAG) {
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews INDENT(style);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews ADD_STRING(target, "KEY-TAG");
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews if (optlen > 0U && (optlen % 2U) == 0U) {
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews const char *sep = ": ";
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews isc_uint16_t id;
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews while (optlen > 0U) {
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews id = isc_buffer_getuint16(&optbuf);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews snprintf(buf, sizeof(buf), "%s%u",
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews sep, id);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews ADD_STRING(target, buf);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews sep = ", ";
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews optlen -= 2;
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews }
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews ADD_STRING(target, "\n");
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews continue;
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "OPT: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%u", optcode);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (optlen != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk int i;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, ": ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk optdata = isc_buffer_current(&optbuf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk for (i = 0; i < optlen; i++) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk const char *sep;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk switch (optcode) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk case DNS_OPT_COOKIE:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk sep = "";
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk break;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk default:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk sep = " ";
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk break;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%02x%s",
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk optdata[i], sep);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_forward(&optbuf, optlen);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (optcode == DNS_OPT_COOKIE) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk /*
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * Valid server cookie?
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->cc_ok && optlen >= 16)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " (good)");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk /*
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * Server cookie is not valid but
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * we had our cookie echoed back.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->cc_ok && optlen < 16)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " (echoed)");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk /*
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * We didn't get our cookie echoed
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * back.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->cc_bad)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " (bad)");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk continue;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (optcode == DNS_OPT_CLIENT_SUBNET) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk continue;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk /*
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * For non-COOKIE options, add a printable
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * version
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "(\"");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (isc_buffer_availablelength(target) < optlen)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_NOSPACE;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk for (i = 0; i < optlen; i++) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (isprint(optdata[i]))
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_putmem(target,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk &optdata[i],
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk 1);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk else
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk isc_buffer_putstr(target, ".");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\")");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk case DNS_PSEUDOSECTION_TSIG:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ps = dns_message_gettsig(msg, &name);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (ps == NULL) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "TSIG_PSEUDOSECTION:\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_master_rdatasettotext(name, ps, style, target);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk case DNS_PSEUDOSECTION_SIG0:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ps = dns_message_getsig0(msg, &name);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (ps == NULL) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_SUCCESS;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "SIG0_PSEUDOSECTION:\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_master_rdatasettotext(name, ps, style, target);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk goto cleanup;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_UNEXPECTED;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk cleanup:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk dns_master_indent = saveindent;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (result);
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt}
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt
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,
586d94eb740587975d5348b22a5fb8440d95925dMark Andrews isc_buffer_t *target)
586d94eb740587975d5348b22a5fb8440d95925dMark Andrews{
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;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews dns_rdata_t rdata;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews isc_buffer_t optbuf;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews isc_uint16_t optcode, optlen;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews unsigned char *optdata;
8db2b65318b72e3ee477d6f6a346b525dd2db53aAndreas Gustafsson
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(DNS_MESSAGE_VALID(msg));
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(target != NULL);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer REQUIRE(VALID_PSEUDOSECTION(section));
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (dns_message_pseudosectiontoyaml(msg, section, style,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk flags, target));
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);
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt }
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
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");
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews mbz = ps->ttl & 0xffff;
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews if (mbz != 0) {
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews ADD_STRING(target, "; MBZ: ");
8d00c5ab2c16985457947ddb0376707ab7094b80Mark Andrews snprintf(buf, sizeof(buf), "0x%.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);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews result = dns_rdataset_first(ps);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews if (result != ISC_R_SUCCESS)
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews return (ISC_R_SUCCESS);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews /*
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * Print EDNS info, if any.
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews *
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * WARNING: The option contents may be malformed as
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * dig +ednsopt=value:<content> does not validity
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * checking.
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews */
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews dns_rdata_init(&rdata);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews dns_rdataset_current(ps, &rdata);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews isc_buffer_init(&optbuf, rdata.data, rdata.length);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews isc_buffer_add(&optbuf, rdata.length);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews while (isc_buffer_remaininglength(&optbuf) != 0) {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews optcode = isc_buffer_getuint16(&optbuf);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews optlen = isc_buffer_getuint16(&optbuf);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews if (optcode == DNS_OPT_NSID) {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, "; NSID");
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews } else if (optcode == DNS_OPT_COOKIE) {
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews ADD_STRING(target, "; COOKIE");
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt } else if (optcode == DNS_OPT_CLIENT_SUBNET) {
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews isc_buffer_t ecsbuf;
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews ADD_STRING(target, "; CLIENT-SUBNET");
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews isc_buffer_init(&ecsbuf,
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews isc_buffer_current(&optbuf),
0796eca5f7159622c0aa04ab41ca943a3493dc56Tinderbox User optlen);
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews isc_buffer_add(&ecsbuf, optlen);
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews result = render_ecs(&ecsbuf, target);
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews if (result == ISC_R_NOSPACE)
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews return (result);
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews if (result == ISC_R_SUCCESS) {
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews isc_buffer_forward(&optbuf, optlen);
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews ADD_STRING(target, "\n");
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews continue;
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews }
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews } else if (optcode == DNS_OPT_EXPIRE) {
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews if (optlen == 4) {
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews isc_uint32_t secs;
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews secs = isc_buffer_getuint32(&optbuf);
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews ADD_STRING(target, "; EXPIRE: ");
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews snprintf(buf, sizeof(buf), "%u", secs);
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews ADD_STRING(target, buf);
6cba0b8e61859e37cbf16818cc95ba1da85d68fdEvan Hunt ADD_STRING(target, " (");
2879ee2c72638ea190728f931ce286760caa4521Evan Hunt result = dns_ttl_totext(secs,
2879ee2c72638ea190728f931ce286760caa4521Evan Hunt ISC_TRUE,
2879ee2c72638ea190728f931ce286760caa4521Evan Hunt target);
2879ee2c72638ea190728f931ce286760caa4521Evan Hunt if (result != ISC_R_SUCCESS)
2879ee2c72638ea190728f931ce286760caa4521Evan Hunt return (result);
6cba0b8e61859e37cbf16818cc95ba1da85d68fdEvan Hunt ADD_STRING(target, ")\n");
51d6d7eea46134078fbaf5824c34f836a44d0784Mark Andrews continue;
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews }
16134801ce8fffbb6c42bb54d544c3397a45ad06Mark Andrews ADD_STRING(target, "; EXPIRE");
33a4294f442f7505c8e2453beb422b5928ec697cMark Andrews } else if (optcode == DNS_OPT_PAD) {
33a4294f442f7505c8e2453beb422b5928ec697cMark Andrews ADD_STRING(target, "; PAD");
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews } else if (optcode == DNS_OPT_KEY_TAG) {
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews ADD_STRING(target, "; KEY-TAG");
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews if (optlen > 0U && (optlen % 2U) == 0U) {
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews const char *sep = ": ";
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews isc_uint16_t id;
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews while (optlen > 0U) {
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews id = isc_buffer_getuint16(&optbuf);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews snprintf(buf, sizeof(buf), "%s%u",
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews sep, id);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews ADD_STRING(target, buf);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews sep = ", ";
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews optlen -= 2;
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews }
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews ADD_STRING(target, "\n");
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews continue;
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews }
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews } else {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, "; OPT=");
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt snprintf(buf, sizeof(buf), "%u", optcode);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews ADD_STRING(target, buf);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews }
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews if (optlen != 0) {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews int i;
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, ": ");
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews optdata = isc_buffer_current(&optbuf);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews for (i = 0; i < optlen; i++) {
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews const char *sep;
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews switch (optcode) {
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews case DNS_OPT_COOKIE:
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews sep = "";
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews break;
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews default:
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews sep = " ";
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews break;
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews }
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt snprintf(buf, sizeof(buf), "%02x%s",
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt optdata[i], sep);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, buf);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews }
a499dddb4b4d4db2bb6ced82b5ee7a459e23603eEvan Hunt
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews isc_buffer_forward(&optbuf, optlen);
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews if (optcode == DNS_OPT_COOKIE) {
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews /*
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * Valid server cookie?
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews */
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews if (msg->cc_ok && optlen >= 16)
f0c00f10a0b15e551655a309e3bc9252e6bf8cfdMark Andrews ADD_STRING(target, " (good)");
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews /*
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * Server cookie is not valid but
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * we had our cookie echoed back.
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews */
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews if (msg->cc_ok && optlen < 16)
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews ADD_STRING(target, " (echoed)");
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews /*
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * We didn't get our cookie echoed
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * back.
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews */
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews if (msg->cc_bad)
f0c00f10a0b15e551655a309e3bc9252e6bf8cfdMark Andrews ADD_STRING(target, " (bad)");
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews ADD_STRING(target, "\n");
51d6d7eea46134078fbaf5824c34f836a44d0784Mark Andrews continue;
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews }
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews if (optcode == DNS_OPT_CLIENT_SUBNET) {
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews ADD_STRING(target, "\n");
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews continue;
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews }
46fc714aa0558bfb96c195983a48703659db1f5dMark Andrews
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews /*
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews * For non-COOKIE options, add a printable
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews * version
b5f6271f4daf1e54501af2cb7dd278d7e8003d65Mark Andrews */
a499dddb4b4d4db2bb6ced82b5ee7a459e23603eEvan Hunt ADD_STRING(target, "(\"");
586d94eb740587975d5348b22a5fb8440d95925dMark Andrews if (isc_buffer_availablelength(target) < optlen)
586d94eb740587975d5348b22a5fb8440d95925dMark Andrews return (ISC_R_NOSPACE);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews for (i = 0; i < optlen; i++) {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews if (isprint(optdata[i]))
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews isc_buffer_putmem(target,
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews &optdata[i],
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews 1);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews else
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews isc_buffer_putstr(target, ".");
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews }
a499dddb4b4d4db2bb6ced82b5ee7a459e23603eEvan Hunt ADD_STRING(target, "\")");
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews }
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, "\n");
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews }
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);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
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);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
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 }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = ISC_R_UNEXPECTED;
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk cleanup:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (result);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer}
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerisc_result_t
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellingtondns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews dns_messagetextflag_t flags, isc_buffer_t *target)
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews{
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
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) &&
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk (dns_master_styleflags(style) & DNS_STYLEFLAG_YAML))
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "opcode: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, opcodetext[msg->opcode]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "status: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_rcode_totext(msg->rcode, target);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (result != ISC_R_SUCCESS)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (result);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "id: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%6u", msg->id);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "flags:");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " qr");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " aa");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " tc");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " rd");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " ra");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " ad");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, " cd");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk /*
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * The final unnamed flag must be zero.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk */
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((msg->flags & 0x0040U) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "MBZ: 0x4");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->opcode != dns_opcode_update) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "QUESTION: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "ZONE: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%1u",
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk msg->counts[DNS_SECTION_QUESTION]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->opcode != dns_opcode_update) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "ANSWER: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "PREREQ: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%1u",
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk msg->counts[DNS_SECTION_ANSWER]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (msg->opcode != dns_opcode_update) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "AUTHORITY: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "UPDATE: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk }
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%1u",
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk msg->counts[DNS_SECTION_AUTHORITY]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "ADDITIONAL: ");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%1u",
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk msg->counts[DNS_SECTION_ADDITIONAL]);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, buf);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, opcodetext[msg->opcode]);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", status: ");
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews result = dns_rcode_totext(msg->rcode, target);
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews if (result != ISC_R_SUCCESS)
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews return (result);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ", id: ");
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews snprintf(buf, sizeof(buf), "%6u", msg->id);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, buf);
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt ADD_STRING(target, "\n");
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt ADD_STRING(target, ";; flags:");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_QR) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " qr");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_AA) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " aa");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " tc");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_RD) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " rd");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_RA) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " ra");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_AD) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " ad");
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if ((msg->flags & DNS_MESSAGEFLAG_CD) != 0)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, " cd");
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews /*
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews * The final unnamed flag must be zero.
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews */
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt if ((msg->flags & 0x0040U) != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews ADD_STRING(target, "; MBZ: 0x4");
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt }
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer if (msg->opcode != dns_opcode_update) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer ADD_STRING(target, "; QUESTION: ");
d2762d6c3797b1ce43965404d03b410f215932e0Michael Graff } else {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk INDENT(style);
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
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk cleanup:
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (result);
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,
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews const 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}
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrewsvoid
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrewsdns_message_logpacket(dns_message_t *message, const char *description,
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_logcategory_t *category, isc_logmodule_t *module,
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews int level, isc_mem_t *mctx)
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt{
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, NULL, category, module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews &dns_master_style_debug, level, mctx);
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews}
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewsvoid
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewsdns_message_logpacket2(dns_message_t *message,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews const char *description, isc_sockaddr_t *address,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_logcategory_t *category, isc_logmodule_t *module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews int level, isc_mem_t *mctx)
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews{
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews REQUIRE(address != NULL);
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, address, category, module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews &dns_master_style_debug, level, mctx);
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt}
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Huntvoid
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Huntdns_message_logfmtpacket(dns_message_t *message, const char *description,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt isc_logcategory_t *category, isc_logmodule_t *module,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt const dns_master_style_t *style, int level,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt isc_mem_t *mctx)
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews{
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, NULL, category, module, style,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews level, mctx);
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews}
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewsvoid
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewsdns_message_logfmtpacket2(dns_message_t *message,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews const char *description, isc_sockaddr_t *address,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_logcategory_t *category, isc_logmodule_t *module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews const dns_master_style_t *style, int level,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_mem_t *mctx)
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews{
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews REQUIRE(address != NULL);
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, address, category, module, style,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews level, mctx);
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews}
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewsstatic void
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrewslogfmtpacket(dns_message_t *message, const char *description,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_sockaddr_t *address, isc_logcategory_t *category,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_logmodule_t *module, const dns_master_style_t *style,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews int level, isc_mem_t *mctx)
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews{
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews char addrbuf[ISC_SOCKADDR_FORMATSIZE] = { 0 };
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews const char *newline = "\n";
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews const char *space = " ";
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_buffer_t buffer;
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews char *buf = NULL;
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews int len = 1024;
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_result_t result;
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews if (! isc_log_wouldlog(dns_lctx, level))
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews return;
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews /*
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews * Note that these are multiline debug messages. We want a newline
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews * to appear in the log after each message.
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews */
5fa46bc91672ef5737aee6f99763161511566c24Tinderbox User
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews if (address != NULL)
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews else
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews newline = space = "";
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews do {
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews buf = isc_mem_get(mctx, len);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews if (buf == NULL)
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews break;
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_buffer_init(&buffer, buf, len);
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt result = dns_message_totext(message, style, 0, &buffer);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews if (result == ISC_R_NOSPACE) {
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_mem_put(mctx, buf, len);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews len += 1024;
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews } else if (result == ISC_R_SUCCESS)
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_log_write(dns_lctx, category, module, level,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews "%s%s%s%s%.*s", description, space,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews addrbuf, newline,
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews (int)isc_buffer_usedlength(&buffer),
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews buf);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews } while (result == ISC_R_NOSPACE);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews if (buf != NULL)
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_mem_put(mctx, buf, len);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews}
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrewsisc_result_t
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrewsdns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp,
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews unsigned int version, isc_uint16_t udpsize,
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews unsigned int flags, dns_ednsopt_t *ednsopts, size_t count)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews{
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_rdataset_t *rdataset = NULL;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_rdatalist_t *rdatalist = NULL;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_rdata_t *rdata = NULL;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews isc_result_t result;
c3c8823fed039b3a2b8e5ca8bc2f3301d1dd840eMark Andrews unsigned int len = 0, i;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews REQUIRE(DNS_MESSAGE_VALID(message));
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_message_gettemprdatalist(message, &rdatalist);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (result != ISC_R_SUCCESS)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews return (result);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_message_gettemprdata(message, &rdata);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (result != ISC_R_SUCCESS)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews goto cleanup;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_message_gettemprdataset(message, &rdataset);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (result != ISC_R_SUCCESS)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews goto cleanup;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdatalist->type = dns_rdatatype_opt;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews /*
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews * Set Maximum UDP buffer size.
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews */
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdatalist->rdclass = udpsize;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews /*
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews * Set EXTENDED-RCODE and Z to 0.
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews */
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdatalist->ttl = (version << 16);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdatalist->ttl |= (flags & 0xffff);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews /*
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews * Set EDNS options if applicable
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews */
11d945cd75380cb9f0228370b1b4eecb14730159Mark Andrews if (count != 0U) {
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews isc_buffer_t *buf = NULL;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews for (i = 0; i < count; i++)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews len += ednsopts[i].length + 4;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (len > 0xffffU) {
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = ISC_R_NOSPACE;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews goto cleanup;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews }
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = isc_buffer_allocate(message->mctx, &buf, len);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (result != ISC_R_SUCCESS)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews goto cleanup;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews for (i = 0; i < count; i++) {
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews isc_buffer_putuint16(buf, ednsopts[i].code);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews isc_buffer_putuint16(buf, ednsopts[i].length);
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews if (ednsopts[i].length != 0) {
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews isc_buffer_putmem(buf, ednsopts[i].value,
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews ednsopts[i].length);
a5a1cbece45e6ca68aafe3b9b995eac6b0f45dd2Mark Andrews }
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews }
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->data = isc_buffer_base(buf);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->length = len;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_message_takebuffer(message, &buf);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews } else {
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->data = NULL;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->length = 0;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews }
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->rdclass = rdatalist->rdclass;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->type = rdatalist->type;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews rdata->flags = 0;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_rdatalist_tordataset(rdatalist, rdataset);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews RUNTIME_CHECK(result == ISC_R_SUCCESS);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews *rdatasetp = rdataset;
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews return (ISC_R_SUCCESS);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews cleanup:
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (rdata != NULL)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_message_puttemprdata(message, &rdata);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (rdataset != NULL)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_message_puttemprdataset(message, &rdataset);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews if (rdatalist != NULL)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_message_puttemprdatalist(message, &rdatalist);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews return (result);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews}
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrewsvoid
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrewsdns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) {
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews REQUIRE(DNS_MESSAGE_VALID(msg));
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews REQUIRE(msg->state == DNS_SECTION_ANY);
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews REQUIRE(msg->rdclass_set == 0);
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass = rdclass;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews msg->rdclass_set = 1;
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews}