mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
snapshot work
This commit is contained in:
parent
802a7c6d87
commit
f9df80f434
2 changed files with 516 additions and 44 deletions
|
|
@ -66,26 +66,28 @@ ISC_LANG_BEGINDECLS
|
|||
#define DNS_MESSAGE_OPCODE_SHIFT 11
|
||||
#define DNS_MESSAGE_RCODE_MASK 0x000fU
|
||||
|
||||
/*
|
||||
* Ordering here matters. DNS_SECTION_ANY must be the lowest and negative,
|
||||
* and DNS_SECTION_MAX must be one greater than the last used section.
|
||||
*/
|
||||
typedef int dns_section_t;
|
||||
#define DNS_SECTION_ANY (-1) /* XXX good idea? */
|
||||
#define DNS_SECTION_ANY (-1)
|
||||
#define DNS_SECTION_QUESTION 0
|
||||
#define DNS_SECTION_ANSWER 1
|
||||
#define DNS_SECTION_AUTHORITY 2
|
||||
#define DNS_SECTION_ADDITIONAL 3
|
||||
#define DNS_SECTION_OPT 4 /* pseudo-section */
|
||||
#define DNS_SECTION_TSIG 5 /* pseudo-section */
|
||||
#define DNS_SECTION_MAX 6
|
||||
|
||||
/*
|
||||
* "helper" type, which consists of a block of some type, and is linkable.
|
||||
* For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
|
||||
* size, or the allocated elements will not be alligned correctly.
|
||||
* These tell the message library how the created dns_message_t will be used.
|
||||
*/
|
||||
#define DNS_MESSAGE_INTENT_UNKNOWN 0 /* internal use only */
|
||||
#define DNS_MESSAGE_INTENT_PARSE 1 /* parsing messages */
|
||||
#define DNS_MESSAGE_INTENT_RENDER 2 /* rendering */
|
||||
|
||||
typedef struct dns_msgblock dns_msgblock_t;
|
||||
struct dns_msgblock {
|
||||
unsigned int length;
|
||||
unsigned int remaining;
|
||||
ISC_LINK(dns_msgblock_t) link;
|
||||
}; /* dynamically sized */
|
||||
|
||||
typedef struct {
|
||||
unsigned int magic;
|
||||
|
|
@ -101,26 +103,23 @@ typedef struct {
|
|||
unsigned int aucount;
|
||||
unsigned int adcount;
|
||||
|
||||
dns_namelist_t question;
|
||||
dns_namelist_t answer;
|
||||
dns_namelist_t authority;
|
||||
dns_namelist_t additional;
|
||||
/* 4 real, 2 pseudo */
|
||||
dns_namelist_t sections[DNS_SECTION_MAX];
|
||||
dns_name_t *cursors[DNS_SECTION_MAX];
|
||||
|
||||
unsigned int handled_question : 1;
|
||||
unsigned int handled_answer : 1;
|
||||
unsigned int handled_authority : 1;
|
||||
unsigned int handled_additional : 1;
|
||||
int state;
|
||||
unsigned int from_to_wire : 2;
|
||||
unsigned int reserved;
|
||||
|
||||
isc_mem_t *mctx;
|
||||
isc_dynbuffer_t *scratchpad;
|
||||
ISC_LIST(isc_dynbuffer_t) scratchpad;
|
||||
ISC_LIST(dns_msgblock_t) names;
|
||||
ISC_LIST(dns_msgblock_t) rdatas;
|
||||
ISC_LIST(dns_msgblock_t) rdatalists;
|
||||
} dns_message_t;
|
||||
|
||||
dns_result_t
|
||||
dns_message_init(isc_mem_t *mctx, dns_message_t *msg);
|
||||
dns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent);
|
||||
/*
|
||||
* Initialize msg structure. Must be called on a new (or reused) structure.
|
||||
*
|
||||
|
|
@ -130,14 +129,15 @@ dns_message_init(isc_mem_t *mctx, dns_message_t *msg);
|
|||
* Requires:
|
||||
* 'mctx' be a valid memory context.
|
||||
*
|
||||
* 'msg' be invalid.
|
||||
* 'msg' be non-null and '*msg' be NULL.
|
||||
*
|
||||
* 'intent' must be one of DNS_MESSAGE_INTENT_PARSE or
|
||||
* DNS_MESSAGE_INTENT_RENDER.
|
||||
*
|
||||
* Ensures:
|
||||
* The data in "msg" is set to indicate an unused and empty msg
|
||||
* The data in "*msg" is set to indicate an unused and empty msg
|
||||
* structure.
|
||||
*
|
||||
* Some bit of internal scratchpad memory is allocated.
|
||||
*
|
||||
* Returns:
|
||||
* DNS_R_NOMEMORY - out of memory
|
||||
* DNS_R_SUCCESS - success
|
||||
|
|
@ -160,7 +160,7 @@ dns_message_reset(dns_message_t *msg);
|
|||
*/
|
||||
|
||||
void
|
||||
dns_message_destroy(dns_message_t *msg);
|
||||
dns_message_destroy(dns_message_t **msg);
|
||||
/*
|
||||
* Destroy all state in the message.
|
||||
*
|
||||
|
|
@ -221,7 +221,7 @@ dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer);
|
|||
|
||||
dns_result_t
|
||||
dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
|
||||
int space);
|
||||
unsigned int space);
|
||||
/*
|
||||
* Reserve "space" bytes in the given buffer.
|
||||
*
|
||||
|
|
@ -235,6 +235,21 @@ dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
|
|||
* DNS_R_NOSPACE -- not enough free space in the buffer.
|
||||
*/
|
||||
|
||||
dns_result_t
|
||||
dns_message_renderrelease(dns_message_t *msg, unsigned int space);
|
||||
/*
|
||||
* Release "space" bytes in the given buffer that was previously reserved.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'msg' be valid.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* DNS_R_SUCCESS -- all is well.
|
||||
* DNS_R_NOSPACE -- trying to release more than was reserved.
|
||||
*/
|
||||
|
||||
dns_result_t
|
||||
dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
|
||||
dns_section_t section, unsigned int priority,
|
||||
|
|
@ -306,13 +321,16 @@ dns_message_nextname(dns_message_t *msg, dns_section_t section);
|
|||
*
|
||||
* 'section' be a valid section.
|
||||
*
|
||||
* dns_message_firstname() must have been called on this section,
|
||||
* and the result was DNS_R_SUCCESS.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* DNS_R_SUCCESS -- All is well.
|
||||
* DNS_R_NOMORE -- No names in given section.
|
||||
*/
|
||||
|
||||
dns_result_t
|
||||
void
|
||||
dns_message_currentname(dns_message_t *msg, dns_section_t section,
|
||||
dns_name_t **name);
|
||||
/*
|
||||
|
|
@ -327,10 +345,9 @@ dns_message_currentname(dns_message_t *msg, dns_section_t section,
|
|||
*
|
||||
* 'section' be a valid section.
|
||||
*
|
||||
* Returns:
|
||||
*
|
||||
* DNS_R_SUCCESS -- All is well.
|
||||
* DNS_R_NOMORE -- No names in given section.
|
||||
* dns_message_firstname() must have been called on this section,
|
||||
* and the result of it and any dns_message_nextname() calls was
|
||||
* DNS_R_SUCCESS.
|
||||
*/
|
||||
|
||||
dns_result_t
|
||||
|
|
@ -377,21 +394,31 @@ dns_message_movename(dns_message_t *msg, dns_name_t *name,
|
|||
*
|
||||
* 'msg' be valid.
|
||||
*
|
||||
* 'name' must be a member of the section it is to be moved from.
|
||||
* 'name' must be in 'fromsection'.
|
||||
*
|
||||
* 'fromsection' must be a valid section.
|
||||
*
|
||||
* 'tosection' must be a valid section, and be renderable.
|
||||
*
|
||||
* 'fromsection' and 'tosection' cannot be the same section.
|
||||
*/
|
||||
|
||||
dns_result_t
|
||||
dns_message_addname(dns_message_t *msg, dns_section_t section,
|
||||
dns_name_t *name);
|
||||
void
|
||||
dns_message_addname(dns_message_t *msg, dns_name_t *name,
|
||||
dns_section_t section);
|
||||
/*
|
||||
* Adds the name to the given section.
|
||||
*
|
||||
* Caller must ensure that the name does not already exist. This condition
|
||||
* is NOT checked for by this function.
|
||||
*
|
||||
* Requires:
|
||||
*
|
||||
* 'msg' be valid, and be a renderable message.
|
||||
*
|
||||
* 'name' be a valid name.
|
||||
*
|
||||
* 'section' be a named section.
|
||||
*/
|
||||
|
||||
ISC_LANG_ENDDECLS
|
||||
|
|
|
|||
|
|
@ -25,31 +25,73 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <isc/assertions.h>
|
||||
#include <isc/boolean.h>
|
||||
#include <isc/region.h>
|
||||
|
||||
#include <dns/message.h>
|
||||
#include <dns/rdataset.h>
|
||||
#include <dns/rdata.h>
|
||||
#include <dns/rdataclass.h>
|
||||
#include <dns/rdatatype.h>
|
||||
#include <dns/rdatalist.h>
|
||||
#include <dns/compress.h>
|
||||
|
||||
#define MESSAGE_MAGIC 0x4d534740U /* MSG@ */
|
||||
#define VALID_MESSAGE_MAGIC(magic) ((magic) == MESSAGE_MAGIC)
|
||||
#define VALID_MESSAGE(msg) (((msg)->magic) == MESSAGE_MAGIC)
|
||||
|
||||
#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
|
||||
&& ((s) < DNS_SECTION_MAX))
|
||||
#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
|
||||
&& ((s) < DNS_SECTION_MAX))
|
||||
|
||||
/*
|
||||
* This is the size of each individual scratchpad buffer, and the numbers
|
||||
* of various block allocations used within the server.
|
||||
*/
|
||||
#define SCRATCHPAD_SIZE 768
|
||||
#define NAME_COUNT 16
|
||||
#define RDATA_COUNT 32
|
||||
#define RDATALIST_COUNT 32
|
||||
|
||||
/*
|
||||
* internal state stuff.
|
||||
*/
|
||||
#define TO_FROM_UNKNOWN 0
|
||||
#define TO_FROM_FROMWIRE 1
|
||||
#define TO_FROM_TOWIRE 2
|
||||
|
||||
/*
|
||||
* "helper" type, which consists of a block of some type, and is linkable.
|
||||
* For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
|
||||
* size, or the allocated elements will not be alligned correctly.
|
||||
*/
|
||||
struct dns_msgblock {
|
||||
unsigned int length;
|
||||
unsigned int remaining;
|
||||
ISC_LINK(dns_msgblock_t) link;
|
||||
}; /* dynamically sized */
|
||||
|
||||
static inline void
|
||||
dns_msgblock_free(isc_mem_t *, dns_msgblock_t *);
|
||||
#define dns_msgblock_get(block, type) \
|
||||
((type *)dns_msgblock__get(block, sizeof(type)))
|
||||
msgblock_free(isc_mem_t *, dns_msgblock_t *);
|
||||
#define msgblock_get(block, type) \
|
||||
(((type) *)msgblock_internalget(block, sizeof(type)))
|
||||
|
||||
static inline void *
|
||||
dns_msgblock__get(dns_msgblock_t *, unsigned int);
|
||||
msgblock_internalget(dns_msgblock_t *, unsigned int);
|
||||
|
||||
static inline void
|
||||
msgblock_reset(dns_msgblock_t *, unsigned int);
|
||||
|
||||
static inline dns_msgblock_t *
|
||||
dns_msgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
|
||||
msgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
|
||||
|
||||
/*
|
||||
* Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
|
||||
* is free, return NULL.
|
||||
*/
|
||||
static inline dns_msgblock_t *
|
||||
dns_msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
|
||||
unsigned int count)
|
||||
msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
|
||||
unsigned int count)
|
||||
{
|
||||
dns_msgblock_t *block;
|
||||
unsigned int length;
|
||||
|
|
@ -73,7 +115,7 @@ dns_msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
|
|||
* NULL.
|
||||
*/
|
||||
static inline void *
|
||||
dns_msgblock__get(dns_msgblock_t *block, unsigned int sizeof_type)
|
||||
msgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
|
|
@ -89,11 +131,414 @@ dns_msgblock__get(dns_msgblock_t *block, unsigned int sizeof_type)
|
|||
return (ptr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
msgblock_reset(dns_msgblock_t *block, unsigned int count)
|
||||
{
|
||||
block->remaining = count;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release memory associated with a message block.
|
||||
*/
|
||||
static inline void
|
||||
dns_msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block)
|
||||
msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block)
|
||||
{
|
||||
isc_mem_put(mctx, block, block->length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Init elements to default state. Used both when allocating a new element
|
||||
* and when resetting one.
|
||||
*/
|
||||
static inline void
|
||||
msginit(dns_message_t *m)
|
||||
{
|
||||
m->id = 0;
|
||||
m->flags = 0;
|
||||
m->rcode = 0;
|
||||
m->opcode = 0;
|
||||
m->class = 0;
|
||||
m->qcount = 0;
|
||||
m->ancount = 0;
|
||||
m->aucount = 0;
|
||||
m->adcount = 0;
|
||||
m->state = DNS_SECTION_ANY; /* indicate nothing parsed or rendered */
|
||||
}
|
||||
|
||||
/*
|
||||
* Free all but one (or everything) for this message. This is used by
|
||||
* both dns_message_reset() and dns_message_parse().
|
||||
*/
|
||||
static void
|
||||
msgreset(dns_message_t *msg, isc_boolean_t everything)
|
||||
{
|
||||
dns_msgblock_t *msgblock, *next_msgblock;
|
||||
isc_dynbuffer_t *dynbuf, *next_dynbuf;
|
||||
dns_rdataset_t *rds, *next_rds;
|
||||
dns_name_t *name, *next_name;
|
||||
unsigned int i;
|
||||
|
||||
/*
|
||||
* Clean up name lists by calling the rdataset disassociate function.
|
||||
*/
|
||||
for (i = 0 ; i < DNS_SECTION_MAX ; i++) {
|
||||
name = ISC_LIST_HEAD(msg->sections[i]);
|
||||
while (name != NULL) {
|
||||
next_name = ISC_LIST_NEXT(name, link);
|
||||
ISC_LIST_UNLINK(msg->sections[i], name, link);
|
||||
|
||||
rds = ISC_LIST_HEAD(name->list);
|
||||
while (rds != NULL) {
|
||||
next_rds = ISC_LIST_NEXT(rds, link);
|
||||
ISC_LIST_UNLINK(name->list, rds, link);
|
||||
|
||||
dns_rdataset_disassociate(rds);
|
||||
rds = next_rds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up linked lists.
|
||||
*/
|
||||
|
||||
dynbuf = ISC_LIST_HEAD(msg->scratchpad);
|
||||
INSIST(dynbuf != NULL);
|
||||
if (everything == ISC_FALSE) {
|
||||
isc_dynbuffer_reset(dynbuf);
|
||||
dynbuf = ISC_LIST_NEXT(dynbuf, link);
|
||||
}
|
||||
while (dynbuf != NULL) {
|
||||
next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
|
||||
ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
|
||||
isc_dynbuffer_free(msg->mctx, &dynbuf);
|
||||
dynbuf = next_dynbuf;
|
||||
}
|
||||
|
||||
msgblock = ISC_LIST_HEAD(msg->names);
|
||||
INSIST(msgblock != NULL);
|
||||
if (everything == ISC_FALSE) {
|
||||
msgblock_reset(msgblock, NAME_COUNT);
|
||||
msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
}
|
||||
while (msgblock != NULL) {
|
||||
next_msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
ISC_LIST_UNLINK(msg->names, msgblock, link);
|
||||
msgblock_free(msg->mctx, msgblock);
|
||||
msgblock = next_msgblock;
|
||||
}
|
||||
|
||||
msgblock = ISC_LIST_HEAD(msg->rdatas);
|
||||
INSIST(msgblock != NULL);
|
||||
if (everything == ISC_FALSE) {
|
||||
msgblock_reset(msgblock, RDATA_COUNT);
|
||||
msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
}
|
||||
while (msgblock != NULL) {
|
||||
next_msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
ISC_LIST_UNLINK(msg->rdatas, msgblock, link);
|
||||
msgblock_free(msg->mctx, msgblock);
|
||||
msgblock = next_msgblock;
|
||||
}
|
||||
|
||||
if (msg->from_to_wire == DNS_MESSAGE_INTENT_PARSE) {
|
||||
msgblock = ISC_LIST_HEAD(msg->rdatalists);
|
||||
INSIST(msgblock != NULL);
|
||||
if (everything == ISC_FALSE) {
|
||||
msgblock_reset(msgblock, RDATALIST_COUNT);
|
||||
msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
}
|
||||
while (msgblock != NULL) {
|
||||
next_msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
ISC_LIST_UNLINK(msg->rdatalists, msgblock, link);
|
||||
msgblock_free(msg->mctx, msgblock);
|
||||
msgblock = next_msgblock;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set other bits to normal default values.
|
||||
*/
|
||||
msginit(msg);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent)
|
||||
{
|
||||
dns_message_t *m;
|
||||
isc_result_t iresult;
|
||||
dns_msgblock_t *msgblock;
|
||||
isc_dynbuffer_t *dynbuf;
|
||||
unsigned int i;
|
||||
|
||||
REQUIRE(mctx != NULL);
|
||||
REQUIRE(msg != NULL);
|
||||
REQUIRE(*msg == NULL);
|
||||
REQUIRE(intent == DNS_MESSAGE_INTENT_PARSE
|
||||
|| intent == DNS_MESSAGE_INTENT_RENDER);
|
||||
|
||||
m = isc_mem_get(mctx, sizeof(dns_message_t));
|
||||
if (m == NULL)
|
||||
return(DNS_R_NOMEMORY);
|
||||
|
||||
m->magic = MESSAGE_MAGIC;
|
||||
m->from_to_wire = intent;
|
||||
msginit(m);
|
||||
for (i = 0 ; i < DNS_SECTION_MAX ; i++)
|
||||
ISC_LIST_INIT(m->sections[i]);
|
||||
m->mctx = mctx;
|
||||
ISC_LIST_INIT(m->scratchpad);
|
||||
ISC_LIST_INIT(m->names);
|
||||
ISC_LIST_INIT(m->rdatas);
|
||||
ISC_LIST_INIT(m->rdatalists);
|
||||
|
||||
dynbuf = NULL;
|
||||
iresult = isc_dynbuffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE,
|
||||
ISC_BUFFERTYPE_BINARY);
|
||||
if (iresult != ISC_R_SUCCESS)
|
||||
goto cleanup1;
|
||||
ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
|
||||
|
||||
msgblock = msgblock_allocate(mctx, sizeof(dns_name_t),
|
||||
NAME_COUNT);
|
||||
if (msgblock == NULL)
|
||||
goto cleanup2;
|
||||
ISC_LIST_APPEND(m->names, msgblock, link);
|
||||
|
||||
msgblock = msgblock_allocate(mctx, sizeof(dns_rdata_t),
|
||||
RDATA_COUNT);
|
||||
if (msgblock == NULL)
|
||||
goto cleanup3;
|
||||
ISC_LIST_APPEND(m->rdatas, msgblock, link);
|
||||
|
||||
if (intent == DNS_MESSAGE_INTENT_PARSE) {
|
||||
msgblock = msgblock_allocate(mctx, sizeof(dns_rdatalist_t),
|
||||
RDATALIST_COUNT);
|
||||
if (msgblock == NULL)
|
||||
goto cleanup4;
|
||||
ISC_LIST_APPEND(m->rdatalists, msgblock, link);
|
||||
}
|
||||
|
||||
return (DNS_R_SUCCESS);
|
||||
|
||||
/*
|
||||
* Cleanup for error returns.
|
||||
*/
|
||||
cleanup4:
|
||||
msgblock = ISC_LIST_HEAD(m->rdatas);
|
||||
msgblock_free(mctx, msgblock);
|
||||
cleanup3:
|
||||
msgblock = ISC_LIST_HEAD(m->names);
|
||||
msgblock_free(mctx, msgblock);
|
||||
cleanup2:
|
||||
dynbuf = ISC_LIST_HEAD(m->scratchpad);
|
||||
isc_dynbuffer_free(mctx, &dynbuf);
|
||||
cleanup1:
|
||||
m->magic = 0;
|
||||
isc_mem_put(mctx, m, sizeof(dns_message_t));
|
||||
|
||||
return (DNS_R_NOMEMORY);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_reset(dns_message_t *msg)
|
||||
{
|
||||
msgreset(msg, ISC_FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_destroy(dns_message_t **xmsg)
|
||||
{
|
||||
dns_message_t *msg;
|
||||
|
||||
REQUIRE(xmsg != NULL);
|
||||
REQUIRE(VALID_MESSAGE(*xmsg));
|
||||
|
||||
msg = *xmsg;
|
||||
*xmsg = NULL;
|
||||
|
||||
msgreset(msg, ISC_TRUE);
|
||||
msg->magic = 0;
|
||||
isc_mem_put(msg->mctx, msg, sizeof(dns_message_t));
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_parse(dns_message_t *msg, void *buffer, size_t buflen)
|
||||
{
|
||||
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(buffer != NULL);
|
||||
REQUIRE(buflen > 0); /* XXXMLG Should be >= header length... */
|
||||
|
||||
/* XXX implement */
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_renderbegin(dns_message_t *msg, isc_buffer_t *buffer)
|
||||
{
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(buffer != NULL);
|
||||
|
||||
/* XXX implement */
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_renderrelease(dns_message_t *msg, unsigned int space)
|
||||
{
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
|
||||
if (msg->reserved < space)
|
||||
return (DNS_R_NOSPACE);
|
||||
|
||||
msg->reserved -= space;
|
||||
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_renderreserve(dns_message_t *msg, isc_buffer_t *buffer,
|
||||
unsigned int space)
|
||||
{
|
||||
isc_region_t r;
|
||||
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(buffer != NULL);
|
||||
|
||||
/*
|
||||
* "space" can be positive or negative. If it is negative we are
|
||||
* removing our reservation of space. If it is positive, we are
|
||||
* requesting more space to be reserved.
|
||||
*/
|
||||
|
||||
isc_buffer_available(buffer, &r);
|
||||
if (r.length < (space + msg->reserved))
|
||||
return (DNS_R_NOSPACE);
|
||||
|
||||
msg->reserved += space;
|
||||
|
||||
return (DNS_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_rendersection(dns_message_t *msg, isc_buffer_t *buffer,
|
||||
dns_section_t section, unsigned int priority,
|
||||
unsigned int flags)
|
||||
{
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(buffer != NULL);
|
||||
REQUIRE(VALID_NAMED_SECTION(section));
|
||||
|
||||
/* XXX implement */
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_renderend(dns_message_t *msg, isc_buffer_t *buffer)
|
||||
{
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(buffer != NULL);
|
||||
|
||||
/* XXX implement */
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_firstname(dns_message_t *msg, dns_section_t section)
|
||||
{
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(VALID_NAMED_SECTION(section));
|
||||
|
||||
msg->cursors[section] = ISC_LIST_HEAD(msg->sections[section]);
|
||||
|
||||
if (msg->cursors[section] == NULL)
|
||||
return (DNS_R_NOMORE);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_nextname(dns_message_t *msg, dns_section_t section)
|
||||
{
|
||||
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(VALID_NAMED_SECTION(section));
|
||||
REQUIRE(msg->cursors[section] != NULL);
|
||||
|
||||
msg->cursors[section] = ISC_LIST_NEXT(msg->cursors[section], link);
|
||||
|
||||
if (msg->cursors[section] == NULL)
|
||||
return (DNS_R_NOMORE);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_currentname(dns_message_t *msg, dns_section_t section,
|
||||
dns_name_t **name)
|
||||
{
|
||||
REQUIRE(VALID_MESSAGE(msg));
|
||||
REQUIRE(VALID_NAMED_SECTION(section));
|
||||
REQUIRE(name != NULL && name == NULL);
|
||||
REQUIRE(msg->cursors[section] != NULL);
|
||||
|
||||
*name = msg->cursors[section];
|
||||
}
|
||||
|
||||
dns_result_t
|
||||
dns_message_findname(dns_message_t *msg, dns_section_t section,
|
||||
dns_name_t *target, dns_rdatatype_t type,
|
||||
dns_name_t **name, dns_rdataset_t **rdataset)
|
||||
{
|
||||
|
||||
/*
|
||||
* XXX These requirements are probably too intensive, especially
|
||||
* where things can be NULL, but as they are they ensure that if
|
||||
* something is NON-NULL, indicating that the caller expects it
|
||||
* to be filled in, that we can in fact fill it in.
|
||||
*/
|
||||
REQUIRE(msg != NULL);
|
||||
REQUIRE(VALID_SECTION(section));
|
||||
REQUIRE(target != NULL);
|
||||
if (name != NULL)
|
||||
REQUIRE(*name == NULL);
|
||||
if (type == dns_rdatatype_any) {
|
||||
REQUIRE(rdataset == NULL);
|
||||
} else {
|
||||
if (rdataset != NULL)
|
||||
REQUIRE(*rdataset == NULL);
|
||||
}
|
||||
|
||||
return (ISC_R_NOTIMPLEMENTED);
|
||||
/* XXX implement */
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_movename(dns_message_t *msg, dns_name_t *name,
|
||||
dns_section_t fromsection,
|
||||
dns_section_t tosection)
|
||||
{
|
||||
REQUIRE(msg != NULL);
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(VALID_NAMED_SECTION(fromsection));
|
||||
REQUIRE(VALID_NAMED_SECTION(tosection));
|
||||
REQUIRE(fromsection != tosection);
|
||||
|
||||
/*
|
||||
* Unlink the name from the old section
|
||||
*/
|
||||
ISC_LIST_UNLINK(msg->sections[fromsection], name, link);
|
||||
ISC_LIST_APPEND(msg->sections[tosection], name, link);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_addname(dns_message_t *msg, dns_name_t *name,
|
||||
dns_section_t section)
|
||||
{
|
||||
REQUIRE(msg != NULL);
|
||||
REQUIRE(name != NULL);
|
||||
REQUIRE(VALID_NAMED_SECTION(section));
|
||||
|
||||
ISC_LIST_APPEND(msg->sections[section], name, link);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue