Kill all reflection when packing/unpacking RR (#372)

Update the size-xxx-member tags to point to another field in the struct
that should be used for the length in that field. Fix NSEC3/HIP and TSIG
to use to this and generate the correct pack/unpack functions for them.

Remove IPSECKEY from the lib and handle it as an unknown record - it is
such a horrible RR, needed kludges before - now just handle it as an
unknown RR.

All types now use generated pack and unpack functions. The blacklist is
removed.
This commit is contained in:
Miek Gieben 2016-06-12 18:31:50 +01:00 committed by GitHub
parent 6ae3b9f061
commit dbffa4b057
12 changed files with 157 additions and 378 deletions

View File

@ -113,7 +113,6 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 340{1,2,3} - NAPTR record
* 3445 - Limiting the scope of (DNS)KEY
* 3597 - Unknown RRs
* 4025 - IPSECKEY
* 403{3,4,5} - DNSSEC + validation functions
* 4255 - SSHFP record
* 4343 - Case insensitivity

View File

@ -403,31 +403,6 @@ func TestMsgCopy(t *testing.T) {
}
}
func TestPackIPSECKEY(t *testing.T) {
tests := []string{
"38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
}
buf := make([]byte, 1024)
for _, t1 := range tests {
rr, _ := NewRR(t1)
off, err := PackRR(rr, buf, 0, nil, false)
if err != nil {
t.Errorf("failed to pack IPSECKEY %v: %s", err, t1)
continue
}
rr, _, err = UnpackRR(buf[:off], 0)
if err != nil {
t.Errorf("failed to unpack IPSECKEY %v: %s", err, t1)
}
t.Log(rr)
}
}
func TestMsgPackBuffer(t *testing.T) {
var testMessages = []string{
// news.ycombinator.com.in.escapemg.com. IN A, response

37
msg.go
View File

@ -1165,13 +1165,7 @@ func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress boo
return len(msg), &Error{err: "nil rr"}
}
_, ok := blacklist[rr.Header().Rrtype]
switch ok {
case false:
off1, err = rr.pack(msg, off, compression, compress)
default:
off1, err = packStructCompress(rr, msg, off, compression, compress)
}
off1, err = rr.pack(msg, off, compression, compress)
if err != nil {
return len(msg), err
}
@ -1183,29 +1177,16 @@ func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress boo
// UnpackRR unpacks msg[off:] into an RR.
func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
off0 := off
h, off, msg, err := unpackHeader(msg, off)
if err != nil {
return nil, len(msg), err
}
end := off + int(h.Rdlength)
_, ok := blacklist[h.Rrtype]
switch ok {
case false:
// Shortcut reflection.
if fn, known := typeToUnpack[h.Rrtype]; !known {
rr, off, err = unpackRFC3597(h, msg, off)
} else {
rr, off, err = fn(h, msg, off)
}
default:
if mk, known := TypeToRR[h.Rrtype]; !known {
rr = new(RFC3597)
} else {
rr = mk()
}
off, err = UnpackStruct(rr, msg, off0)
if fn, known := typeToUnpack[h.Rrtype]; !known {
rr, off, err = unpackRFC3597(h, msg, off)
} else {
rr, off, err = fn(h, msg, off)
}
if off != end {
return &h, end, &Error{err: "bad rdlength"}
@ -1852,11 +1833,3 @@ func unpackMsgHdr(msg []byte, off int) (Header, int, error) {
dh.Arcount, off, err = unpackUint16(msg, off)
return dh, off, err
}
// Which types do no work reflectionless yet.
var blacklist = map[uint16]bool{
TypeHIP: true,
TypeIPSECKEY: true,
TypeNSEC3: true,
TypeTSIG: true,
}

View File

@ -14,14 +14,9 @@ import (
"go/types"
"log"
"os"
"strings"
)
// All RR pack and unpack functions should be generated, currently RR that present some problems
// * NSEC3 - size hex
// * TSIG - size hex
// * HIP - uses "hex", but is actually size-hex - might drop size-hex?
// * IPSECKEY -
var packageHdr = `
// *** DO NOT MODIFY ***
// AUTOGENERATED BY go generate from msg_generate.go
@ -119,29 +114,39 @@ return off, err
continue
}
switch st.Tag(i) {
case `dns:"-"`: // ignored
case `dns:"cdomain-name"`:
switch {
case st.Tag(i) == `dns:"-"`: // ignored
case st.Tag(i) == `dns:"cdomain-name"`:
fallthrough
case `dns:"domain-name"`:
case st.Tag(i) == `dns:"domain-name"`:
o("off, err = PackDomainName(rr.%s, msg, off, compression, compress)\n")
case `dns:"a"`:
case st.Tag(i) == `dns:"a"`:
o("off, err = packDataA(rr.%s, msg, off)\n")
case `dns:"aaaa"`:
case st.Tag(i) == `dns:"aaaa"`:
o("off, err = packDataAAAA(rr.%s, msg, off)\n")
case `dns:"uint48"`:
case st.Tag(i) == `dns:"uint48"`:
o("off, err = packUint48(rr.%s, msg, off)\n")
case `dns:"txt"`:
case st.Tag(i) == `dns:"txt"`:
o("off, err = packString(rr.%s, msg, off)\n")
case `dns:"base32"`:
case strings.HasPrefix(st.Tag(i), `dns:"size-base32`): // size-base32 can be packed just like base32
fallthrough
case st.Tag(i) == `dns:"base32"`:
o("off, err = packStringBase32(rr.%s, msg, off)\n")
case `dns:"base64"`:
case strings.HasPrefix(st.Tag(i), `dns:"size-base64`): // size-base64 can be packed just like base64
fallthrough
case st.Tag(i) == `dns:"base64"`:
o("off, err = packStringBase64(rr.%s, msg, off)\n")
case `dns:"hex"`:
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex
fallthrough
case st.Tag(i) == `dns:"hex"`:
o("off, err = packStringHex(rr.%s, msg, off)\n")
case `dns:"octet"`:
case st.Tag(i) == `dns:"octet"`:
o("off, err = packStringOctet(rr.%s, msg, off)\n")
case "":
case st.Tag(i) == "":
switch st.Field(i).Type().(*types.Basic).Kind() {
case types.Uint8:
o("off, err = packUint8(rr.%s, msg, off)\n")
@ -156,8 +161,8 @@ return off, err
default:
log.Fatalln(name, st.Field(i).Name())
}
//default:
//log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
default:
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
}
}
// We have packed everything, only now we know the rdlength of this RR
@ -190,6 +195,27 @@ return rr, off, err
`)
}
// size-* are special, because they reference a struct member we should use for the length.
if strings.HasPrefix(st.Tag(i), `dns:"size-`) {
structMember := structMember(st.Tag(i))
structTag := structTag(st.Tag(i))
switch structTag {
case "hex":
fmt.Fprintf(b, "rr.%s, off, err = unpackStringHex(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember)
case "base32":
fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase32(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember)
case "base64":
fmt.Fprintf(b, "rr.%s, off, err = unpackStringBase64(msg, off, off + int(rr.%s))\n", st.Field(i).Name(), structMember)
default:
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
}
fmt.Fprint(b, `if err != nil {
return rr, off, err
}
`)
continue
}
if _, ok := st.Field(i).Type().(*types.Slice); ok {
switch st.Tag(i) {
case `dns:"-"`: // ignored
@ -244,8 +270,8 @@ return rr, off, err
default:
log.Fatalln(name, st.Field(i).Name())
}
//default:
//log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
default:
log.Fatalln(name, st.Field(i).Name(), st.Tag(i))
}
// If we've hit len(msg) we return without error.
if i < st.NumFields()-1 {
@ -281,6 +307,29 @@ return rr, off, nil
f.Write(res)
}
// structMember will take a tag like dns:"size-base32:SaltLength" and return the last part of this string.
func structMember(s string) string {
fields := strings.Split(s, ":")
if len(fields) == 0 {
return ""
}
f := fields[len(fields)-1]
// f should have a closing "
if len(f) > 1 {
return f[:len(f)-1]
}
return f
}
// structTag will take a tag like dns:"size-base32:SaltLength" and return base32.
func structTag(s string) string {
fields := strings.Split(s, ":")
if len(fields) < 2 {
return ""
}
return fields[1][len("\"size-"):]
}
func fatalIfErr(err error) {
if err != nil {
log.Fatal(err)

View File

@ -294,6 +294,27 @@ func packString(s string, msg []byte, off int) (int, error) {
return off, nil
}
func unpackStringBase32(msg []byte, off, end int) (string, int, error) {
if end > len(msg) {
return "", len(msg), &Error{err: "overflow unpacking base32"}
}
s := toBase32(msg[off:end])
return s, end, nil
}
func packStringBase32(s string, msg []byte, off int) (int, error) {
b32, err := fromBase32([]byte(s))
if err != nil {
return len(msg), err
}
if off+len(b32) > len(msg) {
return len(msg), &Error{err: "overflow packing base32"}
}
copy(msg[off:off+len(b32)], b32)
off += len(b32)
return off, nil
}
func unpackStringBase64(msg []byte, off, end int) (string, int, error) {
// Rest of the RR is base64 encoded value, so we don't need an explicit length
// to be set. Thus far all RR's that have base64 encoded fields have those as their

View File

@ -1346,38 +1346,6 @@ func TestPrintfVerbsRdata(t *testing.T) {
}
}
func TestParseIPSECKEY(t *testing.T) {
tests := []string{
"38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 1 2 192.0.2.38 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
"38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 0 2 . AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
"38.2.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.2.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 1 2 192.0.2.3 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
"38.1.0.192.in-addr.arpa. 7200 IN IPSECKEY ( 10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"38.1.0.192.in-addr.arpa.\t7200\tIN\tIPSECKEY\t10 3 2 mygateway.example.com. AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
"0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0 7200 IN IPSECKEY ( 10 2 2 2001:0DB8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ== )",
"0.d.4.0.3.0.e.f.f.f.3.f.0.1.2.0.\t7200\tIN\tIPSECKEY\t10 2 2 2001:db8:0:8002::2000:1 AQNRU3mG7TVTO2BkR47usntb102uFJtugbo6BSGvgqt4AQ==",
}
for i := 0; i < len(tests)-1; i++ {
t1 := tests[i]
e1 := tests[i+1]
r, err := NewRR(t1)
if err != nil {
t.Errorf("failed to parse IPSECKEY %v", err)
continue
}
if r.String() != e1 {
t.Errorf("these two IPSECKEY records should match:\n%s\n%s", r.String(), e1)
}
i++
}
}
func TestParseTokenOverflow(t *testing.T) {
_, err := NewRR("_443._tcp.example.org. IN TLSA 0 0 0 308205e8308204d0a00302010202100411de8f53b462f6a5a861b712ec6b59300d06092a864886f70d01010b05003070310b300906035504061302555331153013060355040a130c446967694365727420496e6331193017060355040b13107777772e64696769636572742e636f6d312f302d06035504031326446967694365727420534841322048696768204173737572616e636520536572766572204341301e170d3134313130363030303030305a170d3135313131333132303030305a3081a5310b3009060355040613025553311330110603550408130a43616c69666f726e6961311430120603550407130b4c6f7320416e67656c6573313c303a060355040a1333496e7465726e657420436f72706f726174696f6e20666f722041737369676e6564204e616d657320616e64204e756d6265727331133011060355040b130a546563686e6f6c6f6779311830160603550403130f7777772e6578616d706c652e6f726730820122300d06092a864886f70d01010105000382010f003082010a02820101009e663f52a3d18cb67cdfed547408a4e47e4036538988da2798da3b6655f7240d693ed1cb3fe6d6ad3a9e657ff6efa86b83b0cad24e5d31ff2bf70ec3b78b213f1b4bf61bdc669cbbc07d67154128ca92a9b3cbb4213a836fb823ddd4d7cc04918314d25f06086fa9970ba17e357cca9b458c27eb71760ab95e3f9bc898ae89050ae4d09ba2f7e4259d9ff1e072a6971b18355a8b9e53670c3d5dbdbd283f93a764e71b3a4140ca0746090c08510e2e21078d7d07844bf9c03865b531a0bf2ee766bc401f6451c5a1e6f6fb5d5c1d6a97a0abe91ae8b02e89241e07353909ccd5b41c46de207c06801e08f20713603827f2ae3e68cf15ef881d7e0608f70742e30203010001a382024630820242301f0603551d230418301680145168ff90af0207753cccd9656462a212b859723b301d0603551d0e04160414b000a7f422e9b1ce216117c4c46e7164c8e60c553081810603551d11047a3078820f7777772e6578616d706c652e6f7267820b6578616d706c652e636f6d820b6578616d706c652e656475820b6578616d706c652e6e6574820b6578616d706c652e6f7267820f7777772e6578616d706c652e636f6d820f7777772e6578616d706c652e656475820f7777772e6578616d706c652e6e6574300e0603551d0f0101ff0404030205a0301d0603551d250416301406082b0601050507030106082b0601050507030230750603551d1f046e306c3034a032a030862e687474703a2f2f63726c332e64696769636572742e636f6d2f736861322d68612d7365727665722d67332e63726c3034a032a030862e687474703a2f2f63726c342e64696769636572742e636f6d2f736861322d68612d7365727665722d67332e63726c30420603551d20043b3039303706096086480186fd6c0101302a302806082b06010505070201161c68747470733a2f2f7777772e64696769636572742e636f6d2f43505330818306082b0601050507010104773075302406082b060105050730018618687474703a2f2f6f6373702e64696769636572742e636f6d304d06082b060105050730028641687474703a2f2f636163657274732e64696769636572742e636f6d2f446967694365727453484132486967684173737572616e636553657276657243412e637274300c0603551d130101ff04023000300d06092a864886f70d01010b050003820101005eac2124dedb3978a86ff3608406acb542d3cb54cb83facd63aec88144d6a1bf15dbf1f215c4a73e241e582365cba9ea50dd306541653b3513af1a0756c1b2720e8d112b34fb67181efad9c4609bdc670fb025fa6e6d42188161b026cf3089a08369c2f3609fc84bcc3479140c1922ede430ca8dbac2b2a3cdacb305ba15dc7361c4c3a5e6daa99cb446cb221b28078a7a944efba70d96f31ac143d959bccd2fd50e30c325ea2624fb6b6dbe9344dbcf133bfbd5b4e892d635dbf31596451672c6b65ba5ac9b3cddea92b35dab1065cae3c8cb6bb450a62ea2f72ea7c6bdc7b65fa09b012392543734083c7687d243f8d0375304d99ccd2e148966a8637a6797")
if err == nil {

View File

@ -2045,73 +2045,6 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, ""
}
func setIPSECKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(IPSECKEY)
rr.Hdr = h
l := <-c
if l.length == 0 {
return rr, nil, l.comment
}
i, err := strconv.Atoi(l.token)
if err != nil || l.err {
return nil, &ParseError{f, "bad IPSECKEY Precedence", l}, ""
}
rr.Precedence = uint8(i)
<-c // zBlank
l = <-c
i, err = strconv.Atoi(l.token)
if err != nil || l.err {
return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
}
rr.GatewayType = uint8(i)
<-c // zBlank
l = <-c
i, err = strconv.Atoi(l.token)
if err != nil || l.err {
return nil, &ParseError{f, "bad IPSECKEY Algorithm", l}, ""
}
rr.Algorithm = uint8(i)
// Now according to GatewayType we can have different elements here
<-c // zBlank
l = <-c
switch rr.GatewayType {
case 0:
fallthrough
case 3:
rr.GatewayName = l.token
if l.token == "@" {
rr.GatewayName = o
}
_, ok := IsDomainName(l.token)
if !ok || l.length == 0 || l.err {
return nil, &ParseError{f, "bad IPSECKEY GatewayName", l}, ""
}
if rr.GatewayName[l.length-1] != '.' {
rr.GatewayName = appendOrigin(rr.GatewayName, o)
}
case 1:
rr.GatewayA = net.ParseIP(l.token)
if rr.GatewayA == nil {
return nil, &ParseError{f, "bad IPSECKEY GatewayA", l}, ""
}
case 2:
rr.GatewayAAAA = net.ParseIP(l.token)
if rr.GatewayAAAA == nil {
return nil, &ParseError{f, "bad IPSECKEY GatewayAAAA", l}, ""
}
default:
return nil, &ParseError{f, "bad IPSECKEY GatewayType", l}, ""
}
s, e, c1 := endingToString(c, "bad IPSECKEY PublicKey", f)
if e != nil {
return nil, e, c1
}
rr.PublicKey = s
return rr, nil, c1
}
func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(CAA)
rr.Hdr = h
@ -2166,7 +2099,6 @@ var typeToparserFunc = map[uint16]parserFunc{
TypeGPOS: {setGPOS, false},
TypeHINFO: {setHINFO, true},
TypeHIP: {setHIP, true},
TypeIPSECKEY: {setIPSECKEY, true},
TypeKX: {setKX, false},
TypeL32: {setL32, false},
TypeL64: {setL64, false},

View File

@ -31,11 +31,11 @@ type TSIG struct {
TimeSigned uint64 `dns:"uint48"`
Fudge uint16
MACSize uint16
MAC string `dns:"size-hex"`
MAC string `dns:"size-hex:MACSize"`
OrigId uint16
Error uint16
OtherLen uint16
OtherData string `dns:"size-hex"`
OtherData string `dns:"size-hex:OtherLen"`
}
// TSIG has no official presentation format, but this will suffice.
@ -69,14 +69,14 @@ type tsigWireFmt struct {
// MACSize, MAC and OrigId excluded
Error uint16
OtherLen uint16
OtherData string `dns:"size-hex"`
OtherData string `dns:"size-hex:OtherLen"`
}
// If we have the MAC use this type to convert it to wiredata.
// Section 3.4.3. Request MAC
type macWireFmt struct {
MACSize uint16
MAC string `dns:"size-hex"`
MAC string `dns:"size-hex:MACSize"`
}
// 3.3. Time values used in TSIG calculations

View File

@ -1,7 +1,6 @@
package dns
import (
"encoding/base64"
"fmt"
"net"
"strconv"
@ -64,7 +63,6 @@ const (
TypeOPT uint16 = 41 // EDNS
TypeDS uint16 = 43
TypeSSHFP uint16 = 44
TypeIPSECKEY uint16 = 45
TypeRRSIG uint16 = 46
TypeNSEC uint16 = 47
TypeDNSKEY uint16 = 48
@ -871,57 +869,6 @@ func (rr *SSHFP) String() string {
" " + strings.ToUpper(rr.FingerPrint)
}
type IPSECKEY struct {
Hdr RR_Header
Precedence uint8
// GatewayType: 1: A record, 2: AAAA record, 3: domainname.
// 0 is use for no type and GatewayName should be "." then.
GatewayType uint8
Algorithm uint8
// Gateway can be an A record, AAAA record or a domain name.
GatewayA net.IP `dns:"a"`
GatewayAAAA net.IP `dns:"aaaa"`
GatewayName string `dns:"domain-name"`
PublicKey string `dns:"base64"`
}
func (rr *IPSECKEY) String() string {
s := rr.Hdr.String() + strconv.Itoa(int(rr.Precedence)) +
" " + strconv.Itoa(int(rr.GatewayType)) +
" " + strconv.Itoa(int(rr.Algorithm))
switch rr.GatewayType {
case 0:
fallthrough
case 3:
s += " " + rr.GatewayName
case 1:
s += " " + rr.GatewayA.String()
case 2:
s += " " + rr.GatewayAAAA.String()
default:
s += " ."
}
s += " " + rr.PublicKey
return s
}
func (rr *IPSECKEY) len() int {
l := rr.Hdr.len() + 3 + 1
switch rr.GatewayType {
default:
fallthrough
case 0:
fallthrough
case 3:
l += len(rr.GatewayName)
case 1:
l += 4
case 2:
l += 16
}
return l + base64.StdEncoding.DecodedLen(len(rr.PublicKey))
}
type KEY struct {
DNSKEY
}
@ -973,9 +920,9 @@ type NSEC3 struct {
Flags uint8
Iterations uint16
SaltLength uint8
Salt string `dns:"size-hex"`
Salt string `dns:"size-hex:SaltLength"`
HashLength uint8
NextDomain string `dns:"size-base32"`
NextDomain string `dns:"size-base32:HashLength"`
TypeBitMap []uint16 `dns:"nsec"`
}
@ -1105,8 +1052,8 @@ type HIP struct {
HitLength uint8
PublicKeyAlgorithm uint8
PublicKeyLength uint16
Hit string `dns:"hex"`
PublicKey string `dns:"base64"`
Hit string `dns:"size-hex:HitLength"`
PublicKey string `dns:"size-base64:PublicKeyLength"`
RendezvousServers []string `dns:"domain-name"`
}

View File

@ -20,10 +20,9 @@ import (
)
var skipLen = map[string]struct{}{
"NSEC": {},
"NSEC3": {},
"OPT": {},
"IPSECKEY": {},
"NSEC": {},
"NSEC3": {},
"OPT": {},
}
var packageHdr = `
@ -104,7 +103,7 @@ func main() {
continue
}
name := strings.TrimPrefix(o.Name(), "Type")
if name == "PrivateRR" || name == "WKS" {
if name == "PrivateRR" {
continue
}
numberedTypes = append(numberedTypes, name)
@ -120,7 +119,7 @@ func main() {
if st, _ := getTypeStruct(o.Type(), scope); st == nil {
continue
}
if name == "PrivateRR" || name == "WKS" {
if name == "PrivateRR" {
continue
}
@ -172,26 +171,30 @@ func main() {
continue
}
switch st.Tag(i) {
case `dns:"-"`:
switch {
case st.Tag(i) == `dns:"-"`:
// ignored
case `dns:"cdomain-name"`, `dns:"domain-name"`:
case st.Tag(i) == `dns:"cdomain-name"`, st.Tag(i) == `dns:"domain-name"`:
o("l += len(rr.%s) + 1\n")
case `dns:"octet"`:
case st.Tag(i) == `dns:"octet"`:
o("l += len(rr.%s)\n")
case `dns:"base64"`:
case strings.HasPrefix(st.Tag(i), `dns:"size-base64`):
fallthrough
case st.Tag(i) == `dns:"base64"`:
o("l += base64.StdEncoding.DecodedLen(len(rr.%s))\n")
case `dns:"size-hex"`, `dns:"hex"`:
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`):
fallthrough
case st.Tag(i) == `dns:"hex"`:
o("l += len(rr.%s)/2 + 1\n")
case `dns:"a"`:
case st.Tag(i) == `dns:"a"`:
o("l += net.IPv4len // %s\n")
case `dns:"aaaa"`:
case st.Tag(i) == `dns:"aaaa"`:
o("l += net.IPv6len // %s\n")
case `dns:"txt"`:
case st.Tag(i) == `dns:"txt"`:
o("for _, t := range rr.%s { l += len(t) + 1 }\n")
case `dns:"uint48"`:
case st.Tag(i) == `dns:"uint48"`:
o("l += 6 // %s\n")
case "":
case st.Tag(i) == "":
switch st.Field(i).Type().(*types.Basic).Kind() {
case types.Uint8:
o("l += 1 // %s\n")

144
zmsg.go
View File

@ -411,44 +411,6 @@ func (rr *HIP) pack(msg []byte, off int, compression map[string]int, compress bo
return off, nil
}
func (rr *IPSECKEY) 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 = packUint8(rr.Precedence, msg, off)
if err != nil {
return off, err
}
off, err = packUint8(rr.GatewayType, msg, off)
if err != nil {
return off, err
}
off, err = packUint8(rr.Algorithm, msg, off)
if err != nil {
return off, err
}
off, err = packDataA(rr.GatewayA, msg, off)
if err != nil {
return off, err
}
off, err = packDataAAAA(rr.GatewayAAAA, msg, off)
if err != nil {
return off, err
}
off, err = PackDomainName(rr.GatewayName, msg, off, compression, compress)
if err != nil {
return off, err
}
off, err = packStringBase64(rr.PublicKey, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *KEY) 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 {
@ -839,10 +801,18 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
off, err = packStringHex(rr.Salt, msg, off)
if err != nil {
return off, err
}
off, err = packUint8(rr.HashLength, msg, off)
if err != nil {
return off, err
}
off, err = packStringBase32(rr.NextDomain, msg, off)
if err != nil {
return off, err
}
off, err = packDataNsec(rr.TypeBitMap, msg, off)
if err != nil {
return off, err
@ -1351,6 +1321,10 @@ func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
off, err = packStringHex(rr.MAC, msg, off)
if err != nil {
return off, err
}
off, err = packUint16(rr.OrigId, msg, off)
if err != nil {
return off, err
@ -1363,6 +1337,10 @@ func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress b
if err != nil {
return off, err
}
off, err = packStringHex(rr.OtherData, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
@ -2003,20 +1981,14 @@ func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) {
if off == len(msg) {
return rr, off, nil
}
rr.Hit, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength))
rr.Hit, off, err = unpackStringHex(msg, off, off+int(rr.HitLength))
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
rr.PublicKey, off, err = unpackStringBase64(msg, off, off+int(rr.PublicKeyLength))
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.RendezvousServers, off, err = unpackDataDomainNames(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
@ -2024,66 +1996,6 @@ func unpackHIP(h RR_Header, msg []byte, off int) (RR, int, error) {
return rr, off, err
}
func unpackIPSECKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
if noRdata(h) {
return &h, off, nil
}
var err error
rdStart := off
_ = rdStart
rr := new(IPSECKEY)
rr.Hdr = h
rr.Precedence, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.GatewayType, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.Algorithm, off, err = unpackUint8(msg, off)
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.GatewayA, off, err = unpackDataA(msg, off)
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.GatewayAAAA, off, err = unpackDataAAAA(msg, off)
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.GatewayName, off, err = UnpackDomainName(msg, off)
if err != nil {
return rr, off, err
}
if off == len(msg) {
return rr, off, nil
}
rr.PublicKey, off, err = unpackStringBase64(msg, off, rdStart+int(rr.Hdr.Rdlength))
if err != nil {
return rr, off, err
}
return rr, off, err
}
func unpackKEY(h RR_Header, msg []byte, off int) (RR, int, error) {
if noRdata(h) {
return &h, off, nil
@ -2637,8 +2549,9 @@ func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) {
if off == len(msg) {
return rr, off, nil
}
if off == len(msg) {
return rr, off, nil
rr.Salt, off, err = unpackStringHex(msg, off, off+int(rr.SaltLength))
if err != nil {
return rr, off, err
}
rr.HashLength, off, err = unpackUint8(msg, off)
if err != nil {
@ -2647,8 +2560,9 @@ func unpackNSEC3(h RR_Header, msg []byte, off int) (RR, int, error) {
if off == len(msg) {
return rr, off, nil
}
if off == len(msg) {
return rr, off, nil
rr.NextDomain, off, err = unpackStringBase32(msg, off, off+int(rr.HashLength))
if err != nil {
return rr, off, err
}
rr.TypeBitMap, off, err = unpackDataNsec(msg, off)
if err != nil {
@ -3409,8 +3323,9 @@ func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
if off == len(msg) {
return rr, off, nil
}
if off == len(msg) {
return rr, off, nil
rr.MAC, off, err = unpackStringHex(msg, off, off+int(rr.MACSize))
if err != nil {
return rr, off, err
}
rr.OrigId, off, err = unpackUint16(msg, off)
if err != nil {
@ -3433,6 +3348,10 @@ func unpackTSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
if off == len(msg) {
return rr, off, nil
}
rr.OtherData, off, err = unpackStringHex(msg, off, off+int(rr.OtherLen))
if err != nil {
return rr, off, err
}
return rr, off, err
}
@ -3562,7 +3481,6 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
TypeGPOS: unpackGPOS,
TypeHINFO: unpackHINFO,
TypeHIP: unpackHIP,
TypeIPSECKEY: unpackIPSECKEY,
TypeKEY: unpackKEY,
TypeKX: unpackKX,
TypeL32: unpackL32,

View File

@ -31,7 +31,6 @@ var TypeToRR = map[uint16]func() RR{
TypeGPOS: func() RR { return new(GPOS) },
TypeHINFO: func() RR { return new(HINFO) },
TypeHIP: func() RR { return new(HIP) },
TypeIPSECKEY: func() RR { return new(IPSECKEY) },
TypeKEY: func() RR { return new(KEY) },
TypeKX: func() RR { return new(KX) },
TypeL32: func() RR { return new(L32) },
@ -104,7 +103,6 @@ var TypeToString = map[uint16]string{
TypeGPOS: "GPOS",
TypeHINFO: "HINFO",
TypeHIP: "HIP",
TypeIPSECKEY: "IPSECKEY",
TypeISDN: "ISDN",
TypeIXFR: "IXFR",
TypeKEY: "KEY",
@ -183,7 +181,6 @@ func (rr *GID) Header() *RR_Header { return &rr.Hdr }
func (rr *GPOS) Header() *RR_Header { return &rr.Hdr }
func (rr *HINFO) Header() *RR_Header { return &rr.Hdr }
func (rr *HIP) Header() *RR_Header { return &rr.Hdr }
func (rr *IPSECKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *KEY) Header() *RR_Header { return &rr.Hdr }
func (rr *KX) Header() *RR_Header { return &rr.Hdr }
func (rr *L32) Header() *RR_Header { return &rr.Hdr }
@ -685,9 +682,6 @@ func (rr *HIP) copy() RR {
copy(RendezvousServers, rr.RendezvousServers)
return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
}
func (rr *IPSECKEY) copy() RR {
return &IPSECKEY{*rr.Hdr.copyHeader(), rr.Precedence, rr.GatewayType, rr.Algorithm, copyIP(rr.GatewayA), copyIP(rr.GatewayAAAA), rr.GatewayName, rr.PublicKey}
}
func (rr *KX) copy() RR {
return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger}
}