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