message.c revision 8d6024e7cffbd84fa8d06ce50c60307d7b3b49c2
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Copyright (C) 1999 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.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_MESSAGE(msg) (((msg)->magic) == MESSAGE_MAGIC)
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
f9df80f4348ef68043903efa08299480324f4823Michael Graff#define VALID_SECTION(s) (((s) >= DNS_SECTION_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.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff#define RDATALIST_COUNT 32 /* should match RDATASET_COUNT */
f9df80f4348ef68043903efa08299480324f4823Michael Graff * "helper" type, which consists of a block of some type, and is linkable.
f9df80f4348ef68043903efa08299480324f4823Michael Graff * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
f9df80f4348ef68043903efa08299480324f4823Michael Graff * size, or the allocated elements will not be alligned correctly.
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int length;
f9df80f4348ef68043903efa08299480324f4823Michael Graff}; /* dynamically sized */
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ((type *)msgblock_internalget(block, sizeof(type)))
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_internalget(dns_msgblock_t *, unsigned int);
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_reset(dns_msgblock_t *, unsigned int);
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_allocate(isc_mem_t *, unsigned int, 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 *
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type)
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_reset(dns_msgblock_t *block, unsigned int count)
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graff * Release memory associated with a message block.
9178881e1bf6a4b01db886b355406c8bed61cc2aMichael Graffstatic inline void
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * Allocate a new dynamic buffer, and attach it to this message as the
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * "current" buffer. (which is always the last on the list, for our
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff result = isc_dynbuffer_allocate(msg->mctx, &dynbuf, SCRATCHPAD_SIZE,
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleasename(dns_message_t *msg, dns_name_t *name)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline dns_name_t *
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx, sizeof(dns_name_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleaserdata(dns_message_t *msg, dns_rdata_t *rdata)
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 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);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffreleaserdataset(dns_message_t *msg, dns_rdataset_t *rdataset)
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdataset = msgblock_get(msgblock, dns_rdataset_t);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdataset_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_APPEND(msg->rdatasets, msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff rdataset = msgblock_get(msgblock, dns_rdataset_t);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Init elements to default state. Used both when allocating a new element
f9df80f4348ef68043903efa08299480324f4823Michael Graff * and when resetting one.
f9df80f4348ef68043903efa08299480324f4823Michael Graffstatic inline void
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff unsigned int i;
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (i = 0 ; i < DNS_SECTION_MAX ; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Free all but one (or everything) for this message. This is used by
f9df80f4348ef68043903efa08299480324f4823Michael Graff * both dns_message_reset() and dns_message_parse().
f9df80f4348ef68043903efa08299480324f4823Michael Graffmsgreset(dns_message_t *msg, isc_boolean_t everything)
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up name lists by calling the rdataset disassociate function.
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (i = 0 ; i < DNS_SECTION_MAX ; i++) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->sections[i], name, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Clean up linked lists.
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ISC_LIST_UNLINK(msg->rdatasets, msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff if (msg->from_to_wire == DNS_MESSAGE_INTENT_PARSE) {
f9df80f4348ef68043903efa08299480324f4823Michael Graff next_msgblock = ISC_LIST_NEXT(msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Set other bits to normal default values.
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent)
f9df80f4348ef68043903efa08299480324f4823Michael Graff unsigned int i;
f9df80f4348ef68043903efa08299480324f4823Michael Graff for (i = 0 ; i < DNS_SECTION_MAX ; i++)
f9df80f4348ef68043903efa08299480324f4823Michael Graff iresult = isc_dynbuffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE,
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = msgblock_allocate(mctx, sizeof(dns_name_t),
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = msgblock_allocate(mctx, sizeof(dns_rdata_t),
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff msgblock = msgblock_allocate(mctx, sizeof(dns_rdataset_t),
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff ISC_LIST_APPEND(m->rdatasets, msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff msgblock = msgblock_allocate(mctx, sizeof(dns_rdatalist_t),
f9df80f4348ef68043903efa08299480324f4823Michael Graff ISC_LIST_APPEND(m->rdatalists, msgblock, link);
f9df80f4348ef68043903efa08299480324f4823Michael Graff * Cleanup for error returns.
f9df80f4348ef68043903efa08299480324f4823Michael Graff isc_mem_put(msg->mctx, msg, sizeof(dns_message_t));
e223094b2248afa2697c531f75e6f84855638becMichael Grafffindname(dns_name_t **foundname, dns_name_t *target, dns_namelist_t *section)
e223094b2248afa2697c531f75e6f84855638becMichael Grafffindtype(dns_rdataset_t **rdataset, dns_name_t *name, dns_rdatatype_t type)
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Read a name from buffer "source".
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Assumes dns_name_init() was already called on this name.
e223094b2248afa2697c531f75e6f84855638becMichael Graffgetname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int tries;
e223094b2248afa2697c531f75e6f84855638becMichael Graff if (dns_decompress_edns(dctx) > 1 || !dns_decompress_strict(dctx))
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL);
e223094b2248afa2697c531f75e6f84855638becMichael Graff dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
e223094b2248afa2697c531f75e6f84855638becMichael Graff result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
e223094b2248afa2697c531f75e6f84855638becMichael Graff return (DNS_R_UNEXPECTED); /* should never get here... XXXMLG */
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graffgetrdata(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_decompress_t *dctx, dns_rdataclass_t rdclass,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdatatype_t rdtype, unsigned int rdatalen, dns_rdata_t *rdata)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff unsigned int tries;
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff result = dns_rdata_fromwire(rdata, rdclass, rdtype,
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff return (DNS_R_UNEXPECTED); /* should never get here... XXXMLG */
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetquestions(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];
e223094b2248afa2697c531f75e6f84855638becMichael Graff 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.
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.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * If this class is different than the one we alrady read,
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this is an error.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Search name for the particular type and class.
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * If it was found, this is an error, return FORMERR.
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);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffgetsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
e223094b2248afa2697c531f75e6f84855638becMichael Graff unsigned int count;
e223094b2248afa2697c531f75e6f84855638becMichael Graff for (count = 0 ; count < msg->counts[sectionid] ; count++) {
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Parse the name out of this packet.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Run through the section, looking to see if this name
e223094b2248afa2697c531f75e6f84855638becMichael 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
e223094b2248afa2697c531f75e6f84855638becMichael Graff * to point to the name we found.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * If it is a new name, append to the section.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Get type, class, ttl, and rdatalen. Verify that at least
e223094b2248afa2697c531f75e6f84855638becMichael Graff * rdatalen bytes remain. (Some of this is deferred to
e223094b2248afa2697c531f75e6f84855638becMichael Graff * If this class is different than the one we already read,
e223094b2248afa2697c531f75e6f84855638becMichael Graff * this is an error.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * ... now get ttl and rdatalen, and check buffer.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * Search name for the particular type and class.
e223094b2248afa2697c531f75e6f84855638becMichael Graff * If it was found, this is an error, return FORMERR.
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.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff dns_rdatalist_tordataset(rdatalist, rdataset);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * Read the rdata from the wire format.
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff * XXX 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);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graffdns_message_parse(dns_message_t *msg, isc_buffer_t *source)
be3458c3da0e36d1ef8afc74362af9537359a1e4Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENT_PARSE);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->opcode = ((tmpflags & DNS_MESSAGE_OPCODE_MASK)
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->rcode = (tmpflags & DNS_MESSAGE_RCODE_MASK);
fccf7905e8a06067d49ec00c53d4d57a38a71e52Michael Graff msg->flags = (tmpflags & ~DNS_MESSAGE_FLAG_MASK);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_QUESTION] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_ANSWER] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_AUTHORITY] = isc_buffer_getuint16(source);
e223094b2248afa2697c531f75e6f84855638becMichael Graff msg->counts[DNS_SECTION_ADDITIONAL] = isc_buffer_getuint16(source);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_ANSWER);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_AUTHORITY);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff ret = getsection(source, msg, &dctx, DNS_SECTION_ADDITIONAL);
d68838693666ba930ec4143f848c18bff2bfc244Michael Graff * XXXMLG Need to check the tsig(s) here...
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer)
be3458c3da0e36d1ef8afc74362af9537359a1e4Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENT_RENDER);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Erase the contents of this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Make certain there is enough for at least the header in this
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff result = dns_compress_init(&msg->cctx, -1, msg->mctx);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * Reserve enough space for the header in this buffer.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff isc_buffer_add(buffer, DNS_MESSAGE_HEADER_LEN);
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graffdns_message_renderchangebuffer(dns_message_t *msg, isc_buffer_t *buffer)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff * 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.
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_renderrelease(dns_message_t *msg, unsigned int space)
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graffdns_message_renderreserve(dns_message_t *msg, unsigned int space)
f9df80f4348ef68043903efa08299480324f4823Michael Graff * "space" can be positive or negative. If it is negative we are
f9df80f4348ef68043903efa08299480324f4823Michael Graff * removing our reservation of space. If it is positive, we are
f9df80f4348ef68043903efa08299480324f4823Michael Graff * requesting more space to be reserved.
a920f559c3689f52731519a9d5169ad5814866edMichael Graffdns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
a920f559c3689f52731519a9d5169ad5814866edMichael Graff unsigned int used;
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * Set up a temporary buffer to render into, since we want
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * dns_rdataset_towire() to fail if it goes past the reserved
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff isc_buffer_init(&subbuffer, r.base, r.length - msg->reserved,
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff result = dns_name_towire(name, &msg->cctx, &subbuffer);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff next_rdataset = ISC_LIST_NEXT(rdataset, link);
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * If out of space, record stats on what we rendered
1d7987f4227c838f7fa790ad57255d3df3332ccaMichael Graff * so far, and return that status.
e690d225ad09e0b4617554c753b68abc82f0583aMichael Graff msg->buffer = NULL; /* forget about this buffer only on success XXX */
f9df80f4348ef68043903efa08299480324f4823Michael Graff /* XXX implement */
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_firstname(dns_message_t *msg, dns_section_t section)
f9df80f4348ef68043903efa08299480324f4823Michael Graff msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_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 * Search through, looking for the name.
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff result = findname(&foundname, target, &msg->sections[section]);
ded7456a4dc944742c4a98cbf7b055b860b7569cMichael Graff * And now look for the type.
f9df80f4348ef68043903efa08299480324f4823Michael Graffdns_message_movename(dns_message_t *msg, dns_name_t *name,
be3458c3da0e36d1ef8afc74362af9537359a1e4Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENT_RENDER);
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,
be3458c3da0e36d1ef8afc74362af9537359a1e4Michael Graff REQUIRE(msg->from_to_wire == DNS_MESSAGE_INTENT_RENDER);