3b7f610bec248f85e25a52a0ad7dec9894389ca5Tinderbox User * Copyright (C) 1999-2017 Internet Systems Consortium, Inc. ("ISC")
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/.
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/string.h> /* Required for HP/UX (and others?) */
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewshexdump(const char *msg, const char *msg2, void *base, size_t len) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews unsigned char *p;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews printf(" %02x %c", *p, (isprint(*p) ? *p : ' '));
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington#define ADD_STRING(b, s) {if (strlen(s) >= \
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
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.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * Text representation of the different items, for message_totext
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer "PREREQUISITE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED10",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
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}; /* dynamically sized */
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ((type *)msgblock_internalget(block, sizeof(type)))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_internalget(dns_msgblock_t *, unsigned int);
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffstatic inline void
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
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,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * is free, return NULL.
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int count)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * count);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Return an element from the msgblock. If no more are available, return
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
8c55a67a6d185de7036e39da30561a5c1637d22bAndreas Gustafsson if (block == NULL || block->remaining == 0)
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Release memory associated with a message block.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);
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
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencenewbuffer(dns_message_t *msg, unsigned int size) {
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencereleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_PREPEND(msg->freerdata, rdata, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_rdata_t *
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencereleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington offsets = msgblock_get(msgblock, dns_offsets_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_APPEND(msg->offsets, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington offsets = msgblock_get(msgblock, dns_offsets_t);
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley unsigned int i;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley for (i = 0; i < DNS_SECTION_MAX; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonstatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Init elements to default state. Used both when allocating a new element
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * and when resetting one.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleystatic inline void
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleymsgresetnames(dns_message_t *msg, unsigned int first_section) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up name lists by calling the rdataset disassociate function.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley for (i = first_section; i < DNS_SECTION_MAX; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[i], name, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_message_renderrelease(msg, msg->opt_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonmsgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington INSIST(dns_rdataset_isassociated(msg->tsig));
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_mempool_put(msg->rdspool, msg->querytsig);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington isc_mempool_put(msg->namepool, msg->tsigname);
6dc130c7c95107748fff5f767161c2bb742f9f87Brian Wellington } else if (msg->querytsig != NULL && !replying) {
22057930cd2a71e1073781b650c7296739c869a6Brian Wellington isc_mempool_put(msg->rdspool, msg->querytsig);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington INSIST(dns_rdataset_isassociated(msg->sig0));
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington isc_mempool_put(msg->namepool, msg->sig0name);
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().
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencemsgreset(dns_message_t *msg, isc_boolean_t everything) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up linked lists.
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 rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t));
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * rdatalists could be empty.
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));
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));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * cleanup the buffer cleanup list
069104dd6a1bba610d0c3a413459accf73f3921bBrian Wellington ISC_LIST_UNLINK(msg->cleanup, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Set other bits to normal default values.
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington ENSURE(isc_mempool_getallocated(msg->namepool) == 0);
3bd43bb300ca4b65602bcffcbd321865d4f18db9Brian Wellington ENSURE(isc_mempool_getallocated(msg->rdspool) == 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonstatic unsigned int
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonspacefortsig(dns_tsigkey_t *key, int otherlen) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int x;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * The space required for an TSIG record is:
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
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington return (26 + r1.length + r2.length + x + otherlen);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * No allocations until further notice. Just initialize all lists
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * and other members that are freed in the cleanup phase here.
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (i = 0; i < DNS_SECTION_MAX; i++)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * Ok, it is safe to allocate (and then "goto cleanup" if failure)
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
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");
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t),
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");
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Cleanup for error returns.
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington ISC_LIST_UNLINK(m->scratchpad, dynbuf, link);
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t));
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_reset(dns_message_t *msg, unsigned int intent) {
df925e6c66d45d960fbac0383169763967d2111cEvan Hunt isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t));
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafssonfindname(dns_name_t **foundname, dns_name_t *target,
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrewsdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(rdataset == NULL || *rdataset == NULL);
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews curr->type == type && curr->covers == covers) {
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graffdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff dns_rdatatype_t covers, dns_rdataset_t **rdataset)
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(rdataset == NULL || *rdataset == NULL);
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley if (curr->type == type && curr->covers == covers) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Read a name from buffer "source".
e223094b2248afa2697c531f75e6f84855638becMichael Graffgetname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * First try: use current buffer.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Second try: allocate a new buffer and use that.
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = newbuffer(msg, SCRATCHPAD_SIZE);
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrencegetrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
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.
9dee95b41cfe1d33d542cc2ec0337d66b28b75abBrian Wellington /* XXX possibly change this to a while (tries < 2) loop */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = dns_rdata_fromwire(rdata, rdclass, rdtype,
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson /* XXX DNS_R_RRTOOLONG? */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellingtongetquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
e223094b2248afa2697c531f75e6f84855638becMichael Graff section = &msg->sections[DNS_SECTION_QUESTION];
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Parse the name out of this packet.
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.
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = findname(&name2, name, section);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is the first name in the section, accept it.
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 * Get type and class.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If this class is different than the one we already read,
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this is an error.
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews * Is this a TKEY query?
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Can't ask the same question twice.
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews result = dns_message_find(name, rdclass, rdtype, 0, NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new rdatalist.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Convert rdatalist to rdataset, and attach the latter to
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_rdatalist_tordataset(rdatalist, rdataset);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsupdate(dns_section_t section, dns_rdataclass_t rdclass) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews return (ISC_TF(rdclass == dns_rdataclass_any ||
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson return (ISC_TF(rdclass == dns_rdataclass_any));
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * Check to confirm that all DNSSEC records (DS, NSEC, NSEC3) have
2595d1da358cc7391e001894d45471509976e7d5Mark Andrews * covering RRSIGs.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_section_t sectionid, unsigned int options)
7fa388dac3ff85315ced069f657bbebfc0828df8Evan Hunt isc_boolean_t free_name = ISC_FALSE, free_rdataset = ISC_FALSE;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington isc_boolean_t preserve_order, best_effort, seen_problem;
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
f1b68725503ff3e46001eee5a1751e29a43a09d1Andreas Gustafsson for (count = 0; count < msg->counts[sectionid]; count++) {
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley isc_boolean_t skip_name_search, skip_type_search;
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Parse the name out of this packet.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Get type, class, ttl, and rdatalen. Verify that at least
e223094b2248afa2697c531f75e6f84855638becMichael Graff * rdatalen bytes remain. (Some of this is deferred to
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson * If there was no question section, we may not yet have
57cf89b149a6c4a9794c24613f9b765e02a54b2fAndreas Gustafsson * established a class. Do so now.
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 */
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If this class is different than the one in the question
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * section, bail.
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 */
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews * If this is not a TKEY query/response then the KEY
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews * record's class needs to match.
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrews if (msg->opcode != dns_opcode_update && !msg->tkey &&
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Special type handling for TSIG, OPT, and TKEY.
bf555703f27295798de30fa8c04d727410788f66Bob Halley * If it is a tsig, verify that it is in the
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * additional data section.
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.
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.
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Its class is ignored.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)
e223094b2248afa2697c531f75e6f84855638becMichael Graff * ... now get ttl and rdatalen, and check buffer.
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.
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.
5059b393e80cda6beffb74f2f30d7329502c41e6Mark Andrews result = getrdata(source, msg, dctx, msg->rdclass,
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence result = getrdata(source, msg, dctx, rdclass,
38e8022ace865803bdd609c9763cd7d7ba2818dcMark Andrews } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews * Check the ownername of NSEC3 records
36e5ac00333d89001f0c518a7d381d16c38d0402Mark Andrews !dns_rdata_checkowner(name, msg->rdclass, rdtype,
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.
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
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.
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = findname(&name2, name, section);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * If it is a new name, append to the section.
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.
bf555703f27295798de30fa8c04d727410788f66Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * If this is a type that can only occur in
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * the question section, fail.
6657a9e2d8c039be0bec367cae59a91d77ccaad4Mark Andrews result = dns_message_find(name, rdclass, rdtype,
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.
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.
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * Minimize TTLs.
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.
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews /* Append this rdata to the rdataset. */
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews dns_rdatalist_fromrdataset(rdataset, &rdatalist);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
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 * 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.
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
5d727330e46c8073703aea7cc0771a456db86829Andreas Gustafsson } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {
c19f322914f380404b613fbb31f5ac2582098f9dMark Andrews /* Windows doesn't like TSIG names to be compressed. */
c19f322914f380404b613fbb31f5ac2582098f9dMark Andrews msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
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
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafssondns_message_parse(dns_message_t *msg, isc_buffer_t *source,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
c73c1c33ec9569c8f9ffd205b48f044f9b03795bMark Andrews ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
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);
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * -1 means no EDNS.
942d1a339b1fe617f7d17d66cb5fccce798d15aeBrian Wellington dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getquestions(source, msg, &dctx, options);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
83c45e69f849a80e21856ceb38b6fc74d4cad7f9Andreas Gustafsson "message has %u byte(s) of trailing garbage",
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington isc_buffer_usedregion(&origsource, &msg->saved);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->saved.length = isc_buffer_usedlength(&origsource);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length);
e851ea826066ac5a5b01c2c23218faa0273a12e8Evan Hunt memmove(msg->saved.base, isc_buffer_base(&origsource),
e43b9a20054cdda6946ab758e1c2005f2b25641aBrian Wellingtondns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Erase the contents of this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Make certain there is enough for at least the header in this
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews if (r.length - DNS_MESSAGE_HEADERLEN < msg->reserved)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Reserve enough space for the header in this buffer.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Ensure that the new buffer is empty, and has enough space to
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * hold the current contents.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Copy the contents from the old to the new buffer.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderrelease(dns_message_t *msg, unsigned int space) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderreserve(dns_message_t *msg, unsigned int space) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_availableregion(msg->buffer, &r);
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrewswrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * If we are not rendering class IN, this ordering is bogus.
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt * Decide whether to not answer with an AAAA record and its RRSIG
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrewsnorender_rdataset(const dns_rdataset_t *rdataset, unsigned int options,
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0)
c8aa7ce70d75d5d8f28f941e3a522c71e948b166Evan Hunt if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrewsrenderset(dns_rdataset_t *rdataset, dns_name_t *owner_name,
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews unsigned int reserved, unsigned int options, unsigned int *countp)
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews * Shrink the space in the buffer by the reserved amount.
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = dns_rdataset_towire(rdataset, owner_name,
ac9072210cea5283e554f1787876b647a08fda96Mark Andrewsmaybe_clear_ad(dns_message_t *msg, dns_section_t sectionid) {
a920f559c3689f52731519a9d5169ad5814866edMichael Graffdns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff unsigned int options)
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews && (options & DNS_MESSAGERENDER_ORDERED) == 0) {
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) {
c4a9ce445c48a57eed5aa16582b1964cf8cedf87Mark Andrews } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) {
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0)
84185d19c7a9ef1ac23cc6236c8773697d4efeb1Brian Wellington rd_options = DNS_RDATASETTOWIRE_OMITDNSSEC;
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff * Shrink the space in the buffer by the reserved amount.
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews if (msg->buffer->length - msg->buffer->used < msg->reserved)
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews * Render required glue first. Set TC if it won't fit.
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 &&
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) {
e50b75e36ca79f84e2c9b2a12f6e28cbf22aaa83Mark Andrews rdataset->attributes |= DNS_RDATASETATTR_RENDERED;
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next_rdataset = ISC_LIST_NEXT(rdataset, link);
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.
4a61eae6514bfde56f8801ef66f27a8d462bd164Mark Andrews if (norender_rdataset(rdataset, options, sectionid)) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * If out of space, record stats on what we
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rendered so far, and return that status.
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.
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington * If we have rendered non-validated data,
ec772e873bd7f24418049b5b1b5d7c44ff781356Brian Wellington * ensure that the AD bit is not set.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff } while (--pass != 0);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) {
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington REQUIRE(r.length >= DNS_MESSAGE_HEADERLEN);
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT)
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrence msg->counts[DNS_SECTION_AUTHORITY] < 65536 &&
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] < 65536);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * We have an extended rcode but are not using EDNS.
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 if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) &&
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
0fbd29837a5911e0f0a83fca93aa4453200a8ccfMark Andrews if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * If we've got an OPT record, render it.
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley dns_message_renderrelease(msg, msg->opt_reserved);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Set the extended rcode.
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = renderset(msg->opt, dns_rootname, msg->cctx,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a TSIG record, generate and render it.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = renderset(msg->tsig, msg->tsigname, msg->cctx,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] += count;
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a SIG(0) record, generate and render it.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington result = dns_dnssec_signmessage(msg, msg->sig0key);
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.
700d3cb7895b5da2543282d18735d2176d1aff86Mark Andrews result = renderset(msg->sig0, dns_rootname, msg->cctx,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington msg->counts[DNS_SECTION_ADDITIONAL] += count;
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->buffer = NULL; /* forget about this buffer only on success XXX */
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley unsigned int i;
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Reset the message so that it may be rendered again.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley for (i = 0; i < DNS_SECTION_MAX; i++) {
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_message_puttempname(msg, &msg->tsigname);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_message_puttemprdataset(msg, &msg->tsig);
94baac869a70b529a24ff23d8dc899faa5d4fdc4Brian Wellington dns_message_puttemprdataset(msg, &msg->sig0);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_firstname(dns_message_t *msg, dns_section_t section) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_nextname(dns_message_t *msg, dns_section_t section) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_currentname(dns_message_t *msg, dns_section_t section,
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_findname(dns_message_t *msg, dns_section_t section,
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.
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman REQUIRE(rdataset == NULL || *rdataset == NULL);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff * And now look for the type.
9da98335c185c39591150ccb4e307adc4cea44bcMukund Sivaraman if (ISC_UNLIKELY(type == dns_rdatatype_any))
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(foundname, type, covers, rdataset);
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_movename(dns_message_t *msg, dns_name_t *name,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Unlink the name from the old section
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(msg->sections[tosection], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_addname(dns_message_t *msg, dns_name_t *name,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(msg->sections[section], name, link);
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrewsdns_message_removename(dns_message_t *msg, dns_name_t *name,
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
f27eae9cfeb5b6c3c38ead6a7a0b1dd36bba691dMark Andrews ISC_LIST_UNLINK(msg->sections[section], name, link);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtondns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellingtondns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graffdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff unsigned int *flagsp)
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
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.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * This saves the query TSIG status, if the query was signed, and
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * reserves space in the reply for the TSIG.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->querytsigstatus == dns_tsigerror_badtime)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = spacefortsig(msg->tsigkey, otherlen);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_renderreserve(msg, msg->sig_reserved);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Get the OPT record for 'msg'.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Set the OPT record for 'msg'.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * The space required for an OPT record is:
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 * plus the length of the rdata.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley result = dns_message_renderreserve(msg, msg->opt_reserved);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Get the TSIG record and owner for 'msg'.
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington * Set the TSIG key for 'msg'
5a680f4170ba77be1e31cf1fc40ab43856919078Mark Andrews dns_message_renderrelease(msg, msg->sig_reserved);
97527fc03cdb061759e2c9529c670ac1c190ef84Brian Wellington REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->sig_reserved = spacefortsig(msg->tsigkey, 0);
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_message_gettsigkey(dns_message_t *msg) {
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellington * Get the TSIG key for 'msg'
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_gettemprdata(msg, &rdata);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_gettemprdatalist(msg, &list);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_gettemprdataset(msg, &set);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = isc_buffer_allocate(msg->mctx, &buf, r.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_rdatalist_tordataset(list, set);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(querytsig != NULL && *querytsig == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = isc_buffer_allocate(mctx, querytsig, r.length);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_buffer_putmem(*querytsig, r.base, r.length);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellingtondns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Get the SIG(0) record for 'msg'.
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.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_setsig0key(dns_message_t *msg, dst_key_t *key) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int x;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Set the SIG(0) key for 'msg'
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * The space required for an SIG(0) record is:
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 REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
97527fc03cdb061759e2c9529c670ac1c190ef84Brian Wellington REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_message_renderreserve(msg, msg->sig_reserved);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_getsig0key(dns_message_t *msg) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Get the SIG(0) key for 'msg'
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellingtondns_message_signer(dns_message_t *msg, dns_name_t *signer) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->tsig == NULL && msg->sig0 == NULL)
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_rdata_tostruct(&rdata, &sig, NULL);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington result = dns_rdata_tostruct(&rdata, &tsig, NULL);
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
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington identity = dns_tsigkey_identity(msg->tsigkey);
880723fb130841459d45695b387651cacd6c9bb8Mark Andrewsdns_message_rechecksig(dns_message_t *msg, dns_view_t *view) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrewsdns_message_dumpsig(dns_message_t *msg, char *txt1) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_current(msg->tsig, &querytsigrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_rdataset_current(msg->querytsig, &querytsigrdata);
f1263d2aa405087e74caf001cd443079f50ee903Mark Andrews result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews hexdump(txt1, "QUERYTSIG", querytsig.signature,
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtondns_message_checksig(dns_message_t *msg, dns_view_t *view) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL)
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington if (msg->tsigkey != NULL || msg->tsig != NULL) {
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews dns_message_dumpsig(msg, "dns_message_checksig#1");
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington return (dns_view_checksig(view, &msgb, msg));
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington return (dns_tsig_verify(&msgb, msg, NULL, NULL));
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.
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdata_tostruct(&rdata, &sig, msg->mctx);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_view_simplefind(view, &sig.signer,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /* XXXBEW Should possibly create a fetch here */
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington } else if (keyset.trust < dns_trust_secure) {
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington /* XXXBEW Should call a validator here */
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence isc_buffer_init(&b, rdata.data, rdata.length);
5c29047792191d6141f69b2684314d0b762fedebBrian Wellington result = dst_key_fromdns(&sig.signer, rdata.rdclass,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington !(dst_key_proto(key) == DNS_KEYPROTO_DNSSEC ||
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_dnssec_verifymessage(&msgb, msg, key);
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews unsigned int __i; \
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews dns_masterstyle_flags_t __flags = dns_master_styleflags(sp); \
fd71f5a87fbef60a9c8823495765723a40bed641Mark Andrews if ((__flags & DNS_STYLEFLAG_INDENT) == 0ULL && \
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } while (0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_firstname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_message_currentname(msg, section, &name);
13396661f46572d7b94703a25721aad040fbd91aMark Andrews if ((flags & DNS_MESSAGETEXTFLAG_OMITSOA) != 0)
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrewsrender_ecs(isc_buffer_t *ecsbuf, isc_buffer_t *target) {
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * Note: This routine needs to handle malformed ECS options.
292eb9c4e4fc51aec911e72821735a123a8c252aMark Andrews if (isc_buffer_remaininglength(ecsbuf) < addrbytes)
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt for (i = 0; i < addrbytes; i ++)
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt inet_ntop(AF_INET, addr, addr_text, sizeof(addr_text));
d7b9756a214030b0022ce791b67b12fb7bceeea0Evan Hunt inet_ntop(AF_INET6, addr, addr_text, sizeof(addr_text));
11463c0ac24692e229ec87f307f5e7df3c0a7e10Evan Hunt snprintf(addr_text, sizeof(addr_text), "/%d/%d", addrlen, scopelen);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (mbz != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * Print EDNS info, if any.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * WARNING: The option contents may be malformed as
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * dig +ednsopt=value:<content> does not validity
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * checking.
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews while (optlen > 0U) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if (optlen != 0) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk for (i = 0; i < optlen; i++) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * Valid server cookie?
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * Server cookie is not valid but
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * we had our cookie echoed back.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * We didn't get our cookie echoed
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * For non-COOKIE options, add a printable
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk for (i = 0; i < optlen; i++) {
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_master_rdatasettotext(name, ps, style, target);
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk result = dns_master_rdatasettotext(name, ps, style, target);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_pseudosectiontotext(dns_message_t *msg,
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk if ((dns_master_styleflags(style) & DNS_STYLEFLAG_YAML) != 0)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk return (dns_message_pseudosectiontoyaml(msg, section, style,
b66b333f59cf51ef87f973084a5023acd9317fb2Evan Hunt if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews mbz &= ~DNS_MESSAGEEXTFLAG_DO; /* Known Flags. */
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * Print EDNS info, if any.
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * WARNING: The option contents may be malformed as
bd08b82891ea6abb339d06d86734df7f4febf533Mark Andrews * dig +ednsopt=value:<content> does not validity
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews isc_buffer_init(&optbuf, rdata.data, rdata.length);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews while (isc_buffer_remaininglength(&optbuf) != 0) {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews INSIST(isc_buffer_remaininglength(&optbuf) >= 4U);
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews INSIST(isc_buffer_remaininglength(&optbuf) >= optlen);
a64daf673deff2358a91bee26bbf2bf874f47c6eMark Andrews while (optlen > 0U) {
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews for (i = 0; i < optlen; i++) {
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * Valid server cookie?
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * Server cookie is not valid but
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * we had our cookie echoed back.
6aaf3d01a1a9829802498c5772b22d649d012181Mark Andrews * We didn't get our cookie echoed
ce67023ae3ad39a77da5361d0187ab6f3f0219cbMark Andrews * For non-COOKIE options, add a printable
586d94eb740587975d5348b22a5fb8440d95925dMark Andrews if (isc_buffer_availablelength(target) < optlen)
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews for (i = 0; i < optlen; i++) {
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)
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)
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellingtondns_message_totext(dns_message_t *msg, const dns_master_style_t *style,
f647c0df9fd334b19a5bdc9c252f90d94c0abf1eMark Andrews dns_messagetextflag_t flags, isc_buffer_t *target)
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk * The final unnamed flag must be zero.
b1866070ef4fb9e17bff16ad458f629bbc5a4accwpk } else if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
e18c62b1dab6bf82530a94c00e2320e542f40c3fMark Andrews * The final unnamed flag must be zero.
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_pseudosectiontotext(msg,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_QUESTION,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_ANSWER,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_AUTHORITY,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_sectiontotext(msg, DNS_SECTION_ADDITIONAL,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_pseudosectiontotext(msg,
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_pseudosectiontotext(msg,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafssondns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order,
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrewsdns_message_settimeadjust(dns_message_t *msg, int timeadjust) {
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrewsdns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) {
5bd76af084edfdcd1cb4db9453ac781d32dde6f7Mark Andrews if (isc_buffer_availablelength(target) < strlen(opcodetext[opcode]))
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrewsdns_message_logpacket(dns_message_t *message, const char *description,
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_logcategory_t *category, isc_logmodule_t *module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, NULL, category, module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews const char *description, isc_sockaddr_t *address,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_logcategory_t *category, isc_logmodule_t *module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, address, category, module,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Huntdns_message_logfmtpacket(dns_message_t *message, const char *description,
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt isc_logcategory_t *category, isc_logmodule_t *module,
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews logfmtpacket(message, description, NULL, category, module, style,
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 logfmtpacket(message, description, address, category, module, style,
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,
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews * Note that these are multiline debug messages. We want a newline
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews * to appear in the log after each message.
dda69168ead4bb44f5a23949a04ee2069b7d4ef0Mark Andrews isc_sockaddr_format(address, addrbuf, sizeof(addrbuf));
1d761cb453c76353deb8423c78e98d00c5f86ffaEvan Hunt result = dns_message_totext(message, style, 0, &buffer);
8a4689070a0b13935822e1bb7138d1d2f8ce237bMark Andrews isc_log_write(dns_lctx, category, module, level,
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrewsdns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp,
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews unsigned int flags, dns_ednsopt_t *ednsopts, size_t count)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_message_gettemprdatalist(message, &rdatalist);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_message_gettemprdata(message, &rdata);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_message_gettemprdataset(message, &rdataset);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews * Set Maximum UDP buffer size.
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews * Set EXTENDED-RCODE and Z to 0.
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews * Set EDNS options if applicable
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews for (i = 0; i < count; i++)
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = isc_buffer_allocate(message->mctx, &buf, len);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews for (i = 0; i < count; i++) {
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews result = dns_rdatalist_tordataset(rdatalist, rdataset);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_message_puttemprdataset(message, &rdataset);
4adf97c32fcca7d00e5756607fd045f2aab9c3d4Mark Andrews dns_message_puttemprdatalist(message, &rdatalist);
c8821d124c532e0a65752b378f924d4259499fd3Mark Andrewsdns_message_setclass(dns_message_t *msg, dns_rdataclass_t rdclass) {