Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
BIND
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
632
Issues
632
List
Boards
Labels
Service Desk
Milestones
Merge Requests
104
Merge Requests
104
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Incidents
Environments
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
BIND
Commits
f9df80f4
Commit
f9df80f4
authored
Apr 27, 1999
by
Michael Graff
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
snapshot work
parent
802a7c6d
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
516 additions
and
44 deletions
+516
-44
lib/dns/include/dns/message.h
lib/dns/include/dns/message.h
+61
-34
lib/dns/message.c
lib/dns/message.c
+455
-10
No files found.
lib/dns/include/dns/message.h
View file @
f9df80f4
...
...
@@ -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
...
...
lib/dns/message.c
View file @
f9df80f4
...
...
@@ -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_internal
get(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_internal
get
(
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
)
{