Add AVC record (#480)
See https://www.iana.org/assignments/dns-parameters/AVC/avc-completed-template for the template, a new record that is (again) a mirror of the TXT record. For lack of a better name, name the rdata Txt - as we do in SPF and TXT.
This commit is contained in:
parent
89d392d274
commit
767422ac12
|
@ -1509,3 +1509,21 @@ func TestParseURI(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseAVC(t *testing.T) {
|
||||
avcs := map[string]string{
|
||||
`example.org. IN AVC "app-name:WOLFGANG|app-class:OAM|business=yes"`: `example.org. 3600 IN AVC "app-name:WOLFGANG|app-class:OAM|business=yes"`,
|
||||
}
|
||||
for avc, o := range avcs {
|
||||
rr, err := NewRR(avc)
|
||||
if err != nil {
|
||||
t.Error("failed to parse RR: ", err)
|
||||
continue
|
||||
}
|
||||
if rr.String() != o {
|
||||
t.Errorf("`%s' should be equal to\n`%s', but is `%s'", avc, o, rr.String())
|
||||
} else {
|
||||
t.Logf("RR is OK: `%s'", rr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
scan_rr.go
13
scan_rr.go
|
@ -1807,6 +1807,18 @@ func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
|
|||
return rr, nil, c1
|
||||
}
|
||||
|
||||
func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
|
||||
rr := new(AVC)
|
||||
rr.Hdr = h
|
||||
|
||||
s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f)
|
||||
if e != nil {
|
||||
return nil, e, ""
|
||||
}
|
||||
rr.Txt = s
|
||||
return rr, nil, c1
|
||||
}
|
||||
|
||||
func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
|
||||
rr := new(TXT)
|
||||
rr.Hdr = h
|
||||
|
@ -2158,6 +2170,7 @@ var typeToparserFunc = map[uint16]parserFunc{
|
|||
TypeSMIMEA: {setSMIMEA, true},
|
||||
TypeSOA: {setSOA, false},
|
||||
TypeSPF: {setSPF, true},
|
||||
TypeAVC: {setAVC, true},
|
||||
TypeSRV: {setSRV, false},
|
||||
TypeSSHFP: {setSSHFP, true},
|
||||
TypeTALINK: {setTALINK, false},
|
||||
|
|
8
types.go
8
types.go
|
@ -91,6 +91,7 @@ const (
|
|||
TypeEUI64 uint16 = 109
|
||||
TypeURI uint16 = 256
|
||||
TypeCAA uint16 = 257
|
||||
TypeAVC uint16 = 258
|
||||
|
||||
TypeTKEY uint16 = 249
|
||||
TypeTSIG uint16 = 250
|
||||
|
@ -530,6 +531,13 @@ type SPF struct {
|
|||
|
||||
func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
|
||||
|
||||
type AVC struct {
|
||||
Hdr RR_Header
|
||||
Txt []string `dns:"txt"`
|
||||
}
|
||||
|
||||
func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
|
||||
|
||||
type SRV struct {
|
||||
Hdr RR_Header
|
||||
Priority uint16
|
||||
|
|
146
zcompress.go
146
zcompress.go
|
@ -5,99 +5,95 @@ package dns
|
|||
|
||||
func compressionLenHelperType(c map[string]int, r RR) {
|
||||
switch x := r.(type) {
|
||||
case *KX:
|
||||
compressionLenHelper(c, x.Exchanger)
|
||||
case *MX:
|
||||
compressionLenHelper(c, x.Mx)
|
||||
case *NSEC:
|
||||
compressionLenHelper(c, x.NextDomain)
|
||||
case *DNAME:
|
||||
compressionLenHelper(c, x.Target)
|
||||
case *HIP:
|
||||
for i := range x.RendezvousServers {
|
||||
compressionLenHelper(c, x.RendezvousServers[i])
|
||||
}
|
||||
case *CNAME:
|
||||
compressionLenHelper(c, x.Target)
|
||||
case *MR:
|
||||
compressionLenHelper(c, x.Mr)
|
||||
case *PX:
|
||||
compressionLenHelper(c, x.Map822)
|
||||
compressionLenHelper(c, x.Mapx400)
|
||||
case *SIG:
|
||||
compressionLenHelper(c, x.SignerName)
|
||||
case *SRV:
|
||||
compressionLenHelper(c, x.Target)
|
||||
case *TALINK:
|
||||
compressionLenHelper(c, x.PreviousName)
|
||||
compressionLenHelper(c, x.NextName)
|
||||
case *LP:
|
||||
compressionLenHelper(c, x.Fqdn)
|
||||
case *NAPTR:
|
||||
compressionLenHelper(c, x.Replacement)
|
||||
case *NS:
|
||||
compressionLenHelper(c, x.Ns)
|
||||
case *RP:
|
||||
compressionLenHelper(c, x.Mbox)
|
||||
compressionLenHelper(c, x.Txt)
|
||||
case *RRSIG:
|
||||
compressionLenHelper(c, x.SignerName)
|
||||
case *TKEY:
|
||||
compressionLenHelper(c, x.Algorithm)
|
||||
case *TSIG:
|
||||
compressionLenHelper(c, x.Algorithm)
|
||||
case *AFSDB:
|
||||
compressionLenHelper(c, x.Hostname)
|
||||
case *MF:
|
||||
compressionLenHelper(c, x.Mf)
|
||||
case *RT:
|
||||
compressionLenHelper(c, x.Host)
|
||||
case *MINFO:
|
||||
compressionLenHelper(c, x.Rmail)
|
||||
compressionLenHelper(c, x.Email)
|
||||
case *PTR:
|
||||
compressionLenHelper(c, x.Ptr)
|
||||
case *SOA:
|
||||
compressionLenHelper(c, x.Ns)
|
||||
compressionLenHelper(c, x.Mbox)
|
||||
case *MD:
|
||||
compressionLenHelper(c, x.Md)
|
||||
case *NSAPPTR:
|
||||
compressionLenHelper(c, x.Ptr)
|
||||
case *MG:
|
||||
compressionLenHelper(c, x.Mg)
|
||||
case *AFSDB:
|
||||
compressionLenHelper(c, x.Hostname)
|
||||
case *HIP:
|
||||
for i := range x.RendezvousServers {
|
||||
compressionLenHelper(c, x.RendezvousServers[i])
|
||||
}
|
||||
case *LP:
|
||||
compressionLenHelper(c, x.Fqdn)
|
||||
case *CNAME:
|
||||
compressionLenHelper(c, x.Target)
|
||||
case *MB:
|
||||
compressionLenHelper(c, x.Mb)
|
||||
case *RP:
|
||||
compressionLenHelper(c, x.Mbox)
|
||||
compressionLenHelper(c, x.Txt)
|
||||
case *RRSIG:
|
||||
compressionLenHelper(c, x.SignerName)
|
||||
case *MF:
|
||||
compressionLenHelper(c, x.Mf)
|
||||
case *MINFO:
|
||||
compressionLenHelper(c, x.Rmail)
|
||||
compressionLenHelper(c, x.Email)
|
||||
case *SIG:
|
||||
compressionLenHelper(c, x.SignerName)
|
||||
case *SRV:
|
||||
compressionLenHelper(c, x.Target)
|
||||
case *TSIG:
|
||||
compressionLenHelper(c, x.Algorithm)
|
||||
case *KX:
|
||||
compressionLenHelper(c, x.Exchanger)
|
||||
case *MG:
|
||||
compressionLenHelper(c, x.Mg)
|
||||
case *NSAPPTR:
|
||||
compressionLenHelper(c, x.Ptr)
|
||||
case *PX:
|
||||
compressionLenHelper(c, x.Map822)
|
||||
compressionLenHelper(c, x.Mapx400)
|
||||
case *DNAME:
|
||||
compressionLenHelper(c, x.Target)
|
||||
case *MR:
|
||||
compressionLenHelper(c, x.Mr)
|
||||
case *MX:
|
||||
compressionLenHelper(c, x.Mx)
|
||||
case *TKEY:
|
||||
compressionLenHelper(c, x.Algorithm)
|
||||
case *NSEC:
|
||||
compressionLenHelper(c, x.NextDomain)
|
||||
case *TALINK:
|
||||
compressionLenHelper(c, x.PreviousName)
|
||||
compressionLenHelper(c, x.NextName)
|
||||
case *MD:
|
||||
compressionLenHelper(c, x.Md)
|
||||
case *NAPTR:
|
||||
compressionLenHelper(c, x.Replacement)
|
||||
case *NS:
|
||||
compressionLenHelper(c, x.Ns)
|
||||
case *RT:
|
||||
compressionLenHelper(c, x.Host)
|
||||
}
|
||||
}
|
||||
|
||||
func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
|
||||
switch x := r.(type) {
|
||||
case *MF:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mf)
|
||||
return k1, ok1
|
||||
case *MG:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mg)
|
||||
return k1, ok1
|
||||
case *MINFO:
|
||||
k1, ok1 := compressionLenSearch(c, x.Rmail)
|
||||
k2, ok2 := compressionLenSearch(c, x.Email)
|
||||
return k1 + k2, ok1 && ok2
|
||||
case *MR:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mr)
|
||||
return k1, ok1
|
||||
case *PTR:
|
||||
k1, ok1 := compressionLenSearch(c, x.Ptr)
|
||||
return k1, ok1
|
||||
case *AFSDB:
|
||||
k1, ok1 := compressionLenSearch(c, x.Hostname)
|
||||
return k1, ok1
|
||||
case *CNAME:
|
||||
k1, ok1 := compressionLenSearch(c, x.Target)
|
||||
case *MB:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mb)
|
||||
return k1, ok1
|
||||
case *MD:
|
||||
k1, ok1 := compressionLenSearch(c, x.Md)
|
||||
return k1, ok1
|
||||
case *MF:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mf)
|
||||
return k1, ok1
|
||||
case *NS:
|
||||
k1, ok1 := compressionLenSearch(c, x.Ns)
|
||||
return k1, ok1
|
||||
case *RT:
|
||||
k1, ok1 := compressionLenSearch(c, x.Host)
|
||||
return k1, ok1
|
||||
|
@ -105,15 +101,19 @@ func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
|
|||
k1, ok1 := compressionLenSearch(c, x.Ns)
|
||||
k2, ok2 := compressionLenSearch(c, x.Mbox)
|
||||
return k1 + k2, ok1 && ok2
|
||||
case *MB:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mb)
|
||||
case *CNAME:
|
||||
k1, ok1 := compressionLenSearch(c, x.Target)
|
||||
return k1, ok1
|
||||
case *MINFO:
|
||||
k1, ok1 := compressionLenSearch(c, x.Rmail)
|
||||
k2, ok2 := compressionLenSearch(c, x.Email)
|
||||
return k1 + k2, ok1 && ok2
|
||||
case *MR:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mr)
|
||||
return k1, ok1
|
||||
case *MX:
|
||||
k1, ok1 := compressionLenSearch(c, x.Mx)
|
||||
return k1, ok1
|
||||
case *NS:
|
||||
k1, ok1 := compressionLenSearch(c, x.Ns)
|
||||
return k1, ok1
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
|
32
zmsg.go
32
zmsg.go
|
@ -61,6 +61,20 @@ func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bo
|
|||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *AVC) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
||||
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
headerEnd := off
|
||||
off, err = packStringTxt(rr.Txt, msg, off)
|
||||
if err != nil {
|
||||
return off, err
|
||||
}
|
||||
rr.Header().Rdlength = uint16(off - headerEnd)
|
||||
return off, nil
|
||||
}
|
||||
|
||||
func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
|
||||
off, err := rr.Hdr.pack(msg, off, compression, compress)
|
||||
if err != nil {
|
||||
|
@ -1528,6 +1542,23 @@ func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) {
|
|||
return rr, off, err
|
||||
}
|
||||
|
||||
func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||
rr := new(AVC)
|
||||
rr.Hdr = h
|
||||
if noRdata(h) {
|
||||
return rr, off, nil
|
||||
}
|
||||
var err error
|
||||
rdStart := off
|
||||
_ = rdStart
|
||||
|
||||
rr.Txt, off, err = unpackStringTxt(msg, off)
|
||||
if err != nil {
|
||||
return rr, off, err
|
||||
}
|
||||
return rr, off, err
|
||||
}
|
||||
|
||||
func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
|
||||
rr := new(CAA)
|
||||
rr.Hdr = h
|
||||
|
@ -3467,6 +3498,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
|
|||
TypeAAAA: unpackAAAA,
|
||||
TypeAFSDB: unpackAFSDB,
|
||||
TypeANY: unpackANY,
|
||||
TypeAVC: unpackAVC,
|
||||
TypeCAA: unpackCAA,
|
||||
TypeCDNSKEY: unpackCDNSKEY,
|
||||
TypeCDS: unpackCDS,
|
||||
|
|
15
ztypes.go
15
ztypes.go
|
@ -14,6 +14,7 @@ var TypeToRR = map[uint16]func() RR{
|
|||
TypeAAAA: func() RR { return new(AAAA) },
|
||||
TypeAFSDB: func() RR { return new(AFSDB) },
|
||||
TypeANY: func() RR { return new(ANY) },
|
||||
TypeAVC: func() RR { return new(AVC) },
|
||||
TypeCAA: func() RR { return new(CAA) },
|
||||
TypeCDNSKEY: func() RR { return new(CDNSKEY) },
|
||||
TypeCDS: func() RR { return new(CDS) },
|
||||
|
@ -86,6 +87,7 @@ var TypeToString = map[uint16]string{
|
|||
TypeAFSDB: "AFSDB",
|
||||
TypeANY: "ANY",
|
||||
TypeATMA: "ATMA",
|
||||
TypeAVC: "AVC",
|
||||
TypeAXFR: "AXFR",
|
||||
TypeCAA: "CAA",
|
||||
TypeCDNSKEY: "CDNSKEY",
|
||||
|
@ -166,6 +168,7 @@ func (rr *A) Header() *RR_Header { return &rr.Hdr }
|
|||
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *AVC) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
|
||||
func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
|
||||
|
@ -252,6 +255,13 @@ func (rr *ANY) len() int {
|
|||
l := rr.Hdr.len()
|
||||
return l
|
||||
}
|
||||
func (rr *AVC) len() int {
|
||||
l := rr.Hdr.len()
|
||||
for _, x := range rr.Txt {
|
||||
l += len(x) + 1
|
||||
}
|
||||
return l
|
||||
}
|
||||
func (rr *CAA) len() int {
|
||||
l := rr.Hdr.len()
|
||||
l++ // Flag
|
||||
|
@ -649,6 +659,11 @@ func (rr *AFSDB) copy() RR {
|
|||
func (rr *ANY) copy() RR {
|
||||
return &ANY{*rr.Hdr.copyHeader()}
|
||||
}
|
||||
func (rr *AVC) copy() RR {
|
||||
Txt := make([]string, len(rr.Txt))
|
||||
copy(Txt, rr.Txt)
|
||||
return &AVC{*rr.Hdr.copyHeader(), Txt}
|
||||
}
|
||||
func (rr *CAA) copy() RR {
|
||||
return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue