message.c revision 33a4294f442f7505c8e2453beb422b5928ec697c
499b34cea04a46823d003d4c0520c8b03e8513cbBrian Wellington * Copyright (C) 2004-2016 Internet Systems Consortium, Inc. ("ISC")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 1999-2003 Internet Software Consortium.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and/or distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
15a44745412679c30a6d022733925af70a38b715David Lawrence * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
15a44745412679c30a6d022733925af70a38b715David Lawrence * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15a44745412679c30a6d022733925af70a38b715David Lawrence * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
15a44745412679c30a6d022733925af70a38b715David Lawrence * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15a44745412679c30a6d022733925af70a38b715David Lawrence * PERFORMANCE OF THIS SOFTWARE.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff#include <isc/string.h> /* Required for HP/UX (and others?) */
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleyhexdump(const char *msg, const char *msg2, void *base, size_t len) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned char *p;
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int cnt;
78838d3e0cd62423c23de5503910e01884d2104bBrian Wellington printf("*** %s [%s] (%u bytes @ %p)\n", msg, msg2, len, base);
f9df80f4348ef68043903efa08299480324f4823Michael Graff printf(" %02x %c", *p, (isprint(*p) ? *p : ' '));
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_EDNSRCODE_MASK 0xff000000U
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer return(ISC_R_NOSPACE); else \
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer#define OPTOUT(x) (((x)->attributes & DNS_RDATASETATTR_OPTOUT) != 0)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * This is the size of each individual scratchpad buffer, and the numbers
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * of various block allocations used within the server.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * XXXMLG These should come from a config setting.
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrence * Text representation of the different items, for message_totext
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic const char *sectiontext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic const char *updsectiontext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "PREREQUISITE",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerstatic const char *opcodetext[] = {
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED10",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED11",
f9df80f4348ef68043903efa08299480324f4823Michael Graff "RESERVED12",
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff "RESERVED13",
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff "RESERVED14",
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * "helper" type, which consists of a block of some type, and is linkable.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
f9df80f4348ef68043903efa08299480324f4823Michael Graff * size, or the allocated elements will not be aligned correctly.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int count;
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff}; /* dynamically sized */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff ((type *)msgblock_internalget(block, sizeof(type)))
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_internalget(dns_msgblock_t *, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Grafflogfmtpacket(dns_message_t *message, const char *description,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff isc_sockaddr_t *address, isc_logcategory_t *category,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff isc_logmodule_t *module, const dns_master_style_t *style,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * is free, return NULL.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff unsigned int count)
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence unsigned int length;
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * count);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Return an element from the msgblock. If no more are available, return
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffmsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Release memory associated with a message block.
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencestatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffmsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int length;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael 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
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffnewbuffer(dns_message_t *msg, unsigned int size) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
d68838693666ba930ec4143f848c18bff2bfc244Michael 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
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff offsets = msgblock_get(msgblock, dns_offsets_t);
e223094b2248afa2697c531f75e6f84855638becMichael Graff ISC_LIST_APPEND(msg->offsets, msgblock, link);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington offsets = msgblock_get(msgblock, dns_offsets_t);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonstatic inline void
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtonstatic inline void
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington unsigned int i;
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington for (i = 0; i < DNS_SECTION_MAX; i++) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian 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
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffstatic inline void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgresetnames(dns_message_t *msg, unsigned int first_section) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley * Clean up name lists by calling the rdataset disassociate function.
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley for (i = first_section; i < DNS_SECTION_MAX; i++) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->opt_reserved);
d1cbf714097e900ed1703529584d3e1a50e8a4a8Brian Wellington INSIST(dns_rdataset_isassociated(msg->opt));
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtonmsgresetsigs(dns_message_t *msg, isc_boolean_t replying) {
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington INSIST(dns_rdataset_isassociated(msg->tsig));
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson dns_rdataset_disassociate(msg->querytsig);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley } else if (msg->querytsig != NULL && !replying) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington isc_mempool_put(msg->rdspool, msg->querytsig);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff isc_mempool_put(msg->namepool, msg->sig0name);
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * Free all but one (or everything) for this message. This is used by
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff * both dns_message_reset() and dns_message_destroy().
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgreset(dns_message_t *msg, isc_boolean_t everything) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up linked lists.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Run through the free lists, and just unlink anything found there.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * The memory isn't lost since these are part of message blocks we
f9df80f4348ef68043903efa08299480324f4823Michael Graff * have allocated.
f9df80f4348ef68043903efa08299480324f4823Michael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff rdatalist = ISC_LIST_HEAD(msg->freerdatalist);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington next_msgblock = ISC_LIST_NEXT(msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington ISC_LIST_UNLINK(msg->rdatas, msgblock, link);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington msgblock_free(msg->mctx, msgblock, sizeof(dns_rdata_t));
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington * rdatalists could be empty.
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington next_msgblock = ISC_LIST_NEXT(msgblock, link);
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington msgblock_free(msg->mctx, msgblock, sizeof(dns_rdatalist_t));
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff ISC_LIST_UNLINK(msg->offsets, msgblock, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t));
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * cleanup the buffer cleanup list
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ISC_LIST_UNLINK(msg->cleanup, dynbuf, link);
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington * Set other bits to normal default values.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ENSURE(isc_mempool_getallocated(msg->namepool) == 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington ENSURE(isc_mempool_getallocated(msg->rdspool) == 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonstatic unsigned int
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtonspacefortsig(dns_tsigkey_t *key, int otherlen) {
abaec24086f0cc3d7c0994ca9d2247b40eb6aaedBrian Wellington unsigned int x;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * The space required for an TSIG record is:
f9df80f4348ef68043903efa08299480324f4823Michael Graff * n1 bytes for the name
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the type
4556681e191b7c1654639895ce719d98f2822ee2Michael Graff * 2 bytes for the class
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 4 bytes for the ttl
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the rdlength
f9df80f4348ef68043903efa08299480324f4823Michael Graff * n2 bytes for the algorithm name
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * 6 bytes for the time signed
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * 2 bytes for the fudge
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * 2 bytes for the MAC size
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * x bytes for the MAC
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the original id
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the error
f9df80f4348ef68043903efa08299480324f4823Michael Graff * 2 bytes for the other data length
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * y bytes for the other data (at most)
f9df80f4348ef68043903efa08299480324f4823Michael Graff * ---------------------------------
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 26 + n1 + n2 + x + y bytes
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff return (26 + r1.length + r2.length + x + otherlen);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graffdns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
70fd62761dfe44f2254fb63ac3ded1b02663713fMichael Graff unsigned int i;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * No allocations until further notice. Just initialize all lists
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * and other members that are freed in the cleanup phase here.
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff for (i = 0; i < DNS_SECTION_MAX; i++)
703dfde61b044a866875f6217cb34acf0ff298acBrian Wellington * Ok, it is safe to allocate (and then "goto cleanup" if failure)
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mempool_setfreemax(m->namepool, NAME_COUNT);
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mempool_setname(m->namepool, "msg:names");
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isc_mempool_create(m->mctx, sizeof(dns_rdataset_t),
f9df80f4348ef68043903efa08299480324f4823Michael Graff result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE);
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * Cleanup for error returns.
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson isc_mem_putanddetach(&mctx, m, sizeof(dns_message_t));
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafssondns_message_reset(dns_message_t *msg, unsigned int intent) {
428b78e56dc10ea220fadfed11242ceb1d51d0e3Andreas Gustafsson REQUIRE(intent == DNS_MESSAGE_INTENTPARSE
732e0731dec1922747bb3b3147cf2c3d16b22eaaBob Halley isc_mem_putanddetach(&msg->mctx, msg, sizeof(dns_message_t));
e223094b2248afa2697c531f75e6f84855638becMichael Grafffindname(dns_name_t **foundname, dns_name_t *target,
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graffdns_message_find(dns_name_t *name, dns_rdataclass_t rdclass,
e223094b2248afa2697c531f75e6f84855638becMichael Graff REQUIRE(rdataset == NULL || *rdataset == NULL);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff curr->type == type && curr->covers == covers) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graffdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_rdatatype_t covers, dns_rdataset_t **rdataset)
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence REQUIRE(rdataset == NULL || *rdataset == NULL);
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson if (curr->type == type && curr->covers == covers) {
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Read a name from buffer "source".
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafssongetname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int tries;
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * First try: use current buffer.
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson * Second try: allocate a new buffer and use that.
d347e7af94d77a83244cb592291ac0cc4edc4b62Andreas Gustafsson result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellingtongetrdata(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_rdataclass_t rdclass, dns_rdatatype_t rdtype,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int trysize;
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * First try: use current buffer.
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * Second try: allocate a new buffer of size
e223094b2248afa2697c531f75e6f84855638becMichael Graff * max(SCRATCHPAD_SIZE, 2 * compressed_rdatalen)
e223094b2248afa2697c531f75e6f84855638becMichael Graff * (the data will fit if it was not more than 50% compressed)
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Subsequent tries: double buffer size on each try.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff /* XXX possibly change this to a while (tries < 2) loop */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = dns_rdata_fromwire(rdata, rdclass, rdtype,
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington /* XXX DNS_R_RRTOOLONG? */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffgetquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int options)
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int count;
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff section = &msg->sections[DNS_SECTION_QUESTION];
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff for (count = 0; count < msg->counts[DNS_SECTION_QUESTION]; count++) {
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael 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
e223094b2248afa2697c531f75e6f84855638becMichael Graff * name since we no longer need it, and set our name pointer
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * to point to the name we found.
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * If it is the first name in the section, accept it.
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * If it is not, but is not the same as the name already
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * in the question section, append to the section. Note that
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * here in the question section this is illegal, so return
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * FORMERR. In the future, check the opcode to see if
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * this should be legal or not. In either case we no longer
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * need this name pointer.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Get type and class.
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff * If this class is different than the one we already read,
f2762b0d99a9f1cc43f57f713aa632f6abe37892Michael Graff * this is an error.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Is this a TKEY query?
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson * Can't ask the same question twice.
5e1c2afd107815aec1bd72193797356d3d12f24cAndreas Gustafsson result = dns_message_find(name, rdclass, rdtype, 0, NULL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new rdatalist.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Convert rdatalist to rdataset, and attach the latter to
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington result = dns_rdatalist_tordataset(rdatalist, rdataset);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffupdate(dns_section_t section, dns_rdataclass_t rdclass) {
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff return (ISC_TF(rdclass == dns_rdataclass_any ||
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (ISC_TF(rdclass == dns_rdataclass_any));
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrencegetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff dns_section_t sectionid, unsigned int options)
e223094b2248afa2697c531f75e6f84855638becMichael Graff isc_boolean_t preserve_order, best_effort, seen_problem;
e223094b2248afa2697c531f75e6f84855638becMichael Graff preserve_order = ISC_TF(options & DNS_MESSAGEPARSE_PRESERVEORDER);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff best_effort = ISC_TF(options & DNS_MESSAGEPARSE_BESTEFFORT);
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington for (count = 0; count < msg->counts[sectionid]; count++) {
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington isc_boolean_t skip_name_search, skip_type_search;
bf555703f27295798de30fa8c04d727410788f66Bob Halley * Parse the name out of this packet.
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * Get type, class, ttl, and rdatalen. Verify that at least
1672aaee14415d8ce643ce401b4a29635dfd8fd6Brian Wellington * rdatalen bytes remain. (Some of this is deferred to
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * If there was no question section, we may not yet have
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington * established a class. Do so now.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff rdtype != dns_rdatatype_opt && /* class is UDP SIZE */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence rdtype != dns_rdatatype_tsig && /* class is ANY */
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdtype != dns_rdatatype_tkey) { /* class is undefined */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * If this class is different than the one in the question
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * section, bail.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence && rdtype != dns_rdatatype_key /* in a TKEY query */
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * If this is not a TKEY query/response then the KEY
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * record's class needs to match.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (msg->opcode != dns_opcode_update && !msg->tkey &&
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * Special type handling for TSIG, OPT, and TKEY.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * If it is a tsig, verify that it is in the
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * additional data section.
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson } else if (rdtype == dns_rdatatype_opt) {
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson * The name of an OPT record must be ".", it
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * must be in the additional data section, and
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff * it must be the first OPT we've seen.
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington * A TKEY must be in the additional section if this
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington * is a query, and the answer section if this is a
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * response. Unless it's a Win2000 client.
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * Its class is ignored.
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if ((msg->flags & DNS_MESSAGEFLAG_QR) == 0)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * ... now get ttl and rdatalen, and check buffer.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Read the rdata from the wire format. Interpret the
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * rdata according to its actual class, even if it had a
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * DynDNS meta-class in the packet (unless this is a TSIG).
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Then put the meta-class back into the finished rdata.
bf555703f27295798de30fa8c04d727410788f66Bob Halley * When the rdata is empty, the data pointer is
2f6040ed6717dd47da8afb20da053ce408f702a8Bob Halley * never dereferenced, but it must still be non-NULL.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * Casting 1 rather than "" avoids warnings about
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff * discarding the const attribute of a string,
7ec579cd5d07228c0d6cece58b80694ad8d59de9Michael Graff * for compilers that would warn about such things.
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = getrdata(source, msg, dctx, msg->rdclass,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } else if (rdtype == dns_rdatatype_sig /* SIG(0) */ &&
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Check the ownername of NSEC3 records
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff !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
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * to the end of the message.
fb12d257efa7dad8ab467d51cb7e5081f4f22b34Michael Graff if (preserve_order || msg->opcode == dns_opcode_update ||
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * Run through the section, looking to see if this name
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * is already there. If it is found, put back the
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * allocated name since we no longer need it, and set
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff * our name pointer to point to the name we found.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * If it is a new name, append to the section.
2726950412a5c598e123554e4d758fe66a2ebc21Michael Graff * Search name for the particular type and class.
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * Skip this stage if in update mode or this is a meta-type.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (preserve_order || msg->opcode == dns_opcode_update ||
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson * If this is a type that can only occur in
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson * the question section, fail.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_message_find(name, rdclass, rdtype,
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * If we found an rdataset that matches, we need to
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * append this rdata to that set. If we did not, we need
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington * to create a new rdatalist, store the important bits there,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * convert it to an rdataset, and link the latter to the name.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * Yuck. When appending, make certain that the type isn't
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * a singleton type, such as SOA or CNAME.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * Note that this check will be bypassed when preserving order,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington * the opcode is an update, or the type search is skipped.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Minimize TTLs.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Section 5.2 of RFC2181 says we should drop
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * nonauthoritative rrsets where the TTLs differ, but we
21e82177fbe363a28ad79246cd2d236dc65c50f3Brian Wellington * currently treat them the as if they were authoritative and
b02262cbcd550c63f85df76edc6fff556ea5e95dMichael Graff * minimize them.
e223094b2248afa2697c531f75e6f84855638becMichael Graff rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff /* Append this rdata to the rdataset. */
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff dns_rdatalist_fromrdataset(rdataset, &rdatalist);
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
94a08e09db3dc844b6ee4841c368a2d7074a9c3fAndreas Gustafsson * If this is an OPT, SIG(0) or TSIG record, remember it.
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * Also, set the extended rcode for TSIG.
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington * Note msg->opt, msg->sig0 and msg->tsig will only be
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington * already set if best-effort parsing is enabled otherwise
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington * there will only be at most one of each.
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington } else if (issigzero && msg->sig0 == NULL) {
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington /* Windows doesn't like TSIG names to be compressed. */
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington msg->tsigname->attributes |= DNS_NAMEATTR_NOCOMPRESS;
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graffdns_message_parse(dns_message_t *msg, isc_buffer_t *source,
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ignore_tc = ISC_TF(options & DNS_MESSAGEPARSE_IGNORETRUNCATION);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->rcode = (dns_rcode_t)(tmpflags & DNS_MESSAGE_RCODE_MASK);
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff msg->flags = (tmpflags & DNS_MESSAGE_FLAG_MASK);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
ddd035637d92035a0d9e2bc32a7e2c9cc8a99d3fMichael Graff msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * -1 means no EDNS.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_ANY);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff dns_decompress_setmethods(&dctx, DNS_COMPRESS_GLOBAL14);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = getquestions(source, msg, &dctx, options);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER, options);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY, options);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL, options);
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff if (r.length != 0) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff "message has %u byte(s) of trailing garbage",
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff if ((options & DNS_MESSAGEPARSE_CLONEBUFFER) == 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff isc_buffer_usedregion(&origsource, &msg->saved);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->saved.length = isc_buffer_usedlength(&origsource);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff msg->saved.base = isc_mem_get(msg->mctx, msg->saved.length);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff memmove(msg->saved.base, isc_buffer_base(&origsource),
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffdns_message_renderbegin(dns_message_t *msg, dns_compress_t *cctx,
f9df80f4348ef68043903efa08299480324f4823Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * Erase the contents of this buffer.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * Make certain there is enough for at least the header in this
41cc03374dc7fd58d3b099d6c921f192a7bbb5f7Michael Graff * Reserve enough space for the header in this buffer.
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff isc_buffer_add(buffer, DNS_MESSAGE_HEADERLEN);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer) {
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * Ensure that the new buffer is empty, and has enough space to
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * hold the current contents.
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * Copy the contents from the old to the new buffer.
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewsdns_message_renderrelease(dns_message_t *msg, unsigned int space) {
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrewsdns_message_renderreserve(dns_message_t *msg, unsigned int space) {
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafsson isc_buffer_availableregion(msg->buffer, &r);
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffwrong_priority(dns_rdataset_t *rds, int pass, dns_rdatatype_t preferred_glue) {
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * If we are not rendering class IN, this ordering is bogus.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Decide whether to not answer with an AAAA record and its RRSIG
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graffnorender_rdataset(const dns_rdataset_t *rdataset, unsigned int options,
bfbf3f2d770dc093ac5c74d5fd716ac9521e8715Michael Graff if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0)
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley if ((options & DNS_MESSAGERENDER_FILTER_AAAA) == 0 ||
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington if ((rdataset->covers == dns_rdatatype_ns) &&
c866769e664ba0a6a5e6f9375245f5ccca393009David Lawrencedns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((options & DNS_MESSAGERENDER_PREFER_A) != 0) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley } else if ((options & DNS_MESSAGERENDER_PREFER_AAAA) != 0) {
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if ((options & DNS_MESSAGERENDER_OMITDNSSEC) == 0)
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Shrink the space in the buffer by the reserved amount.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * Render required glue first. Set TC if it won't fit.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 &&
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) {
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_towirepartial(rdataset,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_towiresorted(rdataset,
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff rdataset->attributes |= DNS_RDATASETATTR_RENDERED;
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellington next_rdataset = ISC_LIST_NEXT(rdataset, link);
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Suppress AAAAs if asked and we are
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * not doing DNSSEC or are breaking DNSSEC.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley * Say so in the AD bit if we break DNSSEC.
435abcf2e22d777afbdccdc3048d0ad3df65240aBob Halley if (norender_rdataset(rdataset, options, sectionid)) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff * If out of space, record stats on what we
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * rendered so far, and return that status.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * XXXMLG Need to change this when
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff * dns_rdataset_towire() can render partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * sets starting at some arbitrary point in the
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley * set. This will include setting a bit in the
f9df80f4348ef68043903efa08299480324f4823Michael Graff * rdataset to indicate that a partial
f9df80f4348ef68043903efa08299480324f4823Michael Graff * rendering was done, and some state saved
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * somewhere (probably in the message struct)
f9df80f4348ef68043903efa08299480324f4823Michael Graff * to indicate where to continue from.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * If we have rendered non-validated data,
f9df80f4348ef68043903efa08299480324f4823Michael Graff * ensure that the AD bit is not set.
f9df80f4348ef68043903efa08299480324f4823Michael Graff } while (--pass != 0);
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_renderheader(dns_message_t *msg, isc_buffer_t *target) {
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff tmp = ((msg->opcode << DNS_MESSAGE_OPCODE_SHIFT)
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff INSIST(msg->counts[DNS_SECTION_QUESTION] < 65536 &&
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_QUESTION]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_ANSWER]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_AUTHORITY]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff (isc_uint16_t)msg->counts[DNS_SECTION_ADDITIONAL]);
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int count;
f9df80f4348ef68043903efa08299480324f4823Michael Graff if ((msg->rcode & ~DNS_MESSAGE_RCODE_MASK) != 0 && msg->opt == NULL) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff * We have an extended rcode but are not using EDNS.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * If we're adding a OPT, TSIG or SIG(0) to a truncated message,
f9df80f4348ef68043903efa08299480324f4823Michael Graff * clear all rdatasets from the message except for the question
f9df80f4348ef68043903efa08299480324f4823Michael Graff * before adding the OPT, TSIG or SIG(0). If the question doesn't
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * fit, don't include it.
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) &&
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * If we've got an OPT record, render it.
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff dns_message_renderrelease(msg, msg->opt_reserved);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * Set the extended rcode.
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff result = dns_rdataset_towire(msg->opt, dns_rootname,
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence msg->counts[DNS_SECTION_ADDITIONAL] += count;
419590499823ce15b5d2ad4fe71eaf04bd5a86c0Michael Graff * If we're adding a TSIG record, generate and render it.
499371d17c34a5770af022f4aa15e764e957a803Michael Graff dns_message_renderrelease(msg, msg->sig_reserved);
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley result = dns_rdataset_towire(msg->tsig, msg->tsigname,
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * If we're adding a SIG(0) record, generate and render it.
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington result = dns_dnssec_signmessage(msg, msg->sig0key);
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * Note: dns_rootname is used here, not msg->sig0name, since
55f3daa4ea84859f9753089831a950a4fd9678c3Brian Wellington * the owner name of a SIG(0) is irrelevant, and will not
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff * be set in a message being rendered.
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley result = dns_rdataset_towire(msg->sig0, dns_rootname,
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff msg->buffer = NULL; /* forget about this buffer only on success XXX */
438d7099d1d6109c2df35d5e6f168fb6c40093f6Michael Graff unsigned int i;
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff * Reset the message so that it may be rendered again.
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff for (i = 0; i < DNS_SECTION_MAX; i++) {
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff rds->attributes &= ~DNS_RDATASETATTR_RENDERED;
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halleydns_message_firstname(dns_message_t *msg, dns_section_t section) {
d8705ff90a299e0aa9fc2b4286bc0a71cf221872Bob Halley msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
a6ebd71eed266a08850b5300c2effb18bdb87c8cBob Halleydns_message_nextname(dns_message_t *msg, dns_section_t section) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
6d4886fa7430889a96dbf9b88a2a4eb6f9d04674Brian Wellingtondns_message_currentname(dns_message_t *msg, dns_section_t section,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_findname(dns_message_t *msg, dns_section_t section,
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington * XXX These requirements are probably too intensive, especially
8d6fe3f38895752e3603cf2e1e9a0446b38f20cfBrian Wellington * where things can be NULL, but as they are they ensure that if
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington * something is NON-NULL, indicating that the caller expects it
5c688a008a28f215cd772377774e6a1ed07d0525Brian Wellington * to be filled in, that we can in fact fill it in.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * And now look for the type.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_message_findtype(foundname, type, covers, rdataset);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halleydns_message_movename(dns_message_t *msg, dns_name_t *name,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * Unlink the name from the old section
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
5eb8688b78ddf13d46cd52561301c35d24a5d52aBob Halley ISC_LIST_APPEND(msg->sections[tosection], name, link);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafssondns_message_addname(dns_message_t *msg, dns_name_t *name,
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
1dd8ee4fd5b55752a5003671ddd3b0fd8482faadAndreas Gustafsson ISC_LIST_APPEND(msg->sections[section], name, link);
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graffdns_message_removename(dns_message_t *msg, dns_name_t *name,
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington ISC_LIST_UNLINK(msg->sections[section], name, link);
7a97b7630fb5e43b64152db587b64b21ff8d5d51Brian Wellingtondns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item) {
af602636644fdfaabc331bd926b0aabb9432e152Brian Wellingtondns_message_gettemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttemprdataset(dns_message_t *msg, dns_rdataset_t **item) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington REQUIRE(!dns_rdataset_isassociated(*item));
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_puttemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrewsdns_message_peekheader(isc_buffer_t *source, dns_messageid_t *idp,
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int *flagsp)
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellingtondns_message_reply(dns_message_t *msg, isc_boolean_t want_question_section) {
41faaa9b35bb5b3c72ca964e108ba398eaa63f3dBrian Wellington REQUIRE((msg->flags & DNS_MESSAGEFLAG_QR) == 0);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington msg->from_to_wire = DNS_MESSAGE_INTENTRENDER;
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * We now clear most flags and then set QR, ensuring that the
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * reply's flags will be in a reasonable state.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * This saves the query TSIG status, if the query was signed, and
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * reserves space in the reply for the TSIG.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington unsigned int otherlen = 0;
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);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Get the OPT record for 'msg'.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington * Set the OPT record for 'msg'.
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * The space required for an OPT record is:
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 1 byte for the name
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the type
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the class
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 4 bytes for the ttl
af6e7e5cd2643e2aaaffefe1dd804a03394b4928Michael Graff * 2 bytes for the rdata length
e5c75445501bb0459753f55cf3a9529b3cb794dfBrian Wellington * ---------------------------------
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington * plus the length of the rdata.
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
6e49e91bd08778d7eae45a2229dcf41ed97cc636David Lawrence result = dns_message_renderreserve(msg, msg->opt_reserved);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedns_message_gettsig(dns_message_t *msg, dns_name_t **owner) {
f7fbd68b1cd96c733140fce938a61faf8b459b6fBrian Wellington * Get the TSIG record and owner for 'msg'.
b1a7fea53cb35baf4ca0c6841dce20ef1f90f259Andreas Gustafsson REQUIRE(owner == NULL || *owner == NULL);
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellingtondns_message_settsigkey(dns_message_t *msg, dns_tsigkey_t *key) {
0b764d91c9021259f15b32c4beec852f2888f40cBrian Wellington * Set the TSIG key for 'msg'
c5c779df9a09a9fa73149f38991ae32c92135811Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington REQUIRE(msg->tsigkey == NULL && msg->sig0key == NULL);
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington if (msg->from_to_wire == DNS_MESSAGE_INTENTRENDER) {
5ca7310c8af54c68f3a5d8a84639053472a451b2Brian Wellington msg->sig_reserved = spacefortsig(msg->tsigkey, 0);
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellingtondns_message_gettsigkey(dns_message_t *msg) {
b984520acca2532d048eae929dc0682dd334c7a3Brian Wellington * Get the TSIG key for 'msg'
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellingtondns_message_setquerytsig(dns_message_t *msg, isc_buffer_t *querytsig) {
81b438273a0c3141144d169a7ccb110150757337Brian Wellington result = dns_message_gettemprdata(msg, &rdata);
c637772ac34b4abb76a250eca89930e6f2bc2ce9Brian Wellington result = dns_message_gettemprdatalist(msg, &list);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_message_gettemprdataset(msg, &set);
bb71d64085c044920d978fc706996e7e2c0ccb4eBrian Wellington result = isc_buffer_allocate(msg->mctx, &buf, r.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington dns_rdata_fromregion(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &r);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington result = dns_rdatalist_tordataset(list, set);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellingtondns_message_getquerytsig(dns_message_t *msg, isc_mem_t *mctx,
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington REQUIRE(querytsig != NULL && *querytsig == NULL);
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington result = isc_buffer_allocate(mctx, querytsig, r.length);
6f17d90364f01c3e81073a9ffb40b0093878c8e2Brian Wellington isc_buffer_putmem(*querytsig, r.base, r.length);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_getsig0(dns_message_t *msg, dns_name_t **owner) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * Get the SIG(0) record for 'msg'.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer /* If dns_message_getsig0 is called on a rendered message
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * after the SIG(0) has been applied, we need to return the
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer * root name, not NULL.
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_setsig0key(dns_message_t *msg, dst_key_t *key) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer unsigned int x;
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington * Set the SIG(0) key for 'msg'
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * The space required for an SIG(0) record is:
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * 1 byte for the name
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * 2 bytes for the type
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 2 bytes for the class
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington * 4 bytes for the ttl
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 2 bytes for the type covered
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 1 byte for the algorithm
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington * 1 bytes for the labels
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 4 bytes for the original ttl
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 4 bytes for the signature expiration
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 4 bytes for the signature inception
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * 2 bytes for the key tag
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington * n bytes for the signer's name
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * x bytes for the signature
531eafa3026663020f4a2ac5587cce44341e3442Andreas Gustafsson * ---------------------------------
d1eee4693871f9e02fc8598e2e2f8fac80df25a3Brian Wellington * 27 + n + x bytes
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTRENDER);
194de894f0697562f94e048f573d99260a18a639Michael Sawyer REQUIRE(msg->sig0key == NULL && msg->tsigkey == NULL);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_message_renderreserve(msg, msg->sig_reserved);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer * Get the SIG(0) key for 'msg'
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafssondns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer) {
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ISC_LIST_APPEND(msg->cleanup, *buffer, link);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_signer(dns_message_t *msg, dns_name_t *signer) {
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENTPARSE);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer result = isc_buffer_allocate(msg->mctx, &dynbuf, 512);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdata_tostruct(&rdata, &sig, NULL);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer if (msg->verified_sig && msg->sig0status == dns_rcode_noerror)
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_rdata_tostruct(&rdata, &tsig, NULL);
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer * If msg->tsigstatus & tsig.error are both
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer * dns_rcode_noerror, the message must have been
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer * verified, which means msg->tsigkey will be
9b3a69e6a701ffe2fc49fbb750d0761b3a822b37Michael Sawyer identity = dns_tsigkey_identity(msg->tsigkey);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_rechecksig(dns_message_t *msg, dns_view_t *view) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_dumpsig(dns_message_t *msg, char *txt1) {
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer dns_rdataset_current(msg->tsig, &querytsigrdata);
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyer result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews dns_rdataset_current(msg->querytsig, &querytsigrdata);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews result = dns_rdata_tostruct(&querytsigrdata, &querytsig, NULL);
5126112bc3639b9dae5726c3148d6699d277e789Mark Andrews hexdump(txt1, "QUERYTSIG", querytsig.signature,
febaa091847ab004f40500cc475a819f2c73fcddAndreas Gustafssondns_message_checksig(dns_message_t *msg, dns_view_t *view) {
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews if (msg->tsigkey == NULL && msg->tsig == NULL && msg->sig0 == NULL)
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews isc_buffer_init(&msgb, msg->saved.base, msg->saved.length);
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews if (msg->tsigkey != NULL || msg->tsig != NULL) {
19c7cce8555ccc0c95455a0c35dedd017d420d05Mark Andrews dns_message_dumpsig(msg, "dns_message_checksig#1");
return (ISC_R_UNEXPECTEDEND);
return (result);
return (DNS_R_KEYUNAUTHORIZED);
goto freesig;
goto freesig;
return (result);
return (ISC_R_SUCCESS);
return (result);
if (seensoa &&
target);
target);
return (result);
return (result);
static isc_result_t
return (DNS_R_OPTERR);
return (DNS_R_OPTERR);
return (DNS_R_OPTERR);
for (i = 0; i < addrbytes; i ++)
return (DNS_R_OPTERR);
return (DNS_R_OPTERR);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
unsigned char *optdata;
switch (section) {
case DNS_PSEUDOSECTION_OPT:
return (ISC_R_SUCCESS);
if (mbz != 0) {
return (ISC_R_SUCCESS);
optlen);
return (result);
target);
return (result);
if (optlen != 0) {
for (i = 0; i < optlen; i++) {
const char *sep;
switch (optcode) {
case DNS_OPT_COOKIE:
return (ISC_R_NOSPACE);
for (i = 0; i < optlen; i++) {
&optdata[i],
return (ISC_R_SUCCESS);
case DNS_PSEUDOSECTION_TSIG:
return (ISC_R_SUCCESS);
return (result);
case DNS_PSEUDOSECTION_SIG0:
return (ISC_R_SUCCESS);
return (result);
return (ISC_R_UNEXPECTED);
return (result);
return (result);
return (result);
return (result);
return (result);
return (result);
return (result);
return (result);
return (ISC_R_SUCCESS);
const void *order_arg)
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
buf);
unsigned int len = 0, i;
return (result);
goto cleanup;
goto cleanup;
if (count != 0U) {
for (i = 0; i < count; i++)
goto cleanup;
goto cleanup;
for (i = 0; i < count; i++) {
return (ISC_R_SUCCESS);
return (result);