closes #4
+30
-1
resource_record.go
+30
-1
resource_record.go
···
26
26
return nil, fmt.Errorf("A record: cannot encode non-IPv4 address %s", a.Address.String())
27
27
}
28
28
29
-
return append(bytes, a.Address.To4()...), nil
29
+
return append(bytes, ipv4...), nil
30
30
}
31
31
32
32
func (a A) String() string {
···
751
751
return fmt.Sprintf("%d %s", rt.Preference, rt.IntermediateHost)
752
752
}
753
753
754
+
func (a *AAAA) Decode(buf []byte, offset int, rdlength int) (int, error) {
755
+
bytes, offset, err := getSlice(buf, offset, rdlength)
756
+
if err != nil {
757
+
return offset, fmt.Errorf("AAAA record: failed to read address data: %w", err)
758
+
}
759
+
760
+
a.Address = net.IP(bytes)
761
+
if a.Address.To16() == nil {
762
+
return offset, fmt.Errorf("AAAA record: decoded data is not a valid IPv6 address: %v", bytes)
763
+
}
764
+
return offset, nil
765
+
}
766
+
767
+
func (a *AAAA) Encode(bytes []byte, offsets *map[string]uint16) ([]byte, error) {
768
+
ipv6 := a.Address.To16()
769
+
// XXX: ipv6 encodes ipv4 so need to check its not ipv4
770
+
if a.Address.To4() != nil || ipv6 == nil {
771
+
return nil, fmt.Errorf("AAAA record: cannot encode non-IPv6 address %s", a.Address.String())
772
+
}
773
+
774
+
return append(bytes, ipv6...), nil
775
+
}
776
+
777
+
func (a AAAA) String() string {
778
+
return a.Address.String()
779
+
}
780
+
754
781
func (opt *OPT) Decode(buf []byte, offset int, rdlength int) (int, error) {
755
782
// s := offset
756
783
opt.Options = make([]EDNSOption, 0)
···
915
942
r.RData = &ISDN{}
916
943
case 21:
917
944
r.RData = &RT{}
945
+
case 28:
946
+
r.RData = &AAAA{}
918
947
case 41:
919
948
r.RData = &OPT{}
920
949
default:
+30
resource_record_test.go
+30
resource_record_test.go
···
516
516
})
517
517
}
518
518
}
519
+
520
+
func TestAAAARecord(t *testing.T) {
521
+
addr := net.ParseIP("2001:db8::1")
522
+
rdataBytes := []byte(addr)
523
+
aaaa := &AAAA{}
524
+
525
+
offset, err := aaaa.Decode([]byte{}, 0, 16)
526
+
assert.Error(t, err, "Decode should fail with empty buffer")
527
+
assert.True(t, errors.Is(err, &BufferOverflowError{}))
528
+
529
+
offset, err = aaaa.Decode(rdataBytes, 0, 16)
530
+
assert.NoError(t, err)
531
+
assert.Equal(t, 16, offset)
532
+
assert.Equal(t, addr, aaaa.Address)
533
+
534
+
_, err = aaaa.Decode([]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, 0, 15)
535
+
assert.Error(t, err)
536
+
assert.Contains(t, err.Error(), "AAAA record:")
537
+
538
+
aaaaEncode := &AAAA{Address: addr}
539
+
encoded := encodeRData(t, aaaaEncode)
540
+
assert.Equal(t, rdataBytes, encoded)
541
+
542
+
ipv4 := net.ParseIP("192.168.1.1")
543
+
aaaaEncodeInvalid := &AAAA{Address: ipv4}
544
+
_, err = aaaaEncodeInvalid.Encode([]byte{}, &map[string]uint16{})
545
+
546
+
assert.Error(t, err)
547
+
assert.Contains(t, err.Error(), "cannot encode non-IPv6 address")
548
+
}
+7
types.go
+7
types.go
···
92
92
X25Type = 19
93
93
ISDNType = 20
94
94
RTType = 21
95
+
AAAAType = 28
95
96
96
97
OPTType = 41
97
98
···
145
146
return "ISDN"
146
147
case RTType:
147
148
return "RT"
149
+
case AAAAType:
150
+
return "AAAA"
148
151
case OPTType:
149
152
return "OPT"
150
153
case AXFRType:
···
375
378
IntermediateHost string
376
379
}
377
380
381
+
type AAAA struct {
382
+
Address net.IP
383
+
}
384
+
378
385
type EDNSOption struct {
379
386
Code uint16
380
387
Data []byte