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:
parent
6ae3b9f061
commit
dbffa4b057
@ -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
|
||||
|
25
dns_test.go
25
dns_test.go
@ -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
37
msg.go
@ -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,
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
68
scan_rr.go
68
scan_rr.go
@ -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},
|
||||
|
8
tsig.go
8
tsig.go
@ -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
|
||||
|
61
types.go
61
types.go
@ -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"`
|
||||
}
|
||||
|
||||
|
@ -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
144
zmsg.go
@ -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,
|
||||
|
@ -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}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user