message.c revision 806c235ecf533b98d068b3f8df9d7abbe1e30cf9
a7038d1a0513c8e804937ebc95fc9cb3a46c04f5Mark Andrews * Copyright (C) 1999-2002 Internet Software Consortium.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Permission to use, copy, modify, and distribute this software for any
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * purpose with or without fee is hereby granted, provided that the above
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * copyright notice and this permission notice appear in all copies.
15a44745412679c30a6d022733925af70a38b715David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
15a44745412679c30a6d022733925af70a38b715David Lawrence * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
15a44745412679c30a6d022733925af70a38b715David Lawrence * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
15a44745412679c30a6d022733925af70a38b715David Lawrence * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15a44745412679c30a6d022733925af70a38b715David Lawrence * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
15a44745412679c30a6d022733925af70a38b715David Lawrence * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
806c235ecf533b98d068b3f8df9d7abbe1e30cf9Mark Andrews/* $Id: message.c,v 1.217 2003/04/11 07:25:25 marka Exp $ */
6028d1ce0380d0ba7f6c6ecd1ad20b31ddd1becbDavid Lawrence#include <isc/string.h> /* Required for HP/UX (and others?) */
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) \
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
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *sectiontext[] = {
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyerstatic const char *updsectiontext[] = {
58c40ca8bda08458804d7f15cf97942dea2a17acMichael Sawyer "PREREQUISITE",
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *opcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED10",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
6d12fdf96621801e80f3f4c2a8a569fe48766a20David Lawrencestatic const char *rcodetext[] = {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED11",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED12",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED13",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED14",
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer "RESERVED15",
f9df80f4348ef68043903efa08299480324f4823Michael Graff * "helper" type, which consists of a block of some type, and is linkable.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
f9df80f4348ef68043903efa08299480324f4823Michael Graff * size, or the allocated elements will not be alligned correctly.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff unsigned int count;
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);
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 unsigned int length;
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 unsigned int length;
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);
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),
d8f304288d2fb29fccd2da1672d72ea06af73f8dMichael Graff isc_mempool_setfreemax(m->rdspool, NAME_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);
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrencedns_message_reset(dns_message_t *msg, unsigned int intent) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(msg->mctx, msg, sizeof(dns_message_t));
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafssonfindname(dns_name_t **foundname, dns_name_t *target,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graffdns_message_findtype(dns_name_t *name, dns_rdatatype_t type,
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff dns_rdatatype_t covers, dns_rdataset_t **rdataset)
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,
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int tries;
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,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int tries;
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,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int count;
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.
97e7d389d54a9e3a1ba8313ed140b04afabc7081Michael Graff * Can't ask the same question twice.
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(name, 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));
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
6850cdd4497424c9d42ade487edfde9fb9a47de9Brian Wellington dns_section_t sectionid, unsigned int options)
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.
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_key /* in a TKEY query */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_sig /* SIG(0) */
0e5d6900bdfcbeef8919e6fb453ca6c44f62ccd8Brian Wellington && rdtype != dns_rdatatype_tkey /* Win2000 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
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * never dereferenced, but it must still be non-NULL.
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * Casting 1 rather than "" avoids warnings about
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * discarding the const attribute of a string,
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews * for compilers that would warn about such things.
ecb6c5782ea248307e86c4bceac6c371d27576a6David Lawrence result = getrdata(source, msg, dctx, rdclass,
99eba32b06d21623b14161bd6543c91201d9cbafAndreas Gustafsson result = getrdata(source, msg, dctx, msg->rdclass,
c03bb27f0675a6e60ceea66b451548e8481bc05cMark Andrews if (rdtype == dns_rdatatype_sig && rdata->flags == 0) {
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.
186817c92c7bd1a65aa562d73415abee2e79922bMichael Graff result = dns_message_findtype(name, rdtype, covers,
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.
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * Section 5.2 of RFC 2181 says we should drop
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * nonauthoritative rrsets where the TTLs differ, but we
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * currently treat them the as if they were authoritative and
7ab5937e0b0d5d83e6f4eb1e50a4b041fb68df48Bob Halley * minimize them.
59602a44858a55fce25565491d4fec6d2cdcca19Michael Graff rdataset->attributes |= DNS_RDATASETATTR_TTLADJUSTED;
d49555e76c5d02943fdd6606113aebf2317390d5Michael Graff * XXXMLG Perform a totally ugly hack here to pull
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * the rdatalist out of the private field in the rdataset,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * and append this rdata to the rdatalist's linked list
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff rdatalist = (dns_rdatalist_t *)(rdataset->private1);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley * If this is an OPT record, remember it. Also, set
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * the extended rcode. Note that msg->opt will only be set
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * if best-effort parsing is enabled.
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington if (rdtype == dns_rdatatype_opt && msg->opt == NULL) {
3d4d93c35b5992bd5c32eb913d258be72f88adf5Andreas Gustafsson ((msg->opt->ttl & DNS_MESSAGE_EDNSRCODE_MASK)
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * If this is an SIG(0) or TSIG record, remember it. Note
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * that msg->sig0 or msg->tsig will only be set if best-effort
f70336b8c9528cb9e4d4add3553041f0db85a006Brian Wellington * parsing is enabled.
5d727330e46c8073703aea7cc0771a456db86829Andreas Gustafsson } else if (rdtype == dns_rdatatype_tsig && msg->tsig == NULL) {
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);
efcd38346161b10d60368411cfb2c0d1c22b5fb1Brian Wellington memcpy(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
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.
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.
03f91269f5453bcbd924910ef85a8f8496cf2661Mark Andrews if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff next_rdataset = ISC_LIST_NEXT(rdataset, link);
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
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * sets starting at some arbitary point in the
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * set. This will include setting a bit in the
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rdataset to indicate that a partial
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * rendering was done, and some state saved
1a69a1a78cfaa86f3b68bbc965232b7876d4da2aDavid Lawrence * somewhere (probably in the message struct)
733b16eb0be2e15fa70db85291b386a3bef1d77cMichael Graff * to indicate where to continue from.
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 unsigned int count;
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.
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.
ac77fece9a62537a9e0e5852498ebeda7b2978c3Bob Halley result = dns_rdataset_towire(msg->opt, dns_rootname,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a TSIG or SIG(0) to a truncated message,
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * clear all rdatasets from the message except for the question
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington * before adding the TSIG or SIG(0). If the question doesn't fit,
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington * don't include it.
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington if ((msg->tsigkey != NULL || msg->sig0key != NULL) &&
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
fff07c1022643da7274d4ba1b086c9c218762dc9Brian Wellington if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington * If we're adding a TSIG record, generate and render it.
0f80bfec687db08a6e6ce945ef1d818da06c7ca9Brian Wellington dns_message_renderrelease(msg, msg->sig_reserved);
fe0e3c7707580da885bb6819e4f307986eb60cd0Brian Wellington result = dns_rdataset_towire(msg->tsig, msg->tsigname,
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.
5caab9f99d19ab9ebb0a0ba64c09c8de80e89e29Brian Wellington result = dns_rdataset_towire(msg->sig0, dns_rootname,
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.
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff * And now look for the type.
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);
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)
4c208bd46f94379b011b57ee7edb84ac9c706704Michael Graff unsigned int flags;
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 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);
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'
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) {
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) {
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);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyerdns_message_sectiontotext(dns_message_t *msg, dns_section_t section,
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer result = dns_message_firstname(msg, section);
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer dns_message_currentname(msg, section, &name);
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0 &&
c9c5b25473f3ef04ba2cfe00b21869f8050dd921Michael Sawyer (flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
1ed4ba5a1fcb6aecd1c92fdcc75c6b4bbb7cc60fMichael Sawyerdns_message_pseudosectiontotext(dns_message_t *msg,
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson if ((flags & DNS_MESSAGETEXTFLAG_NOCOMMENTS) == 0)
ab3f2d77bddef25a0af62d89894cb4964ee4f1d8Andreas Gustafsson ADD_STRING(target, ";; OPT PSEUDOSECTION:\n");
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews mbz = ps->ttl & ~DNS_MESSAGEEXTFLAG_DO & 0xffff;
5d7b81d2a49d237ff5e73fdc4bd3394a3ee29392Mark Andrews snprintf(buf, sizeof(buf), "%u\n", (unsigned int)ps->rdclass);
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,
668f8d91db59f4dd89a0b54206f87879354339f5Brian Wellington dns_messagetextflag_t flags, isc_buffer_t *target) {
c7868e2262d57451c7f0ce246be5f44e8c33f1e0Michael Sawyer if ((flags & DNS_MESSAGETEXTFLAG_NOHEADERS) == 0) {
c95a89b433e42ecf9108b6c263f405fecc0d8a65Michael Sawyer ADD_STRING(target, ";; ->>HEADER<<- opcode: ");
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) {