Merge pull request #843 from tmthrgd/hashname

Reduce memory consumption in HashName
This commit is contained in:
Miek Gieben 2018-11-29 07:19:50 +00:00 committed by GitHub
commit ed726faad6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 28 deletions

View File

@ -2,49 +2,44 @@ package dns
import (
"crypto/sha1"
"hash"
"encoding/hex"
"strings"
)
type saltWireFmt struct {
Salt string `dns:"size-hex"`
}
// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
func HashName(label string, ha uint8, iter uint16, salt string) string {
saltwire := new(saltWireFmt)
saltwire.Salt = salt
wire := make([]byte, DefaultMsgSize)
n, err := packSaltWire(saltwire, wire)
if ha != SHA1 {
return ""
}
wireSalt := make([]byte, hex.DecodedLen(len(salt)))
n, err := packStringHex(salt, wireSalt, 0)
if err != nil {
return ""
}
wire = wire[:n]
wireSalt = wireSalt[:n]
name := make([]byte, 255)
off, err := PackDomainName(strings.ToLower(label), name, 0, nil, false)
if err != nil {
return ""
}
name = name[:off]
var s hash.Hash
switch ha {
case SHA1:
s = sha1.New()
default:
return ""
}
s := sha1.New()
// k = 0
s.Write(name)
s.Write(wire)
s.Write(wireSalt)
nsec3 := s.Sum(nil)
// k > 0
for k := uint16(0); k < iter; k++ {
s.Reset()
s.Write(nsec3)
s.Write(wire)
s.Write(wireSalt)
nsec3 = s.Sum(nsec3[:0])
}
return toBase32(nsec3)
}
@ -98,11 +93,3 @@ func (rr *NSEC3) Match(name string) bool {
}
return false
}
func packSaltWire(sw *saltWireFmt, msg []byte) (int, error) {
off, err := packStringHex(sw.Salt, msg, 0)
if err != nil {
return off, err
}
return off, nil
}

View File

@ -1,6 +1,9 @@
package dns
import "testing"
import (
"strconv"
"testing"
)
func TestPackNsec3(t *testing.T) {
nsec3 := HashName("dnsex.nl.", SHA1, 0, "DEAD")
@ -151,3 +154,17 @@ func TestNsec3EmptySalt(t *testing.T) {
t.Fatalf("expected record to match com. label")
}
}
func BenchmarkHashName(b *testing.B) {
for _, iter := range []uint16{
150, 2500, 5000, 10000, ^uint16(0),
} {
b.Run(strconv.Itoa(int(iter)), func(b *testing.B) {
for n := 0; n < b.N; n++ {
if HashName("some.example.org.", SHA1, iter, "deadbeef") == "" {
b.Fatalf("HashName failed")
}
}
})
}
}