Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
wine
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Package registry
Container registry
Model registry
Operate
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Lorenzo Ferrillo
wine
Commits
aec19e86
Commit
aec19e86
authored
3 years ago
by
Alexandre Julliard
Browse files
Options
Downloads
Patches
Plain Diff
dnsapi: Implement DnsExtractRecordsFromMessage().
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
87f94202
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
dlls/dnsapi/main.c
+0
-26
0 additions, 26 deletions
dlls/dnsapi/main.c
dlls/dnsapi/record.c
+433
-0
433 additions, 0 deletions
dlls/dnsapi/record.c
dlls/dnsapi/tests/record.c
+199
-0
199 additions, 0 deletions
dlls/dnsapi/tests/record.c
with
632 additions
and
26 deletions
dlls/dnsapi/main.c
+
0
−
26
View file @
aec19e86
...
...
@@ -150,32 +150,6 @@ VOID WINAPI DnsReleaseContextHandle( HANDLE context )
FIXME
(
"(%p) stub
\n
"
,
context
);
}
/******************************************************************************
* DnsExtractRecordsFromMessage_UTF8 [DNSAPI.@]
*
*/
DNS_STATUS
WINAPI
DnsExtractRecordsFromMessage_UTF8
(
PDNS_MESSAGE_BUFFER
buffer
,
WORD
len
,
PDNS_RECORDA
*
record
)
{
FIXME
(
"(%p,%d,%p) stub
\n
"
,
buffer
,
len
,
record
);
*
record
=
NULL
;
return
ERROR_SUCCESS
;
}
/******************************************************************************
* DnsExtractRecordsFromMessage_W [DNSAPI.@]
*
*/
DNS_STATUS
WINAPI
DnsExtractRecordsFromMessage_W
(
PDNS_MESSAGE_BUFFER
buffer
,
WORD
len
,
PDNS_RECORDW
*
record
)
{
FIXME
(
"(%p,%d,%p) stub
\n
"
,
buffer
,
len
,
record
);
*
record
=
NULL
;
return
ERROR_SUCCESS
;
}
/******************************************************************************
* DnsModifyRecordsInSet_A [DNSAPI.@]
*
...
...
This diff is collapsed.
Click to expand it.
dlls/dnsapi/record.c
+
433
−
0
View file @
aec19e86
...
...
@@ -2,6 +2,7 @@
* DNS support
*
* Copyright (C) 2006 Hans Leidekker
* Copyright (C) 2021 Alexandre Julliard
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
...
...
@@ -95,6 +96,18 @@ const char *debugstr_type( unsigned short type )
}
}
static
const
char
*
debugstr_section
(
DNS_SECTION
section
)
{
switch
(
section
)
{
case
DnsSectionQuestion
:
return
"Question"
;
case
DnsSectionAnswer
:
return
"Answer"
;
case
DnsSectionAuthority
:
return
"Authority"
;
case
DnsSectionAddtional
:
return
"Additional"
;
default:
return
"??"
;
}
}
static
int
strcmpX
(
LPCVOID
str1
,
LPCVOID
str2
,
BOOL
wide
)
{
if
(
wide
)
...
...
@@ -103,6 +116,95 @@ static int strcmpX( LPCVOID str1, LPCVOID str2, BOOL wide )
return
lstrcmpiA
(
str1
,
str2
);
}
static
WORD
get_word
(
const
BYTE
**
ptr
)
{
WORD
ret
=
((
*
ptr
)[
0
]
<<
8
)
+
(
*
ptr
)[
1
];
*
ptr
+=
sizeof
(
WORD
);
return
ret
;
}
static
DWORD
get_dword
(
const
BYTE
**
ptr
)
{
DWORD
ret
=
((
*
ptr
)[
0
]
<<
24
)
+
((
*
ptr
)[
1
]
<<
16
)
+
((
*
ptr
)[
2
]
<<
8
)
+
(
*
ptr
)[
3
];
*
ptr
+=
sizeof
(
DWORD
);
return
ret
;
}
static
const
BYTE
*
skip_name
(
const
BYTE
*
ptr
,
const
BYTE
*
end
)
{
BYTE
len
;
while
(
ptr
<
end
&&
(
len
=
*
ptr
++
))
{
switch
(
len
&
0xc0
)
{
case
0
:
ptr
+=
len
;
continue
;
case
0xc0
:
ptr
++
;
break
;
default:
return
NULL
;
}
break
;
}
if
(
ptr
<
end
)
return
ptr
;
return
NULL
;
}
static
const
BYTE
*
skip_record
(
const
BYTE
*
ptr
,
const
BYTE
*
end
,
DNS_SECTION
section
)
{
WORD
len
;
if
(
!
(
ptr
=
skip_name
(
ptr
,
end
)))
return
NULL
;
ptr
+=
2
;
/* type */
ptr
+=
2
;
/* class */
if
(
section
!=
DnsSectionQuestion
)
{
ptr
+=
4
;
/* ttl */
if
(
ptr
+
2
>
end
)
return
NULL
;
len
=
get_word
(
&
ptr
);
ptr
+=
len
;
}
if
(
ptr
>
end
)
return
NULL
;
return
ptr
;
}
static
const
BYTE
*
get_name
(
const
BYTE
*
base
,
const
BYTE
*
end
,
const
BYTE
*
ptr
,
char
name
[
DNS_MAX_NAME_BUFFER_LENGTH
]
)
{
BYTE
len
;
char
*
out
=
name
;
const
BYTE
*
next
=
NULL
;
int
loop
=
0
;
while
(
ptr
<
end
&&
(
len
=
*
ptr
++
))
{
switch
(
len
&
0xc0
)
{
case
0
:
if
(
out
+
len
+
1
>=
name
+
DNS_MAX_NAME_BUFFER_LENGTH
)
return
NULL
;
if
(
out
>
name
)
*
out
++
=
'.'
;
memcpy
(
out
,
ptr
,
len
);
out
+=
len
;
ptr
+=
len
;
continue
;
case
0xc0
:
if
(
!
next
)
next
=
ptr
+
1
;
if
(
++
loop
>=
end
-
base
)
return
NULL
;
if
(
ptr
<
end
)
ptr
=
base
+
((
len
&
0x3f
)
<<
8
)
+
*
ptr
;
break
;
default:
return
NULL
;
}
}
if
(
ptr
>=
end
)
return
NULL
;
if
(
out
==
name
)
*
out
++
=
'.'
;
*
out
=
0
;
return
next
?
next
:
ptr
;
}
/******************************************************************************
* DnsRecordCompare [DNSAPI.@]
*
...
...
@@ -786,3 +888,334 @@ PDNS_RECORD WINAPI DnsRecordSetDetach( PDNS_RECORD set )
}
return
NULL
;
}
static
unsigned
int
get_record_size
(
WORD
type
,
const
BYTE
*
data
,
WORD
len
)
{
switch
(
type
)
{
case
DNS_TYPE_KEY
:
return
offsetof
(
DNS_RECORDA
,
Data
.
Key
.
Key
[
len
]
);
case
DNS_TYPE_SIG
:
return
offsetof
(
DNS_RECORDA
,
Data
.
Sig
.
Signature
[
len
]
);
case
DNS_TYPE_HINFO
:
case
DNS_TYPE_ISDN
:
case
DNS_TYPE_TEXT
:
case
DNS_TYPE_X25
:
{
int
i
;
const
BYTE
*
pos
=
data
;
for
(
i
=
0
;
pos
<
data
+
len
;
i
++
)
pos
+=
pos
[
0
]
+
1
;
return
offsetof
(
DNS_RECORDA
,
Data
.
Txt
.
pStringArray
[
i
]
);
}
case
DNS_TYPE_NULL
:
case
DNS_TYPE_OPT
:
return
offsetof
(
DNS_RECORDA
,
Data
.
Null
.
Data
[
len
]
);
case
DNS_TYPE_WKS
:
return
offsetof
(
DNS_RECORDA
,
Data
.
Wks
.
BitMask
[
len
/
8
]
);
case
DNS_TYPE_NXT
:
return
offsetof
(
DNS_RECORDA
,
Data
.
Nxt
.
wTypes
[
len
*
8
]
);
case
DNS_TYPE_WINS
:
return
offsetof
(
DNS_RECORDA
,
Data
.
Wins
.
WinsServers
[
len
/
4
]
);
default:
return
sizeof
(
DNS_RECORDA
);
}
}
static
DNS_STATUS
extract_rdata
(
const
BYTE
*
base
,
const
BYTE
*
end
,
const
BYTE
*
pos
,
WORD
len
,
WORD
type
,
DNS_RECORDA
*
r
)
{
DNS_CHARSET
in
=
DnsCharSetUtf8
,
out
=
r
->
Flags
.
S
.
CharSet
;
char
name
[
DNS_MAX_NAME_BUFFER_LENGTH
];
DNS_STATUS
ret
=
ERROR_SUCCESS
;
const
BYTE
*
rrend
=
pos
+
len
;
unsigned
int
i
;
switch
(
type
)
{
case
DNS_TYPE_A
:
if
(
pos
+
sizeof
(
DWORD
)
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
r
->
Data
.
A
.
IpAddress
=
*
(
const
DWORD
*
)
pos
;
r
->
wDataLength
=
sizeof
(
DNS_A_DATA
);
break
;
case
DNS_TYPE_AAAA
:
if
(
pos
+
sizeof
(
IP6_ADDRESS
)
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
for
(
i
=
0
;
i
<
sizeof
(
IP6_ADDRESS
)
/
sizeof
(
DWORD
);
i
++
)
{
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
i
]
=
*
(
const
DWORD
*
)
pos
;
pos
+=
sizeof
(
DWORD
);
}
r
->
wDataLength
=
sizeof
(
DNS_AAAA_DATA
);
break
;
case
DNS_TYPE_KEY
:
if
(
pos
+
4
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
r
->
Data
.
KEY
.
wFlags
=
get_word
(
&
pos
);
r
->
Data
.
KEY
.
chProtocol
=
*
pos
++
;
r
->
Data
.
KEY
.
chAlgorithm
=
*
pos
++
;
r
->
Data
.
KEY
.
wKeyLength
=
rrend
-
pos
;
memcpy
(
r
->
Data
.
KEY
.
Key
,
pos
,
r
->
Data
.
KEY
.
wKeyLength
);
r
->
wDataLength
=
offsetof
(
DNS_KEY_DATA
,
Key
[
r
->
Data
.
KEY
.
wKeyLength
]
);
break
;
case
DNS_TYPE_RP
:
case
DNS_TYPE_MINFO
:
if
(
!
(
pos
=
get_name
(
base
,
end
,
pos
,
name
)))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
MINFO
.
pNameMailbox
=
strcpyX
(
name
,
in
,
out
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
if
(
!
get_name
(
base
,
end
,
pos
,
name
))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
MINFO
.
pNameErrorsMailbox
=
strcpyX
(
name
,
in
,
out
)))
{
heap_free
(
r
->
Data
.
MINFO
.
pNameMailbox
);
return
ERROR_NOT_ENOUGH_MEMORY
;
}
r
->
wDataLength
=
sizeof
(
DNS_MINFO_DATAA
);
break
;
case
DNS_TYPE_AFSDB
:
case
DNS_TYPE_RT
:
case
DNS_TYPE_MX
:
if
(
pos
+
sizeof
(
WORD
)
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
r
->
Data
.
MX
.
wPreference
=
get_word
(
&
pos
);
if
(
!
get_name
(
base
,
end
,
pos
,
name
))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
MX
.
pNameExchange
=
strcpyX
(
name
,
in
,
out
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
r
->
wDataLength
=
sizeof
(
DNS_MX_DATAA
)
+
sizeof
(
DWORD
);
break
;
case
DNS_TYPE_NULL
:
r
->
Data
.
Null
.
dwByteCount
=
len
;
memcpy
(
r
->
Data
.
Null
.
Data
,
pos
,
len
);
r
->
wDataLength
=
offsetof
(
DNS_NULL_DATA
,
Data
[
len
]
);
break
;
case
DNS_TYPE_OPT
:
r
->
Data
.
OPT
.
wDataLength
=
len
;
r
->
Data
.
OPT
.
wPad
=
0
;
memcpy
(
r
->
Data
.
OPT
.
Data
,
pos
,
len
);
r
->
wDataLength
=
offsetof
(
DNS_OPT_DATA
,
Data
[
len
]
);
break
;
case
DNS_TYPE_CNAME
:
case
DNS_TYPE_NS
:
case
DNS_TYPE_MB
:
case
DNS_TYPE_MD
:
case
DNS_TYPE_MF
:
case
DNS_TYPE_MG
:
case
DNS_TYPE_MR
:
case
DNS_TYPE_PTR
:
if
(
!
get_name
(
base
,
end
,
pos
,
name
))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
PTR
.
pNameHost
=
strcpyX
(
name
,
in
,
out
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
r
->
wDataLength
=
sizeof
(
DNS_PTR_DATAA
)
+
sizeof
(
DWORD
);
break
;
case
DNS_TYPE_SIG
:
if
(
pos
+
18
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
r
->
Data
.
SIG
.
wTypeCovered
=
get_word
(
&
pos
);
r
->
Data
.
SIG
.
chAlgorithm
=
*
pos
++
;
r
->
Data
.
SIG
.
chLabelCount
=
*
pos
++
;
r
->
Data
.
SIG
.
dwOriginalTtl
=
get_dword
(
&
pos
);
r
->
Data
.
SIG
.
dwExpiration
=
get_dword
(
&
pos
);
r
->
Data
.
SIG
.
dwTimeSigned
=
get_dword
(
&
pos
);
r
->
Data
.
SIG
.
wKeyTag
=
get_word
(
&
pos
);
if
(
!
(
pos
=
get_name
(
base
,
end
,
pos
,
name
)))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
SIG
.
pNameSigner
=
strcpyX
(
name
,
in
,
out
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
r
->
Data
.
SIG
.
wSignatureLength
=
rrend
-
pos
;
memcpy
(
r
->
Data
.
SIG
.
Signature
,
pos
,
r
->
Data
.
SIG
.
wSignatureLength
);
r
->
wDataLength
=
offsetof
(
DNS_SIG_DATAA
,
Signature
[
r
->
Data
.
SIG
.
wSignatureLength
]
);
break
;
case
DNS_TYPE_SOA
:
if
(
!
(
pos
=
get_name
(
base
,
end
,
pos
,
name
)))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
SOA
.
pNamePrimaryServer
=
strcpyX
(
name
,
in
,
out
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
if
(
!
(
pos
=
get_name
(
base
,
end
,
pos
,
name
)))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
SOA
.
pNameAdministrator
=
strcpyX
(
name
,
in
,
out
)))
{
heap_free
(
r
->
Data
.
SOA
.
pNamePrimaryServer
);
return
ERROR_NOT_ENOUGH_MEMORY
;
}
if
(
pos
+
5
*
sizeof
(
DWORD
)
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
r
->
Data
.
SOA
.
dwSerialNo
=
get_dword
(
&
pos
);
r
->
Data
.
SOA
.
dwRefresh
=
get_dword
(
&
pos
);
r
->
Data
.
SOA
.
dwRetry
=
get_dword
(
&
pos
);
r
->
Data
.
SOA
.
dwExpire
=
get_dword
(
&
pos
);
r
->
Data
.
SOA
.
dwDefaultTtl
=
get_dword
(
&
pos
);
r
->
wDataLength
=
sizeof
(
DNS_SOA_DATAA
);
break
;
case
DNS_TYPE_SRV
:
if
(
pos
+
3
*
sizeof
(
WORD
)
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
r
->
Data
.
SRV
.
wPriority
=
get_word
(
&
pos
);
r
->
Data
.
SRV
.
wWeight
=
get_word
(
&
pos
);
r
->
Data
.
SRV
.
wPort
=
get_word
(
&
pos
);
if
(
!
get_name
(
base
,
end
,
pos
,
name
))
return
DNS_ERROR_BAD_PACKET
;
if
(
!
(
r
->
Data
.
SRV
.
pNameTarget
=
strcpyX
(
name
,
in
,
out
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
r
->
wDataLength
=
sizeof
(
DNS_SRV_DATAA
);
break
;
case
DNS_TYPE_HINFO
:
case
DNS_TYPE_ISDN
:
case
DNS_TYPE_X25
:
case
DNS_TYPE_TEXT
:
for
(
i
=
0
;
pos
<
rrend
;
i
++
)
{
BYTE
len
=
pos
[
0
];
if
(
pos
+
len
+
1
>
rrend
)
return
DNS_ERROR_BAD_PACKET
;
memcpy
(
name
,
pos
+
1
,
len
);
name
[
len
]
=
0
;
if
(
!
(
r
->
Data
.
TXT
.
pStringArray
[
i
]
=
strcpyX
(
name
,
in
,
out
)))
{
while
(
i
>
0
)
heap_free
(
r
->
Data
.
TXT
.
pStringArray
[
--
i
]
);
return
ERROR_NOT_ENOUGH_MEMORY
;
}
pos
+=
len
+
1
;
}
r
->
Data
.
TXT
.
dwStringCount
=
i
;
r
->
wDataLength
=
offsetof
(
DNS_TXT_DATAA
,
pStringArray
[
r
->
Data
.
TXT
.
dwStringCount
]
);
break
;
case
DNS_TYPE_ATMA
:
case
DNS_TYPE_LOC
:
case
DNS_TYPE_NXT
:
case
DNS_TYPE_TSIG
:
case
DNS_TYPE_WKS
:
case
DNS_TYPE_TKEY
:
case
DNS_TYPE_WINS
:
case
DNS_TYPE_WINSR
:
default:
FIXME
(
"unhandled type: %s
\n
"
,
debugstr_type
(
type
));
return
DNS_ERROR_RCODE_NOT_IMPLEMENTED
;
}
return
ret
;
}
static
DNS_STATUS
extract_record
(
const
DNS_MESSAGE_BUFFER
*
hdr
,
const
BYTE
*
end
,
const
BYTE
**
pos
,
DNS_SECTION
section
,
DNS_CHARSET
charset
,
DNS_RECORDA
**
recp
)
{
DNS_STATUS
ret
;
DNS_RECORDA
*
record
;
char
name
[
DNS_MAX_NAME_BUFFER_LENGTH
];
WORD
type
,
rdlen
;
DWORD
ttl
;
const
BYTE
*
base
=
(
const
BYTE
*
)
hdr
;
const
BYTE
*
ptr
=
*
pos
;
if
(
!
(
ptr
=
get_name
(
base
,
end
,
ptr
,
name
)))
return
DNS_ERROR_BAD_PACKET
;
if
(
ptr
+
10
>
end
)
return
DNS_ERROR_BAD_PACKET
;
type
=
get_word
(
&
ptr
);
ptr
+=
sizeof
(
WORD
);
/* class */
ttl
=
get_dword
(
&
ptr
);
rdlen
=
get_word
(
&
ptr
);
if
(
ptr
+
rdlen
>
end
)
return
DNS_ERROR_BAD_PACKET
;
*
pos
=
ptr
+
rdlen
;
if
(
!
(
record
=
heap_alloc_zero
(
get_record_size
(
type
,
ptr
,
rdlen
)
)))
return
ERROR_NOT_ENOUGH_MEMORY
;
record
->
wType
=
type
;
record
->
Flags
.
S
.
Section
=
section
;
record
->
Flags
.
S
.
CharSet
=
charset
;
record
->
dwTtl
=
ttl
;
if
(
!
(
record
->
pName
=
strcpyX
(
name
,
DnsCharSetUtf8
,
charset
)))
{
heap_free
(
record
);
return
ERROR_NOT_ENOUGH_MEMORY
;
}
if
((
ret
=
extract_rdata
(
base
,
end
,
ptr
,
rdlen
,
type
,
record
)))
{
heap_free
(
record
->
pName
);
heap_free
(
record
);
return
ret
;
}
*
recp
=
record
;
TRACE
(
"found %s record in %s section
\n
"
,
debugstr_type
(
record
->
wType
),
debugstr_section
(
section
)
);
return
ERROR_SUCCESS
;
}
static
DNS_STATUS
extract_message_records
(
const
DNS_MESSAGE_BUFFER
*
buffer
,
WORD
len
,
DNS_CHARSET
charset
,
DNS_RRSET
*
rrset
)
{
DNS_STATUS
ret
=
ERROR_SUCCESS
;
const
DNS_HEADER
*
hdr
=
&
buffer
->
MessageHead
;
DNS_RECORDA
*
record
;
const
BYTE
*
base
=
(
const
BYTE
*
)
hdr
;
const
BYTE
*
end
=
base
+
len
;
const
BYTE
*
ptr
=
(
const
BYTE
*
)
buffer
->
MessageBody
;
unsigned
int
num
;
if
(
hdr
->
IsResponse
&&
!
hdr
->
AnswerCount
)
return
DNS_ERROR_BAD_PACKET
;
for
(
num
=
0
;
num
<
hdr
->
QuestionCount
;
num
++
)
if
(
!
(
ptr
=
skip_record
(
ptr
,
end
,
DnsSectionQuestion
)))
return
DNS_ERROR_BAD_PACKET
;
for
(
num
=
0
;
num
<
hdr
->
AnswerCount
;
num
++
)
{
if
((
ret
=
extract_record
(
buffer
,
end
,
&
ptr
,
DnsSectionAnswer
,
charset
,
&
record
)))
return
ret
;
DNS_RRSET_ADD
(
*
rrset
,
(
DNS_RECORD
*
)
record
);
}
for
(
num
=
0
;
num
<
hdr
->
NameServerCount
;
num
++
)
if
(
!
(
ptr
=
skip_record
(
ptr
,
end
,
DnsSectionAuthority
)))
return
DNS_ERROR_BAD_PACKET
;
for
(
num
=
0
;
num
<
hdr
->
AdditionalCount
;
num
++
)
{
if
((
ret
=
extract_record
(
buffer
,
end
,
&
ptr
,
DnsSectionAddtional
,
charset
,
&
record
)))
return
ret
;
DNS_RRSET_ADD
(
*
rrset
,
(
DNS_RECORD
*
)
record
);
}
if
(
ptr
!=
end
)
ret
=
DNS_ERROR_BAD_PACKET
;
return
ret
;
}
/******************************************************************************
* DnsExtractRecordsFromMessage_UTF8 [DNSAPI.@]
*
*/
DNS_STATUS
WINAPI
DnsExtractRecordsFromMessage_UTF8
(
DNS_MESSAGE_BUFFER
*
buffer
,
WORD
len
,
DNS_RECORDA
**
result
)
{
DNS_STATUS
ret
=
DNS_ERROR_BAD_PACKET
;
DNS_RRSET
rrset
;
if
(
len
<
sizeof
(
*
buffer
))
return
ERROR_INVALID_PARAMETER
;
DNS_RRSET_INIT
(
rrset
);
ret
=
extract_message_records
(
buffer
,
len
,
DnsCharSetUtf8
,
&
rrset
);
DNS_RRSET_TERMINATE
(
rrset
);
if
(
!
ret
)
*
result
=
(
DNS_RECORDA
*
)
rrset
.
pFirstRR
;
else
DnsRecordListFree
(
rrset
.
pFirstRR
,
DnsFreeRecordList
);
return
ret
;
}
/******************************************************************************
* DnsExtractRecordsFromMessage_W [DNSAPI.@]
*
*/
DNS_STATUS
WINAPI
DnsExtractRecordsFromMessage_W
(
DNS_MESSAGE_BUFFER
*
buffer
,
WORD
len
,
DNS_RECORDW
**
result
)
{
DNS_STATUS
ret
=
DNS_ERROR_BAD_PACKET
;
DNS_RRSET
rrset
;
if
(
len
<
sizeof
(
*
buffer
))
return
ERROR_INVALID_PARAMETER
;
DNS_RRSET_INIT
(
rrset
);
ret
=
extract_message_records
(
buffer
,
len
,
DnsCharSetUnicode
,
&
rrset
);
DNS_RRSET_TERMINATE
(
rrset
);
if
(
!
ret
)
*
result
=
(
DNS_RECORDW
*
)
rrset
.
pFirstRR
;
else
DnsRecordListFree
(
rrset
.
pFirstRR
,
DnsFreeRecordList
);
return
ret
;
}
This diff is collapsed.
Click to expand it.
dlls/dnsapi/tests/record.c
+
199
−
0
View file @
aec19e86
...
...
@@ -138,9 +138,208 @@ static void test_DnsRecordSetDetach( void )
ok
(
!
r2
.
pNext
,
"failed unexpectedly
\n
"
);
}
static
BYTE
msg_empty
[]
=
/* empty message */
{
0x12
,
0x34
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
};
static
BYTE
msg_empty_answer
[]
=
/* marked as answer but contains only question */
{
0x12
,
0x34
,
0x80
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
};
static
BYTE
msg_question
[]
=
/* question only */
{
0x12
,
0x34
,
0x00
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
};
static
BYTE
msg_winehq
[]
=
/* valid answer for winehq.org */
{
0x12
,
0x34
,
0x81
,
0x80
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x06
,
'w'
,
'i'
,
'n'
,
'e'
,
'h'
,
'q'
,
0x03
,
'o'
,
'r'
,
'g'
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0xc0
,
0x0c
,
0x00
,
0x01
,
0x00
,
0x01
,
0x04
,
0x05
,
0x06
,
0x07
,
0x00
,
0x04
,
0x04
,
0x04
,
0x51
,
0x7c
};
static
BYTE
msg_invchars
[]
=
/* invalid characters in name */
{
0x12
,
0x34
,
0x81
,
0x80
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x02
,
'a'
,
'$'
,
0x02
,
'b'
,
'\\'
,
0x02
,
'c'
,
'.'
,
0x02
,
0x09
,
'd'
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0xc0
,
0x0c
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x04
,
0x04
,
0x04
,
0x51
,
0x7c
};
static
BYTE
msg_root
[]
=
/* root name */
{
0x12
,
0x34
,
0x81
,
0x80
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0xc0
,
0x0c
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x04
,
0x04
,
0x04
,
0x51
,
0x7c
};
static
BYTE
msg_label
[]
=
/* name with binary label, not supported on Windows */
{
0x12
,
0x34
,
0x81
,
0x80
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x03
,
'a'
,
'b'
,
'c'
,
0x41
,
0x01
,
0x34
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
0xc0
,
0x0c
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x04
,
0x04
,
0x04
,
0x51
,
0x7c
};
static
BYTE
msg_loop
[]
=
/* name with loop */
{
0x12
,
0x34
,
0x81
,
0x80
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0xc0
,
0x0c
,
0x00
,
0x01
,
0x00
,
0x01
,
0xc0
,
0x0c
,
0x00
,
0x01
,
0x00
,
0x01
,
0x00
,
0x00
,
0x00
,
0x01
,
0x00
,
0x04
,
0x04
,
0x04
,
0x51
,
0x7c
};
static
BYTE
msg_types
[]
=
/* various record types */
{
0x12
,
0x34
,
0x81
,
0x80
,
0x01
,
0x00
,
0x05
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x06
,
'w'
,
'i'
,
'n'
,
'e'
,
'h'
,
'q'
,
0x03
,
'o'
,
'r'
,
'g'
,
0x00
,
0x00
,
0x01
,
0x00
,
0x01
,
/* CNAME */
0xc0
,
0x0c
,
0x00
,
0x05
,
0x00
,
0x01
,
0x04
,
0x05
,
0x06
,
0x07
,
0x00
,
0x05
,
0x01
,
'a'
,
0x01
,
'b'
,
0x00
,
/* MX */
0xc0
,
0x0c
,
0x00
,
0x0f
,
0x00
,
0x01
,
0x04
,
0x05
,
0x06
,
0x07
,
0x00
,
0x07
,
0x03
,
0x04
,
0x01
,
'c'
,
0x01
,
'd'
,
0x00
,
/* AAAA */
0xc0
,
0x0c
,
0x00
,
0x1c
,
0x00
,
0x01
,
0x04
,
0x05
,
0x06
,
0x07
,
0x00
,
0x10
,
0x01
,
0x02
,
0x03
,
0x04
,
0x05
,
0x06
,
0x07
,
0x08
,
0x09
,
0x0a
,
0x0b
,
0x0c
,
0x0d
,
0x0e
,
0x0f
,
0x00
,
/* KEY */
0xc0
,
0x0c
,
0x00
,
0x19
,
0x00
,
0x01
,
0x04
,
0x05
,
0x06
,
0x07
,
0x00
,
0x06
,
0x11
,
0x22
,
0x33
,
0x44
,
0x55
,
0x66
,
/* TXT */
0x01
,
't'
,
0x01
,
'x'
,
0x00
,
0x00
,
0x10
,
0x00
,
0x01
,
0x04
,
0x05
,
0x06
,
0x07
,
0x00
,
0x09
,
0x02
,
'z'
,
'y'
,
0x00
,
0x04
,
'X'
,
'Y'
,
0xc3
,
0xa9
};
static
void
test_DnsExtractRecordsFromMessage
(
void
)
{
DNS_STATUS
ret
;
DNS_RECORDA
*
rec
,
*
r
;
DNS_RECORDW
*
recW
,
*
rW
;
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_empty
,
sizeof
(
msg_empty
)
-
1
,
&
rec
);
ok
(
ret
==
ERROR_INVALID_PARAMETER
||
broken
(
ret
==
DNS_ERROR_BAD_PACKET
)
/* win7 */
,
"failed %u
\n
"
,
ret
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_empty
,
sizeof
(
msg_empty
),
&
rec
);
ok
(
ret
==
DNS_ERROR_BAD_PACKET
,
"failed %u
\n
"
,
ret
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_empty_answer
,
sizeof
(
msg_empty_answer
),
&
rec
);
ok
(
ret
==
DNS_ERROR_BAD_PACKET
,
"failed %u
\n
"
,
ret
);
rec
=
(
void
*
)
0xdeadbeef
;
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_question
,
sizeof
(
msg_question
),
&
rec
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
ok
(
!
rec
,
"record %p
\n
"
,
rec
);
rec
=
(
void
*
)
0xdeadbeef
;
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_winehq
,
sizeof
(
msg_winehq
),
&
rec
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
ok
(
rec
!=
NULL
,
"record not set
\n
"
);
ok
(
!
strcmp
(
rec
->
pName
,
"winehq.org"
),
"wrong name %s
\n
"
,
rec
->
pName
);
ok
(
rec
->
Flags
.
S
.
Section
==
DnsSectionAnswer
,
"wrong section %u
\n
"
,
rec
->
Flags
.
S
.
Section
);
ok
(
rec
->
Flags
.
S
.
CharSet
==
DnsCharSetUtf8
,
"wrong charset %u
\n
"
,
rec
->
Flags
.
S
.
CharSet
);
ok
(
rec
->
wType
==
DNS_TYPE_A
,
"wrong type %u
\n
"
,
rec
->
wType
);
ok
(
rec
->
wDataLength
==
sizeof
(
DNS_A_DATA
),
"wrong len %u
\n
"
,
rec
->
wDataLength
);
ok
(
rec
->
dwTtl
==
0x04050607
,
"wrong ttl %x
\n
"
,
rec
->
dwTtl
);
ok
(
rec
->
Data
.
A
.
IpAddress
==
0x7c510404
,
"wrong addr %08x
\n
"
,
rec
->
Data
.
A
.
IpAddress
);
ok
(
!
rec
->
pNext
,
"next record %p
\n
"
,
rec
->
pNext
);
DnsRecordListFree
(
(
DNS_RECORD
*
)
rec
,
DnsFreeRecordList
);
recW
=
(
void
*
)
0xdeadbeef
;
ret
=
DnsExtractRecordsFromMessage_W
(
(
DNS_MESSAGE_BUFFER
*
)
msg_winehq
,
sizeof
(
msg_winehq
),
&
recW
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
ok
(
recW
!=
NULL
,
"record not set
\n
"
);
ok
(
!
wcscmp
(
recW
->
pName
,
L"winehq.org"
),
"wrong name %s
\n
"
,
debugstr_w
(
recW
->
pName
)
);
DnsRecordListFree
(
(
DNS_RECORD
*
)
recW
,
DnsFreeRecordList
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_invchars
,
sizeof
(
msg_invchars
),
&
rec
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
ok
(
!
strcmp
(
rec
->
pName
,
"a$.b
\\
.c..
\t
d"
),
"wrong name %s
\n
"
,
rec
->
pName
);
DnsRecordListFree
(
(
DNS_RECORD
*
)
rec
,
DnsFreeRecordList
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_root
,
sizeof
(
msg_root
),
&
rec
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
ok
(
!
strcmp
(
rec
->
pName
,
"."
),
"wrong name %s
\n
"
,
rec
->
pName
);
DnsRecordListFree
(
(
DNS_RECORD
*
)
rec
,
DnsFreeRecordList
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_label
,
sizeof
(
msg_label
),
&
rec
);
ok
(
ret
==
DNS_ERROR_BAD_PACKET
,
"failed %u
\n
"
,
ret
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_loop
,
sizeof
(
msg_loop
),
&
rec
);
ok
(
ret
==
DNS_ERROR_BAD_PACKET
,
"failed %u
\n
"
,
ret
);
ret
=
DnsExtractRecordsFromMessage_UTF8
(
(
DNS_MESSAGE_BUFFER
*
)
msg_types
,
sizeof
(
msg_types
),
&
rec
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
r
=
rec
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
strcmp
(
r
->
pName
,
"winehq.org"
),
"wrong name %s
\n
"
,
r
->
pName
);
ok
(
r
->
wType
==
DNS_TYPE_CNAME
,
"wrong type %u
\n
"
,
r
->
wType
);
ok
(
!
strcmp
(
r
->
Data
.
CNAME
.
pNameHost
,
"a.b"
),
"wrong cname %s
\n
"
,
r
->
Data
.
CNAME
.
pNameHost
);
ok
(
r
->
wDataLength
==
sizeof
(
DNS_PTR_DATAA
)
+
4
,
"wrong len %x
\n
"
,
r
->
wDataLength
);
r
=
r
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
strcmp
(
r
->
pName
,
"winehq.org"
),
"wrong name %s
\n
"
,
r
->
pName
);
ok
(
r
->
wType
==
DNS_TYPE_MX
,
"wrong type %u
\n
"
,
r
->
wType
);
ok
(
r
->
Data
.
MX
.
wPreference
==
0x0304
,
"wrong pref %x
\n
"
,
r
->
Data
.
MX
.
wPreference
);
ok
(
!
strcmp
(
r
->
Data
.
MX
.
pNameExchange
,
"c.d"
),
"wrong mx %s
\n
"
,
r
->
Data
.
MX
.
pNameExchange
);
ok
(
r
->
wDataLength
==
sizeof
(
DNS_MX_DATAA
)
+
4
,
"wrong len %x
\n
"
,
r
->
wDataLength
);
r
=
r
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
strcmp
(
r
->
pName
,
"winehq.org"
),
"wrong name %s
\n
"
,
r
->
pName
);
ok
(
r
->
wType
==
DNS_TYPE_AAAA
,
"wrong type %u
\n
"
,
r
->
wType
);
ok
(
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
0
]
==
0x04030201
,
"wrong addr %x
\n
"
,
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
0
]
);
ok
(
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
1
]
==
0x08070605
,
"wrong addr %x
\n
"
,
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
1
]
);
ok
(
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
2
]
==
0x0c0b0a09
,
"wrong addr %x
\n
"
,
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
2
]
);
ok
(
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
3
]
==
0x000f0e0d
,
"wrong addr %x
\n
"
,
r
->
Data
.
AAAA
.
Ip6Address
.
IP6Dword
[
3
]
);
ok
(
r
->
wDataLength
==
sizeof
(
DNS_AAAA_DATA
),
"wrong len %x
\n
"
,
r
->
wDataLength
);
r
=
r
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
strcmp
(
r
->
pName
,
"winehq.org"
),
"wrong name %s
\n
"
,
r
->
pName
);
ok
(
r
->
wType
==
DNS_TYPE_KEY
,
"wrong type %u
\n
"
,
r
->
wType
);
ok
(
r
->
Data
.
KEY
.
wFlags
==
0x1122
,
"wrong flags %x
\n
"
,
r
->
Data
.
KEY
.
wFlags
);
ok
(
r
->
Data
.
KEY
.
chProtocol
==
0x33
,
"wrong protocol %x
\n
"
,
r
->
Data
.
KEY
.
chProtocol
);
ok
(
r
->
Data
.
KEY
.
chAlgorithm
==
0x44
,
"wrong algorithm %x
\n
"
,
r
->
Data
.
KEY
.
chAlgorithm
);
ok
(
r
->
Data
.
KEY
.
wKeyLength
==
0x02
,
"wrong len %x
\n
"
,
r
->
Data
.
KEY
.
wKeyLength
);
ok
(
r
->
Data
.
KEY
.
Key
[
0
]
==
0x55
,
"wrong key %x
\n
"
,
r
->
Data
.
KEY
.
Key
[
0
]
);
ok
(
r
->
Data
.
KEY
.
Key
[
1
]
==
0x66
,
"wrong key %x
\n
"
,
r
->
Data
.
KEY
.
Key
[
1
]
);
ok
(
r
->
wDataLength
==
offsetof
(
DNS_KEY_DATA
,
Key
[
r
->
Data
.
KEY
.
wKeyLength
]
),
"wrong len %x
\n
"
,
r
->
wDataLength
);
r
=
r
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
strcmp
(
r
->
pName
,
"t.x"
),
"wrong name %s
\n
"
,
r
->
pName
);
ok
(
r
->
wType
==
DNS_TYPE_TEXT
,
"wrong type %u
\n
"
,
r
->
wType
);
ok
(
r
->
Data
.
TXT
.
dwStringCount
==
3
,
"wrong count %u
\n
"
,
r
->
Data
.
TXT
.
dwStringCount
);
ok
(
!
strcmp
(
r
->
Data
.
TXT
.
pStringArray
[
0
],
"zy"
),
"wrong string %s
\n
"
,
r
->
Data
.
TXT
.
pStringArray
[
0
]
);
ok
(
!
strcmp
(
r
->
Data
.
TXT
.
pStringArray
[
1
],
""
),
"wrong string %s
\n
"
,
r
->
Data
.
TXT
.
pStringArray
[
1
]
);
ok
(
!
strcmp
(
r
->
Data
.
TXT
.
pStringArray
[
2
],
"XY
\xc3\xa9
"
),
"wrong string %s
\n
"
,
r
->
Data
.
TXT
.
pStringArray
[
2
]
);
ok
(
r
->
wDataLength
==
offsetof
(
DNS_TXT_DATAA
,
pStringArray
[
r
->
Data
.
TXT
.
dwStringCount
]
),
"wrong len %x
\n
"
,
r
->
wDataLength
);
ok
(
!
r
->
pNext
,
"next record %p
\n
"
,
r
->
pNext
);
DnsRecordListFree
(
(
DNS_RECORD
*
)
rec
,
DnsFreeRecordList
);
ret
=
DnsExtractRecordsFromMessage_W
(
(
DNS_MESSAGE_BUFFER
*
)
msg_types
,
sizeof
(
msg_types
),
&
recW
);
ok
(
!
ret
,
"failed %u
\n
"
,
ret
);
rW
=
recW
;
ok
(
rW
!=
NULL
,
"record not set
\n
"
);
ok
(
!
wcscmp
(
rW
->
pName
,
L"winehq.org"
),
"wrong name %s
\n
"
,
debugstr_w
(
rW
->
pName
)
);
ok
(
rW
->
wType
==
DNS_TYPE_CNAME
,
"wrong type %u
\n
"
,
rW
->
wType
);
ok
(
!
wcscmp
(
rW
->
Data
.
CNAME
.
pNameHost
,
L"a.b"
),
"wrong cname %s
\n
"
,
debugstr_w
(
rW
->
Data
.
CNAME
.
pNameHost
)
);
rW
=
rW
->
pNext
;
ok
(
rW
!=
NULL
,
"record not set
\n
"
);
ok
(
!
wcscmp
(
rW
->
pName
,
L"winehq.org"
),
"wrong name %s
\n
"
,
debugstr_w
(
rW
->
pName
)
);
ok
(
rW
->
wType
==
DNS_TYPE_MX
,
"wrong type %u
\n
"
,
rW
->
wType
);
ok
(
!
wcscmp
(
rW
->
Data
.
MX
.
pNameExchange
,
L"c.d"
),
"wrong mx %s
\n
"
,
debugstr_w
(
rW
->
Data
.
MX
.
pNameExchange
)
);
rW
=
rW
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
wcscmp
(
rW
->
pName
,
L"winehq.org"
),
"wrong name %s
\n
"
,
debugstr_w
(
rW
->
pName
)
);
ok
(
rW
->
wType
==
DNS_TYPE_AAAA
,
"wrong type %u
\n
"
,
rW
->
wType
);
rW
=
rW
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
wcscmp
(
rW
->
pName
,
L"winehq.org"
),
"wrong name %s
\n
"
,
debugstr_w
(
rW
->
pName
)
);
rW
=
rW
->
pNext
;
ok
(
r
!=
NULL
,
"record not set
\n
"
);
ok
(
!
wcscmp
(
rW
->
pName
,
L"t.x"
),
"wrong name %s
\n
"
,
debugstr_w
(
rW
->
pName
)
);
ok
(
rW
->
wType
==
DNS_TYPE_TEXT
,
"wrong type %u
\n
"
,
rW
->
wType
);
ok
(
rW
->
Data
.
TXT
.
dwStringCount
==
3
,
"wrong count %u
\n
"
,
rW
->
Data
.
TXT
.
dwStringCount
);
ok
(
!
wcscmp
(
rW
->
Data
.
TXT
.
pStringArray
[
0
],
L"zy"
),
"wrong string %s
\n
"
,
debugstr_w
(
rW
->
Data
.
TXT
.
pStringArray
[
0
])
);
ok
(
!
wcscmp
(
rW
->
Data
.
TXT
.
pStringArray
[
1
],
L""
),
"wrong string %s
\n
"
,
debugstr_w
(
rW
->
Data
.
TXT
.
pStringArray
[
1
])
);
ok
(
!
wcscmp
(
rW
->
Data
.
TXT
.
pStringArray
[
2
],
L"XY
\x00e9
"
),
"wrong string %s
\n
"
,
debugstr_w
(
rW
->
Data
.
TXT
.
pStringArray
[
2
])
);
ok
(
!
rW
->
pNext
,
"next record %p
\n
"
,
rW
->
pNext
);
DnsRecordListFree
(
(
DNS_RECORD
*
)
recW
,
DnsFreeRecordList
);
}
START_TEST
(
record
)
{
test_DnsRecordCompare
();
test_DnsRecordSetCompare
();
test_DnsRecordSetDetach
();
test_DnsExtractRecordsFromMessage
();
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment