diff --git a/README.md b/README.md index 9dd414a1..83b4183e 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/dns_test.go b/dns_test.go index 34007aa8..438e71ca 100644 --- a/dns_test.go +++ b/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 diff --git a/msg.go b/msg.go index b560d26e..e4d390ec 100644 --- a/msg.go +++ b/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, -} diff --git a/msg_generate.go b/msg_generate.go index 6e63b704..3179ad94 100644 --- a/msg_generate.go +++ b/msg_generate.go @@ -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) diff --git a/msg_helpers.go b/msg_helpers.go index 00c6255a..e7a9500c 100644 --- a/msg_helpers.go +++ b/msg_helpers.go @@ -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 diff --git a/parse_test.go b/parse_test.go index a700f644..4e5b5676 100644 --- a/parse_test.go +++ b/parse_test.go @@ -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 { diff --git a/scan_rr.go b/scan_rr.go index 8092e0ee..e521dc06 100644 --- a/scan_rr.go +++ b/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}, diff --git a/tsig.go b/tsig.go index b07aab4c..4698e449 100644 --- a/tsig.go +++ b/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 diff --git a/types.go b/types.go index 49380628..e7370647 100644 --- a/types.go +++ b/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"` } diff --git a/types_generate.go b/types_generate.go index 35428533..bf80da32 100644 --- a/types_generate.go +++ b/types_generate.go @@ -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") diff --git a/zmsg.go b/zmsg.go index 115c34ca..239bed52 100644 --- a/zmsg.go +++ b/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, diff --git a/ztypes.go b/ztypes.go index a9b4beef..a4ecbb0c 100644 --- a/ztypes.go +++ b/ztypes.go @@ -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} }