Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ISC Open Source Projects
BIND
Commits
f9df80f4
Commit
f9df80f4
authored
Apr 27, 1999
by
Michael Graff
Browse files
snapshot work
parent
802a7c6d
Changes
2
Hide whitespace changes
Inline
Side-by-side
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