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
d6883869
Commit
d6883869
authored
Apr 28, 1999
by
Michael Graff
Browse files
checkpoint
parent
1d6572f9
Changes
2
Hide whitespace changes
Inline
Side-by-side
lib/dns/include/dns/message.h
View file @
d6883869
...
...
@@ -66,6 +66,8 @@ ISC_LANG_BEGINDECLS
#define DNS_MESSAGE_OPCODE_SHIFT 11
#define DNS_MESSAGE_RCODE_MASK 0x000fU
#define DNS_MESSAGE_HEADER_LEN 12
/* 6 u_int16_t's */
/*
* 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.
...
...
@@ -115,7 +117,12 @@ typedef struct {
ISC_LIST
(
isc_dynbuffer_t
)
scratchpad
;
ISC_LIST
(
dns_msgblock_t
)
names
;
ISC_LIST
(
dns_msgblock_t
)
rdatas
;
ISC_LIST
(
dns_msgblock_t
)
rdatasets
;
ISC_LIST
(
dns_msgblock_t
)
rdatalists
;
dns_name_t
*
nextname
;
dns_rdata_t
*
nextrdata
;
dns_rdataset_t
*
nextrdataset
;
dns_rdatalist_t
*
nextrdatalist
;
}
dns_message_t
;
dns_result_t
...
...
@@ -175,7 +182,7 @@ dns_message_destroy(dns_message_t **msg);
*/
dns_result_t
dns_message_parse
(
dns_message_t
*
msg
,
void
*
buffer
,
size_t
buflen
);
dns_message_parse
(
dns_message_t
*
msg
,
isc_buffer_t
*
source
);
/*
* Parse raw wire data pointed to by "buffer" and bounded by "buflen" as a
* DNS message.
...
...
lib/dns/message.c
View file @
d6883869
...
...
@@ -51,7 +51,8 @@
#define SCRATCHPAD_SIZE 768
#define NAME_COUNT 16
#define RDATA_COUNT 32
#define RDATALIST_COUNT 32
#define RDATALIST_COUNT 32
/* should match RDATASET_COUNT */
#define RDATASET_COUNT 32
/*
* internal state stuff.
...
...
@@ -74,7 +75,7 @@ struct dns_msgblock {
static
inline
void
msgblock_free
(
isc_mem_t
*
,
dns_msgblock_t
*
);
#define msgblock_get(block, type) \
((
(
type
)
*)msgblock_internalget(block, sizeof(type)))
((type *)msgblock_internalget(block, sizeof(type)))
static
inline
void
*
msgblock_internalget
(
dns_msgblock_t
*
,
unsigned
int
);
...
...
@@ -146,6 +147,174 @@ msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block)
isc_mem_put
(
mctx
,
block
,
block
->
length
);
}
/*
* Allocate a new dynamic buffer, and attach it to this message as the
* "current" buffer. (which is always the last on the list, for our
* uses)
*/
static
inline
dns_result_t
newbuffer
(
dns_message_t
*
msg
)
{
isc_result_t
result
;
isc_dynbuffer_t
*
dynbuf
;
dynbuf
=
NULL
;
result
=
isc_dynbuffer_allocate
(
msg
->
mctx
,
&
dynbuf
,
SCRATCHPAD_SIZE
,
ISC_BUFFERTYPE_BINARY
);
if
(
result
!=
ISC_R_SUCCESS
)
return
(
DNS_R_NOMEMORY
);
ISC_LIST_APPEND
(
msg
->
scratchpad
,
dynbuf
,
link
);
return
(
DNS_R_SUCCESS
);
}
static
inline
isc_buffer_t
*
currentbuffer
(
dns_message_t
*
msg
)
{
isc_dynbuffer_t
*
dynbuf
;
dynbuf
=
ISC_LIST_TAIL
(
msg
->
scratchpad
);
return
(
&
dynbuf
->
buffer
);
}
static
inline
void
releasename
(
dns_message_t
*
msg
,
dns_name_t
*
name
)
{
msg
->
nextname
=
name
;
}
static
inline
dns_name_t
*
newname
(
dns_message_t
*
msg
)
{
dns_msgblock_t
*
msgblock
;
dns_name_t
*
name
;
if
(
msg
->
nextname
!=
NULL
)
{
name
=
msg
->
nextname
;
msg
->
nextname
=
NULL
;
return
(
name
);
}
msgblock
=
ISC_LIST_HEAD
(
msg
->
names
);
name
=
msgblock_get
(
msgblock
,
dns_name_t
);
if
(
name
==
NULL
)
{
msgblock
=
msgblock_allocate
(
msg
->
mctx
,
sizeof
(
dns_name_t
),
NAME_COUNT
);
if
(
msgblock
==
NULL
)
return
(
NULL
);
ISC_LIST_APPEND
(
msg
->
names
,
msgblock
,
link
);
name
=
msgblock_get
(
msgblock
,
dns_name_t
);
}
return
(
name
);
}
static
inline
void
releaserdata
(
dns_message_t
*
msg
,
dns_rdata_t
*
rdata
)
{
msg
->
nextrdata
=
rdata
;
}
static
inline
dns_rdata_t
*
newrdata
(
dns_message_t
*
msg
)
{
dns_msgblock_t
*
msgblock
;
dns_rdata_t
*
rdata
;
if
(
msg
->
nextrdata
!=
NULL
)
{
rdata
=
msg
->
nextrdata
;
msg
->
nextrdata
=
NULL
;
return
(
rdata
);
}
msgblock
=
ISC_LIST_HEAD
(
msg
->
rdatas
);
rdata
=
msgblock_get
(
msgblock
,
dns_rdata_t
);
if
(
rdata
==
NULL
)
{
msgblock
=
msgblock_allocate
(
msg
->
mctx
,
sizeof
(
dns_rdata_t
),
RDATA_COUNT
);
if
(
msgblock
==
NULL
)
return
(
NULL
);
ISC_LIST_APPEND
(
msg
->
rdatas
,
msgblock
,
link
);
rdata
=
msgblock_get
(
msgblock
,
dns_rdata_t
);
}
return
(
rdata
);
}
static
inline
void
releaserdatalist
(
dns_message_t
*
msg
,
dns_rdatalist_t
*
rdatalist
)
{
msg
->
nextrdatalist
=
rdatalist
;
}
static
inline
dns_rdatalist_t
*
newrdatalist
(
dns_message_t
*
msg
)
{
dns_msgblock_t
*
msgblock
;
dns_rdatalist_t
*
rdatalist
;
if
(
msg
->
nextrdatalist
!=
NULL
)
{
rdatalist
=
msg
->
nextrdatalist
;
msg
->
nextrdatalist
=
NULL
;
return
(
rdatalist
);
}
msgblock
=
ISC_LIST_HEAD
(
msg
->
rdatalists
);
rdatalist
=
msgblock_get
(
msgblock
,
dns_rdatalist_t
);
if
(
rdatalist
==
NULL
)
{
msgblock
=
msgblock_allocate
(
msg
->
mctx
,
sizeof
(
dns_rdatalist_t
),
RDATALIST_COUNT
);
if
(
msgblock
==
NULL
)
return
(
NULL
);
ISC_LIST_APPEND
(
msg
->
rdatalists
,
msgblock
,
link
);
rdatalist
=
msgblock_get
(
msgblock
,
dns_rdatalist_t
);
}
return
(
rdatalist
);
}
static
inline
void
releaserdataset
(
dns_message_t
*
msg
,
dns_rdataset_t
*
rdataset
)
{
msg
->
nextrdataset
=
rdataset
;
}
static
inline
dns_rdataset_t
*
newrdataset
(
dns_message_t
*
msg
)
{
dns_msgblock_t
*
msgblock
;
dns_rdataset_t
*
rdataset
;
if
(
msg
->
nextrdataset
!=
NULL
)
{
rdataset
=
msg
->
nextrdataset
;
msg
->
nextrdataset
=
NULL
;
return
(
rdataset
);
}
msgblock
=
ISC_LIST_HEAD
(
msg
->
rdatasets
);
rdataset
=
msgblock_get
(
msgblock
,
dns_rdataset_t
);
if
(
rdataset
==
NULL
)
{
msgblock
=
msgblock_allocate
(
msg
->
mctx
,
sizeof
(
dns_rdataset_t
),
RDATASET_COUNT
);
if
(
msgblock
==
NULL
)
return
(
NULL
);
ISC_LIST_APPEND
(
msg
->
rdatasets
,
msgblock
,
link
);
rdataset
=
msgblock_get
(
msgblock
,
dns_rdataset_t
);
}
return
(
rdataset
);
}
/*
* Init elements to default state. Used both when allocating a new element
* and when resetting one.
...
...
@@ -153,6 +322,8 @@ msgblock_free(isc_mem_t *mctx, dns_msgblock_t *block)
static
inline
void
msginit
(
dns_message_t
*
m
)
{
unsigned
int
i
;
m
->
id
=
0
;
m
->
flags
=
0
;
m
->
rcode
=
0
;
...
...
@@ -162,7 +333,16 @@ msginit(dns_message_t *m)
m
->
ancount
=
0
;
m
->
aucount
=
0
;
m
->
adcount
=
0
;
for
(
i
=
0
;
i
<
DNS_SECTION_MAX
;
i
++
)
m
->
cursors
[
i
]
=
NULL
;
m
->
state
=
DNS_SECTION_ANY
;
/* indicate nothing parsed or rendered */
m
->
nextname
=
NULL
;
m
->
nextrdata
=
NULL
;
m
->
nextrdataset
=
NULL
;
m
->
nextrdatalist
=
NULL
;
}
/*
...
...
@@ -241,6 +421,19 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
msgblock
=
next_msgblock
;
}
msgblock
=
ISC_LIST_HEAD
(
msg
->
rdatasets
);
INSIST
(
msgblock
!=
NULL
);
if
(
everything
==
ISC_FALSE
)
{
msgblock_reset
(
msgblock
,
RDATASET_COUNT
);
msgblock
=
ISC_LIST_NEXT
(
msgblock
,
link
);
}
while
(
msgblock
!=
NULL
)
{
next_msgblock
=
ISC_LIST_NEXT
(
msgblock
,
link
);
ISC_LIST_UNLINK
(
msg
->
rdatasets
,
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
);
...
...
@@ -311,11 +504,17 @@ dns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent)
goto
cleanup3
;
ISC_LIST_APPEND
(
m
->
rdatas
,
msgblock
,
link
);
msgblock
=
msgblock_allocate
(
mctx
,
sizeof
(
dns_rdataset_t
),
RDATASET_COUNT
);
if
(
msgblock
==
NULL
)
goto
cleanup4
;
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
cleanup
4
;
goto
cleanup
5
;
ISC_LIST_APPEND
(
m
->
rdatalists
,
msgblock
,
link
);
}
...
...
@@ -324,6 +523,9 @@ dns_message_create(isc_mem_t *mctx, dns_message_t **msg, unsigned int intent)
/*
* Cleanup for error returns.
*/
cleanup5:
msgblock
=
ISC_LIST_HEAD
(
m
->
rdatasets
);
msgblock_free
(
mctx
,
msgblock
);
cleanup4:
msgblock
=
ISC_LIST_HEAD
(
m
->
rdatas
);
msgblock_free
(
mctx
,
msgblock
);
...
...
@@ -362,16 +564,120 @@ dns_message_destroy(dns_message_t **xmsg)
isc_mem_put
(
msg
->
mctx
,
msg
,
sizeof
(
dns_message_t
));
}
static
dns_result_t
getquestions
(
isc_buffer_t
*
source
,
dns_message_t
*
msg
,
dns_decompress_t
*
dctx
)
{
isc_region_t
r
;
unsigned
int
count
;
dns_name_t
*
name
;
dns_name_t
*
name2
;
dns_rdataset_t
*
rdataset
;
dns_rdatalist_t
*
rdatalist
;
dns_result_t
result
;
count
=
msg
->
qcount
;
while
(
count
>
0
)
{
name
=
newname
(
msg
);
if
(
name
==
NULL
)
return
(
DNS_R_NOMEMORY
);
/*
* Parse the name out of this packet.
*/
result
=
getname
(
name
,
source
,
msg
,
dctx
);
if
(
result
!=
DNS_R_SUCCESS
)
return
(
result
);
/*
* Run through the section, looking to see if this name
* is already there. If it is found, put back the allocated
* name since we no longer need it, and set our name pointer
* to point to the name we found.
*/
result
=
findname
();
/* XXX stop point */
/*
* If it is a new name, append to the section.
*/
/*
* Get type and class.
*/
/*
* Search name for the particular type and class.
*/
/*
* If it was found, this is an error, return FORMERR.
*/
/*
* Allocate a new rdatalist.
*/
/*
* Convert rdatalist to rdataset, and attach the latter to
* the name.
*/
}
return
(
DNS_R_SUCCESS
);
}
static
dns_result_t
getsection
(
isc_buffer_t
*
source
,
dns_message_t
*
msg
,
dns_decompress_t
*
dctx
,
dns_section_t
section
)
{
return
(
DNS_R_UNEXPECTED
);
}
dns_result_t
dns_message_parse
(
dns_message_t
*
msg
,
void
*
buffer
,
size_t
buflen
)
dns_message_parse
(
dns_message_t
*
msg
,
isc_buffer_t
*
source
)
{
isc_region_t
r
;
dns_decompress_t
dctx
;
dns_result_t
ret
;
REQUIRE
(
VALID_MESSAGE
(
msg
));
REQUIRE
(
buffer
!=
NULL
);
REQUIRE
(
buflen
>
0
);
/* XXXMLG Should be >= header length... */
REQUIRE
(
source
!=
NULL
);
/* XXX implement */
return
(
ISC_R_NOTIMPLEMENTED
);
isc_buffer_remaining
(
source
,
&
r
);
if
(
r
.
length
>=
DNS_MESSAGE_HEADER_LEN
)
return
(
DNS_R_UNEXPECTEDEND
);
msg
->
id
=
isc_buffer_getuint16
(
source
);
msg
->
flags
=
isc_buffer_getuint16
(
source
);
msg
->
qcount
=
isc_buffer_getuint16
(
source
);
msg
->
ancount
=
isc_buffer_getuint16
(
source
);
msg
->
aucount
=
isc_buffer_getuint16
(
source
);
msg
->
adcount
=
isc_buffer_getuint16
(
source
);
dns_decompress_init
(
&
dctx
,
-
1
,
ISC_FALSE
);
ret
=
getquestions
(
source
,
msg
,
&
dctx
);
if
(
ret
!=
DNS_R_SUCCESS
)
return
(
ret
);
ret
=
getsection
(
source
,
msg
,
&
dctx
,
DNS_SECTION_ANSWER
);
if
(
ret
!=
DNS_R_SUCCESS
)
return
(
ret
);
ret
=
getsection
(
source
,
msg
,
&
dctx
,
DNS_SECTION_AUTHORITY
);
if
(
ret
!=
DNS_R_SUCCESS
)
return
(
ret
);
ret
=
getsection
(
source
,
msg
,
&
dctx
,
DNS_SECTION_ADDITIONAL
);
if
(
ret
!=
DNS_R_SUCCESS
)
return
(
ret
);
/*
* XXXMLG Need to check the tsig(s) here...
*/
return
(
DNS_R_SUCCESS
);
}
dns_result_t
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment