Allow for escaping of dots in domainnames

This commit is contained in:
Miek Gieben 2011-02-21 20:33:36 +01:00
parent 865ba16420
commit c7c4d8061e
2 changed files with 110 additions and 80 deletions

23
msg.go
View File

@ -147,6 +147,7 @@ func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
// Each dot ends a segment of the name.
// We trade each dot byte for a length byte.
// Except for escaped dots (\.), which are normal dots.
// There is also a trailing zero.
// Check that we have all the space we need.
tot := len(s) + 1
@ -156,22 +157,32 @@ func packDomainName(s string, msg []byte, off int) (off1 int, ok bool) {
// Emit sequence of counted strings, chopping at dots.
begin := 0
for i := 0; i < len(s); i++ {
if s[i] == '.' {
bs := []byte(s)
ls := len(bs)
for i := 0; i < ls; i++ {
if bs[i] == '\\' {
for j := i; j < len(s)-1; j++ {
bs[j] = bs[j+1]
}
ls--
continue
}
if bs[i] == '.' {
if i-begin >= 1<<6 { // top two bits of length must be clear
return len(msg), false
}
msg[off] = byte(i - begin)
off++
for j := begin; j < i; j++ {
msg[off] = s[j]
msg[off] = bs[j]
off++
}
begin = i + 1
}
}
// Root label is special
if s == "." {
if string(bs) == "." {
return off, true
}
msg[off] = 0
@ -399,7 +410,7 @@ func packStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int, o
return len(msg), false
}
case "size-hex":
fallthrough;
fallthrough
case "hex":
// There is no length encoded here
h, e := hex.DecodeString(s)
@ -605,7 +616,7 @@ func unpackStructValue(val *reflect.StructValue, msg []byte, off int) (off1 int,
case "RR_NSEC3PARAM":
consumed = 5 // Hash(1) + Flags(1) + Iterations(2) + SaltLength(1)
case "RR_RFC3597":
fallthrough; // Rest is the unknown data
fallthrough // Rest is the unknown data
default:
consumed = 0 // return len(msg), false?
}

View File

@ -134,5 +134,24 @@ func TestQuadA(t *testing.T) {
t.Log(str)
t.Fail()
}
}
func TestDotInName(t *testing.T) {
buf := make([]byte, 20)
packDomainName("aa\\.bb.nl", buf, 0)
// index 3 must be a real dot
if buf[3] != '.' {
t.Log("Dot should be a real dot")
t.Fail()
}
if buf[6] != 2 {
t.Log("This must have the value 2")
t.Fail()
}
dom, _, ok := unpackDomainName(buf, 0)
// printing it should yield the backspace again
println(dom)
println(ok)
}