Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
f1bc7120
Commit
f1bc7120
authored
Jul 07, 2009
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
net: use new reflect interface (CL 31107)
R=r DELTA=186 (55 added, 8 deleted, 123 changed) OCL=31117 CL=31287
parent
1b359698
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
177 additions
and
130 deletions
+177
-130
dnsclient.go
src/pkg/net/dnsclient.go
+4
-4
dnsmsg.go
src/pkg/net/dnsmsg.go
+173
-126
No files found.
src/pkg/net/dnsclient.go
View file @
f1bc7120
...
...
@@ -113,16 +113,16 @@ Cname:
for
i
:=
0
;
i
<
len
(
dns
.
answer
);
i
++
{
rr
:=
dns
.
answer
[
i
];
h
:=
rr
.
Header
();
if
h
.
class
==
_DNS_ClassINET
&&
h
.
n
ame
==
name
{
switch
h
.
r
rtype
{
if
h
.
Class
==
_DNS_ClassINET
&&
h
.
N
ame
==
name
{
switch
h
.
R
rtype
{
case
_DNS_TypeA
:
n
:=
len
(
addrs
);
a
:=
rr
.
(
*
_DNS_RR_A
)
.
a
;
a
:=
rr
.
(
*
_DNS_RR_A
)
.
A
;
addrs
=
addrs
[
0
:
n
+
1
];
addrs
[
n
]
=
IPv4
(
byte
(
a
>>
24
),
byte
(
a
>>
16
),
byte
(
a
>>
8
),
byte
(
a
))
.
String
();
case
_DNS_TypeCNAME
:
// redirect to cname
name
=
rr
.
(
*
_DNS_RR_CNAME
)
.
c
name
;
name
=
rr
.
(
*
_DNS_RR_CNAME
)
.
C
name
;
continue
Cname
}
}
...
...
src/pkg/net/dnsmsg.go
View file @
f1bc7120
...
...
@@ -34,7 +34,7 @@ import (
// Wire constants.
const
(
// valid _DNS_RR_Header.
r
rtype and _DNS_Question.qtype
// valid _DNS_RR_Header.
R
rtype and _DNS_Question.qtype
_DNS_TypeA
=
1
;
_DNS_TypeNS
=
2
;
_DNS_TypeMD
=
3
;
...
...
@@ -76,13 +76,13 @@ const (
// The wire format for the DNS packet header.
type
__DNS_Header
struct
{
i
d
uint16
;
b
its
uint16
;
qdcount
,
ancount
,
nscount
,
a
rcount
uint16
;
I
d
uint16
;
B
its
uint16
;
Qdcount
,
Ancount
,
Nscount
,
A
rcount
uint16
;
}
const
(
// __DNS_Header.
b
its
// __DNS_Header.
B
its
_QR
=
1
<<
15
;
// query/response (response=1)
_AA
=
1
<<
10
;
// authoritative
_TC
=
1
<<
9
;
// truncated
...
...
@@ -92,20 +92,20 @@ const (
// DNS queries.
type
_DNS_Question
struct
{
n
ame
string
"domain-name"
;
// "domain-name" specifies encoding; see packers below
q
type
uint16
;
q
class
uint16
;
N
ame
string
"domain-name"
;
// "domain-name" specifies encoding; see packers below
Q
type
uint16
;
Q
class
uint16
;
}
// DNS responses (resource records).
// There are many types of messages,
// but they all share the same header.
type
_DNS_RR_Header
struct
{
n
ame
string
"domain-name"
;
r
rtype
uint16
;
c
lass
uint16
;
t
tl
uint32
;
r
dlength
uint16
;
// length of data after header
N
ame
string
"domain-name"
;
R
rtype
uint16
;
C
lass
uint16
;
T
tl
uint32
;
R
dlength
uint16
;
// length of data after header
}
func
(
h
*
_DNS_RR_Header
)
Header
()
*
_DNS_RR_Header
{
...
...
@@ -120,75 +120,124 @@ type _DNS_RR interface {
// Specific DNS RR formats for each query type.
type
_DNS_RR_CNAME
struct
{
_DNS_RR_Header
;
cname
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Cname
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_CNAME
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_HINFO
struct
{
_DNS_RR_Header
;
cpu
string
;
os
string
;
Hdr
_DNS_RR_Header
;
Cpu
string
;
Os
string
;
}
func
(
rr
*
_DNS_RR_HINFO
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_MB
struct
{
_DNS_RR_Header
;
mb
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Mb
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_MB
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_MG
struct
{
_DNS_RR_Header
;
mg
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Mg
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_MG
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_MINFO
struct
{
_DNS_RR_Header
;
rmail
string
"domain-name"
;
email
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Rmail
string
"domain-name"
;
Email
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_MINFO
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_MR
struct
{
_DNS_RR_Header
;
mr
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Mr
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_MR
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_MX
struct
{
_DNS_RR_Header
;
pref
uint16
;
mx
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Pref
uint16
;
Mx
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_MX
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_NS
struct
{
_DNS_RR_Header
;
ns
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Ns
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_NS
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_PTR
struct
{
_DNS_RR_Header
;
ptr
string
"domain-name"
;
Hdr
_DNS_RR_Header
;
Ptr
string
"domain-name"
;
}
func
(
rr
*
_DNS_RR_PTR
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_SOA
struct
{
_DNS_RR_Header
;
ns
string
"domain-name"
;
mbox
string
"domain-name"
;
serial
uint32
;
refresh
uint32
;
retry
uint32
;
expire
uint32
;
minttl
uint32
;
Hdr
_DNS_RR_Header
;
Ns
string
"domain-name"
;
Mbox
string
"domain-name"
;
Serial
uint32
;
Refresh
uint32
;
Retry
uint32
;
Expire
uint32
;
Minttl
uint32
;
}
func
(
rr
*
_DNS_RR_SOA
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_TXT
struct
{
_DNS_RR_Header
;
txt
string
;
// not domain name
Hdr
_DNS_RR_Header
;
Txt
string
;
// not domain name
}
func
(
rr
*
_DNS_RR_TXT
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
type
_DNS_RR_A
struct
{
_DNS_RR_Header
;
a
uint32
"ipv4"
;
Hdr
_DNS_RR_Header
;
A
uint32
"ipv4"
;
}
func
(
rr
*
_DNS_RR_A
)
Header
()
*
_DNS_RR_Header
{
return
&
rr
.
Hdr
;
}
// Packing and unpacking.
//
// All the packers and unpackers take a (msg []byte, off int)
...
...
@@ -316,28 +365,28 @@ Loop:
return
s
,
off1
,
true
}
// TODO(rsc): Move into generic library?
// Pack a reflect.StructValue into msg. Struct members can only be uint16, uint32, string,
// and other (often anonymous) structs.
func
packStructValue
(
val
reflect
.
StructValue
,
msg
[]
byte
,
off
int
)
(
off1
int
,
ok
bool
)
{
for
i
:=
0
;
i
<
val
.
Len
();
i
++
{
fld
:=
val
.
Field
(
i
);
name
,
typ
,
tag
,
xxx
:=
val
.
Type
()
.
(
reflect
.
StructType
)
.
Field
(
i
);
switch
fld
.
Kind
()
{
func
packStructValue
(
val
*
reflect
.
StructValue
,
msg
[]
byte
,
off
int
)
(
off1
int
,
ok
bool
)
{
for
i
:=
0
;
i
<
val
.
NumField
();
i
++
{
f
:=
val
.
Type
()
.
(
*
reflect
.
StructType
)
.
Field
(
i
);
switch
fv
:=
val
.
Field
(
i
)
.
(
type
)
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown packing type %v"
,
f
ld
.
Type
()
);
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown packing type %v"
,
f
.
Type
);
return
len
(
msg
),
false
;
case
reflect
.
StructKind
:
off
,
ok
=
packStructValue
(
f
ld
.
(
reflect
.
StructValue
)
,
msg
,
off
);
case
reflect
.
Uint16Kind
:
i
:=
f
ld
.
(
reflect
.
Uint16Value
)
.
Get
();
case
*
reflect
.
StructValue
:
off
,
ok
=
packStructValue
(
f
v
,
msg
,
off
);
case
*
reflect
.
Uint16Value
:
i
:=
f
v
.
Get
();
if
off
+
2
>
len
(
msg
)
{
return
len
(
msg
),
false
}
msg
[
off
]
=
byte
(
i
>>
8
);
msg
[
off
+
1
]
=
byte
(
i
);
off
+=
2
;
case
reflect
.
Uint32Kind
:
i
:=
f
ld
.
(
reflect
.
Uint32Value
)
.
Get
();
case
*
reflect
.
Uint32Value
:
i
:=
f
v
.
Get
();
if
off
+
4
>
len
(
msg
)
{
return
len
(
msg
),
false
}
...
...
@@ -346,13 +395,13 @@ func packStructValue(val reflect.StructValue, msg []byte, off int) (off1 int, ok
msg
[
off
+
2
]
=
byte
(
i
>>
8
);
msg
[
off
+
4
]
=
byte
(
i
);
off
+=
4
;
case
reflect
.
StringKind
:
case
*
reflect
.
StringValue
:
// There are multiple string encodings.
// The tag distinguishes ordinary strings from domain names.
s
:=
f
ld
.
(
reflect
.
StringValue
)
.
Get
();
switch
t
ag
{
s
:=
f
v
.
Get
();
switch
f
.
T
ag
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown string tag %v"
,
t
ag
);
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown string tag %v"
,
f
.
T
ag
);
return
len
(
msg
),
false
;
case
"domain-name"
:
off
,
ok
=
packDomainName
(
s
,
msg
,
off
);
...
...
@@ -376,43 +425,46 @@ func packStructValue(val reflect.StructValue, msg []byte, off int) (off1 int, ok
return
off
,
true
}
func
structValue
(
any
interface
{})
*
reflect
.
StructValue
{
return
reflect
.
NewValue
(
any
)
.
(
*
reflect
.
PtrValue
)
.
Elem
()
.
(
*
reflect
.
StructValue
);
}
func
packStruct
(
any
interface
{},
msg
[]
byte
,
off
int
)
(
off1
int
,
ok
bool
)
{
val
:=
reflect
.
NewValue
(
any
)
.
(
reflect
.
PtrValue
)
.
Sub
()
.
(
reflect
.
StructValue
);
off
,
ok
=
packStructValue
(
val
,
msg
,
off
);
off
,
ok
=
packStructValue
(
structValue
(
any
),
msg
,
off
);
return
off
,
ok
}
// TODO(rsc): Move into generic library?
// Unpack a reflect.StructValue from msg.
// Same restrictions as packStructValue.
func
unpackStructValue
(
val
reflect
.
StructValue
,
msg
[]
byte
,
off
int
)
(
off1
int
,
ok
bool
)
{
for
i
:=
0
;
i
<
val
.
Len
();
i
++
{
name
,
typ
,
tag
,
xxx
:=
val
.
Type
()
.
(
reflect
.
StructType
)
.
Field
(
i
);
fld
:=
val
.
Field
(
i
);
switch
fld
.
Kind
()
{
func
unpackStructValue
(
val
*
reflect
.
StructValue
,
msg
[]
byte
,
off
int
)
(
off1
int
,
ok
bool
)
{
for
i
:=
0
;
i
<
val
.
NumField
();
i
++
{
f
:=
val
.
Type
()
.
(
*
reflect
.
StructType
)
.
Field
(
i
);
switch
fv
:=
val
.
Field
(
i
)
.
(
type
)
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown packing type %v"
,
f
ld
.
Type
()
);
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown packing type %v"
,
f
.
Type
);
return
len
(
msg
),
false
;
case
reflect
.
StructKind
:
off
,
ok
=
unpackStructValue
(
f
ld
.
(
reflect
.
StructValue
)
,
msg
,
off
);
case
reflect
.
Uint16Kind
:
case
*
reflect
.
StructValue
:
off
,
ok
=
unpackStructValue
(
f
v
,
msg
,
off
);
case
*
reflect
.
Uint16Value
:
if
off
+
2
>
len
(
msg
)
{
return
len
(
msg
),
false
}
i
:=
uint16
(
msg
[
off
])
<<
8
|
uint16
(
msg
[
off
+
1
]);
f
ld
.
(
reflect
.
Uint16Value
)
.
Set
(
i
);
f
v
.
Set
(
i
);
off
+=
2
;
case
reflect
.
Uint32Kind
:
case
*
reflect
.
Uint32Value
:
if
off
+
4
>
len
(
msg
)
{
return
len
(
msg
),
false
}
i
:=
uint32
(
msg
[
off
])
<<
24
|
uint32
(
msg
[
off
+
1
])
<<
16
|
uint32
(
msg
[
off
+
2
])
<<
8
|
uint32
(
msg
[
off
+
3
]);
f
ld
.
(
reflect
.
Uint32Value
)
.
Set
(
i
);
f
v
.
Set
(
i
);
off
+=
4
;
case
reflect
.
StringKind
:
case
*
reflect
.
StringValue
:
var
s
string
;
switch
t
ag
{
switch
f
.
T
ag
{
default
:
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown string tag %v"
,
t
ag
);
fmt
.
Fprintf
(
os
.
Stderr
,
"net: dns: unknown string tag %v"
,
f
.
T
ag
);
return
len
(
msg
),
false
;
case
"domain-name"
:
s
,
off
,
ok
=
unpackDomainName
(
msg
,
off
);
...
...
@@ -432,15 +484,14 @@ func unpackStructValue(val reflect.StructValue, msg []byte, off int) (off1 int,
off
+=
n
;
s
=
string
(
b
);
}
f
ld
.
(
reflect
.
StringValue
)
.
Set
(
s
);
f
v
.
Set
(
s
);
}
}
return
off
,
true
}
func
unpackStruct
(
any
interface
{},
msg
[]
byte
,
off
int
)
(
off1
int
,
ok
bool
)
{
val
:=
reflect
.
NewValue
(
any
)
.
(
reflect
.
PtrValue
)
.
Sub
()
.
(
reflect
.
StructValue
);
off
,
ok
=
unpackStructValue
(
val
,
msg
,
off
);
off
,
ok
=
unpackStructValue
(
structValue
(
any
),
msg
,
off
);
return
off
,
ok
}
...
...
@@ -448,26 +499,24 @@ func unpackStruct(any interface{}, msg []byte, off int) (off1 int, ok bool) {
// Doesn't care about the string tag "domain-name",
// but does look for an "ipv4" tag on uint32 variables,
// printing them as IP addresses.
func
printStructValue
(
val
reflect
.
StructValue
)
string
{
func
printStructValue
(
val
*
reflect
.
StructValue
)
string
{
s
:=
"{"
;
for
i
:=
0
;
i
<
val
.
Len
();
i
++
{
for
i
:=
0
;
i
<
val
.
NumField
();
i
++
{
if
i
>
0
{
s
+=
", "
;
}
name
,
typ
,
tag
,
xxx
:=
val
.
Type
()
.
(
reflect
.
StructType
)
.
Field
(
i
);
fld
:=
val
.
Field
(
i
);
if
name
!=
""
&&
name
!=
"?"
{
// BUG? Shouldn't the reflect library hide "?" ?
s
+=
name
+
"="
;
}
kind
:=
fld
.
Kind
();
switch
{
case
kind
==
reflect
.
StructKind
:
s
+=
printStructValue
(
fld
.
(
reflect
.
StructValue
));
case
kind
==
reflect
.
Uint32Kind
&&
tag
==
"ipv4"
:
i
:=
fld
.
(
reflect
.
Uint32Value
)
.
Get
();
f
:=
val
.
Type
()
.
(
*
reflect
.
StructType
)
.
Field
(
i
);
if
!
f
.
Anonymous
{
s
+=
f
.
Name
+
"="
;
}
fval
:=
val
.
Field
(
i
);
if
fv
,
ok
:=
fval
.
(
*
reflect
.
StructValue
);
ok
{
s
+=
printStructValue
(
fv
);
}
else
if
fv
,
ok
:=
fval
.
(
*
reflect
.
Uint32Value
);
ok
&&
f
.
Tag
==
"ipv4"
{
i
:=
fv
.
Get
();
s
+=
IPv4
(
byte
(
i
>>
24
),
byte
(
i
>>
16
),
byte
(
i
>>
8
),
byte
(
i
))
.
String
();
default
:
s
+=
fmt
.
Sprint
(
f
ld
.
Interface
())
}
else
{
s
+=
fmt
.
Sprint
(
f
val
.
Interface
())
}
}
s
+=
"}"
;
...
...
@@ -475,9 +524,7 @@ func printStructValue(val reflect.StructValue) string {
}
func
printStruct
(
any
interface
{})
string
{
val
:=
reflect
.
NewValue
(
any
)
.
(
reflect
.
PtrValue
)
.
Sub
()
.
(
reflect
.
StructValue
);
s
:=
printStructValue
(
val
);
return
s
return
printStructValue
(
structValue
(
any
));
}
// Resource record packer.
...
...
@@ -494,7 +541,7 @@ func packRR(rr _DNS_RR, msg []byte, off int) (off2 int, ok bool) {
return
len
(
msg
),
false
}
// pack a third time; redo header with correct data length
rr
.
Header
()
.
r
dlength
=
uint16
(
off2
-
off1
);
rr
.
Header
()
.
R
dlength
=
uint16
(
off2
-
off1
);
packStruct
(
rr
.
Header
(),
msg
,
off
);
return
off2
,
true
}
...
...
@@ -507,11 +554,11 @@ func unpackRR(msg []byte, off int) (rr _DNS_RR, off1 int, ok bool) {
if
off
,
ok
=
unpackStruct
(
&
h
,
msg
,
off
);
!
ok
{
return
nil
,
len
(
msg
),
false
}
end
:=
off
+
int
(
h
.
r
dlength
);
end
:=
off
+
int
(
h
.
R
dlength
);
// make an rr of that type and re-unpack.
// again inefficient but doesn't need to be fast.
mk
,
known
:=
rr_mk
[
int
(
h
.
r
rtype
)];
mk
,
known
:=
rr_mk
[
int
(
h
.
R
rtype
)];
if
!
known
{
return
&
h
,
end
,
true
}
...
...
@@ -551,22 +598,22 @@ func (dns *_DNS_Msg) Pack() (msg []byte, ok bool) {
var
dh
__DNS_Header
;
// Convert convenient _DNS_Msg into wire-like __DNS_Header.
dh
.
i
d
=
dns
.
id
;
dh
.
b
its
=
uint16
(
dns
.
opcode
)
<<
11
|
uint16
(
dns
.
rcode
);
dh
.
I
d
=
dns
.
id
;
dh
.
B
its
=
uint16
(
dns
.
opcode
)
<<
11
|
uint16
(
dns
.
rcode
);
if
dns
.
recursion_available
{
dh
.
b
its
|=
_RA
;
dh
.
B
its
|=
_RA
;
}
if
dns
.
recursion_desired
{
dh
.
b
its
|=
_RD
;
dh
.
B
its
|=
_RD
;
}
if
dns
.
truncated
{
dh
.
b
its
|=
_TC
;
dh
.
B
its
|=
_TC
;
}
if
dns
.
authoritative
{
dh
.
b
its
|=
_AA
;
dh
.
B
its
|=
_AA
;
}
if
dns
.
response
{
dh
.
b
its
|=
_QR
;
dh
.
B
its
|=
_QR
;
}
// Prepare variable sized arrays.
...
...
@@ -575,10 +622,10 @@ func (dns *_DNS_Msg) Pack() (msg []byte, ok bool) {
ns
:=
dns
.
ns
;
extra
:=
dns
.
extra
;
dh
.
q
dcount
=
uint16
(
len
(
question
));
dh
.
a
ncount
=
uint16
(
len
(
answer
));
dh
.
n
scount
=
uint16
(
len
(
ns
));
dh
.
a
rcount
=
uint16
(
len
(
extra
));
dh
.
Q
dcount
=
uint16
(
len
(
question
));
dh
.
A
ncount
=
uint16
(
len
(
answer
));
dh
.
N
scount
=
uint16
(
len
(
ns
));
dh
.
A
rcount
=
uint16
(
len
(
extra
));
// Could work harder to calculate message size,
// but this is far more than we need and not
...
...
@@ -614,20 +661,20 @@ func (dns *_DNS_Msg) Unpack(msg []byte) bool {
if
off
,
ok
=
unpackStruct
(
&
dh
,
msg
,
off
);
!
ok
{
return
false
}
dns
.
id
=
dh
.
i
d
;
dns
.
response
=
(
dh
.
b
its
&
_QR
)
!=
0
;
dns
.
opcode
=
int
(
dh
.
b
its
>>
11
)
&
0xF
;
dns
.
authoritative
=
(
dh
.
b
its
&
_AA
)
!=
0
;
dns
.
truncated
=
(
dh
.
b
its
&
_TC
)
!=
0
;
dns
.
recursion_desired
=
(
dh
.
b
its
&
_RD
)
!=
0
;
dns
.
recursion_available
=
(
dh
.
b
its
&
_RA
)
!=
0
;
dns
.
rcode
=
int
(
dh
.
b
its
&
0xF
);
dns
.
id
=
dh
.
I
d
;
dns
.
response
=
(
dh
.
B
its
&
_QR
)
!=
0
;
dns
.
opcode
=
int
(
dh
.
B
its
>>
11
)
&
0xF
;
dns
.
authoritative
=
(
dh
.
B
its
&
_AA
)
!=
0
;
dns
.
truncated
=
(
dh
.
B
its
&
_TC
)
!=
0
;
dns
.
recursion_desired
=
(
dh
.
B
its
&
_RD
)
!=
0
;
dns
.
recursion_available
=
(
dh
.
B
its
&
_RA
)
!=
0
;
dns
.
rcode
=
int
(
dh
.
B
its
&
0xF
);
// Arrays.
dns
.
question
=
make
([]
_DNS_Question
,
dh
.
q
dcount
);
dns
.
answer
=
make
([]
_DNS_RR
,
dh
.
a
ncount
);
dns
.
ns
=
make
([]
_DNS_RR
,
dh
.
n
scount
);
dns
.
extra
=
make
([]
_DNS_RR
,
dh
.
a
rcount
);
dns
.
question
=
make
([]
_DNS_Question
,
dh
.
Q
dcount
);
dns
.
answer
=
make
([]
_DNS_RR
,
dh
.
A
ncount
);
dns
.
ns
=
make
([]
_DNS_RR
,
dh
.
N
scount
);
dns
.
extra
=
make
([]
_DNS_RR
,
dh
.
A
rcount
);
for
i
:=
0
;
i
<
len
(
dns
.
question
);
i
++
{
off
,
ok
=
unpackStruct
(
&
dns
.
question
[
i
],
msg
,
off
);
...
...
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