ZoneParser: error on parsing an IPv6 address in an A record (#923)
* ZoneParser: error on parsing an IPv6 address in an A record
And vice versa for IPv4 with AAAA.
The implementation of isIPv6 is inspired by e341bae08d/src/net/ip.go (L678-L681)
.
* Fix benchmarks that try to use ::1 as A record.
* Test A/AAAA parsing via NewRR rather than zone parser.
* Document why we distinguish IPv4 vs IPv6 via existence of ":".
This commit is contained in:
parent
e838e1e3ce
commit
487e4636d5
|
@ -233,7 +233,7 @@ func BenchmarkUnpackMX(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkPackAAAAA(b *testing.B) {
|
func BenchmarkPackAAAAA(b *testing.B) {
|
||||||
aaaa := testRR(". IN A ::1")
|
aaaa := testRR(". IN AAAA ::1")
|
||||||
|
|
||||||
buf := make([]byte, Len(aaaa))
|
buf := make([]byte, Len(aaaa))
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
|
@ -244,7 +244,7 @@ func BenchmarkPackAAAAA(b *testing.B) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkUnpackAAAA(b *testing.B) {
|
func BenchmarkUnpackAAAA(b *testing.B) {
|
||||||
aaaa := testRR(". IN A ::1")
|
aaaa := testRR(". IN AAAA ::1")
|
||||||
|
|
||||||
buf := make([]byte, Len(aaaa))
|
buf := make([]byte, Len(aaaa))
|
||||||
PackRR(aaaa, buf, 0, nil, false)
|
PackRR(aaaa, buf, 0, nil, false)
|
||||||
|
|
12
scan_rr.go
12
scan_rr.go
|
@ -133,7 +133,12 @@ func (rr *A) parse(c *zlexer, o, f string) *ParseError {
|
||||||
}
|
}
|
||||||
|
|
||||||
rr.A = net.ParseIP(l.token)
|
rr.A = net.ParseIP(l.token)
|
||||||
if rr.A == nil || l.err {
|
// IPv4 addresses cannot include ":".
|
||||||
|
// We do this rather than use net.IP's To4() because
|
||||||
|
// To4() treats IPv4-mapped IPv6 addresses as being
|
||||||
|
// IPv4.
|
||||||
|
isIPv4 := !strings.Contains(l.token, ":")
|
||||||
|
if rr.A == nil || !isIPv4 || l.err {
|
||||||
return &ParseError{f, "bad A A", l}
|
return &ParseError{f, "bad A A", l}
|
||||||
}
|
}
|
||||||
return slurpRemainder(c, f)
|
return slurpRemainder(c, f)
|
||||||
|
@ -146,7 +151,10 @@ func (rr *AAAA) parse(c *zlexer, o, f string) *ParseError {
|
||||||
}
|
}
|
||||||
|
|
||||||
rr.AAAA = net.ParseIP(l.token)
|
rr.AAAA = net.ParseIP(l.token)
|
||||||
if rr.AAAA == nil || l.err {
|
// IPv6 addresses must include ":", and IPv4
|
||||||
|
// addresses cannot include ":".
|
||||||
|
isIPv6 := strings.Contains(l.token, ":")
|
||||||
|
if rr.AAAA == nil || !isIPv6 || l.err {
|
||||||
return &ParseError{f, "bad AAAA AAAA", l}
|
return &ParseError{f, "bad AAAA AAAA", l}
|
||||||
}
|
}
|
||||||
return slurpRemainder(c, f)
|
return slurpRemainder(c, f)
|
||||||
|
|
45
scan_test.go
45
scan_test.go
|
@ -121,6 +121,51 @@ func TestZoneParserIncludeDisallowed(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestZoneParserAddressAAAA(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
record string
|
||||||
|
want *AAAA
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
record: "1.example.org. 600 IN AAAA ::1",
|
||||||
|
want: &AAAA{Hdr: RR_Header{Name: "1.example.org."}, AAAA: net.IPv6loopback},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
record: "2.example.org. 600 IN AAAA ::FFFF:127.0.0.1",
|
||||||
|
want: &AAAA{Hdr: RR_Header{Name: "2.example.org."}, AAAA: net.ParseIP("::FFFF:127.0.0.1")},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range tests {
|
||||||
|
got, err := NewRR(tc.record)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("expected no error, but got %s", err)
|
||||||
|
}
|
||||||
|
aaaa, ok := got.(*AAAA)
|
||||||
|
if !ok {
|
||||||
|
t.Fatalf("expected *AAAA RR, but got %T", aaaa)
|
||||||
|
}
|
||||||
|
if g, w := aaaa.AAAA, tc.want.AAAA; !g.Equal(w) {
|
||||||
|
t.Fatalf("expected AAAA with IP %v, but got %v", g, w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestZoneParserAddressBad(t *testing.T) {
|
||||||
|
records := []string{
|
||||||
|
"1.bad.example.org. 600 IN A ::1",
|
||||||
|
"2.bad.example.org. 600 IN A ::FFFF:127.0.0.1",
|
||||||
|
"3.bad.example.org. 600 IN AAAA 127.0.0.1",
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, record := range records {
|
||||||
|
const expect = "bad A"
|
||||||
|
if got, err := NewRR(record); err == nil || !strings.Contains(err.Error(), expect) {
|
||||||
|
t.Errorf("NewRR(%v) = %v, want err to contain %q", record, got, expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseTA(t *testing.T) {
|
func TestParseTA(t *testing.T) {
|
||||||
rr, err := NewRR(` Ta 0 0 0`)
|
rr, err := NewRR(` Ta 0 0 0`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
Loading…
Reference in New Issue