Fixes for the new presentation of txt records
This commit is contained in:
parent
2f64868d3c
commit
2c44133163
2
edns.go
2
edns.go
|
@ -42,7 +42,7 @@ type Option struct {
|
||||||
// m.Extra[0] = opt // add OPT RR to the message
|
// m.Extra[0] = opt // add OPT RR to the message
|
||||||
type RR_OPT struct {
|
type RR_OPT struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Option []Option "OPT" // tag is used in Pack and Unpack
|
Option []Option "opt" // tag is used in Pack and Unpack
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_OPT) Header() *RR_Header {
|
func (rr *RR_OPT) Header() *RR_Header {
|
||||||
|
|
|
@ -64,7 +64,7 @@ func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
|
||||||
|
|
||||||
t := new(dns.RR_TXT)
|
t := new(dns.RR_TXT)
|
||||||
t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
|
t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
|
||||||
t.Txt = str
|
t.Txt = []string{str}
|
||||||
|
|
||||||
switch r.Question[0].Qtype {
|
switch r.Question[0].Qtype {
|
||||||
case dns.TypeTXT:
|
case dns.TypeTXT:
|
||||||
|
|
78
msg.go
78
msg.go
|
@ -367,8 +367,24 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
switch val.Type().Field(i).Tag {
|
switch val.Type().Field(i).Tag {
|
||||||
default:
|
default:
|
||||||
|
println("dns: unknown tag packing slice", val.Type().Field(i).Tag)
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
case "OPT": // edns
|
case "txt":
|
||||||
|
for j := 0; j < val.Field(i).Len(); j++ {
|
||||||
|
element := val.Field(i).Index(j).String()
|
||||||
|
// Counted string: 1 byte length.
|
||||||
|
if len(element) > 255 || off+1+len(element) > lenmsg {
|
||||||
|
println("dns: overflow packing TXT string")
|
||||||
|
return len(msg), false
|
||||||
|
}
|
||||||
|
msg[off] = byte(len(element))
|
||||||
|
off++
|
||||||
|
for i := 0; i < len(element); i++ {
|
||||||
|
msg[off+i] = element[i]
|
||||||
|
}
|
||||||
|
off += len(element)
|
||||||
|
}
|
||||||
|
case "opt": // edns
|
||||||
// Length of the entire option section
|
// Length of the entire option section
|
||||||
for j := 0; j < val.Field(i).Len(); j++ {
|
for j := 0; j < val.Field(i).Len(); j++ {
|
||||||
element := val.Field(i).Index(j)
|
element := val.Field(i).Index(j)
|
||||||
|
@ -387,7 +403,7 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
copy(msg[off:off+len(string(h))], h)
|
copy(msg[off:off+len(string(h))], h)
|
||||||
off += len(string(h))
|
off += len(string(h))
|
||||||
}
|
}
|
||||||
case "A":
|
case "a":
|
||||||
// It must be a slice of 4, even if it is 16, we encode
|
// It must be a slice of 4, even if it is 16, we encode
|
||||||
// only the first 4
|
// only the first 4
|
||||||
switch fv.Len() {
|
switch fv.Len() {
|
||||||
|
@ -417,7 +433,7 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
println("dns: overflow packing A")
|
println("dns: overflow packing A")
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
case "AAAA":
|
case "aaaa":
|
||||||
if fv.Len() > net.IPv6len || off+fv.Len() > lenmsg {
|
if fv.Len() > net.IPv6len || off+fv.Len() > lenmsg {
|
||||||
println("dns: overflow packing AAAA")
|
println("dns: overflow packing AAAA")
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
|
@ -426,7 +442,7 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
msg[off] = byte(fv.Index(j).Uint())
|
msg[off] = byte(fv.Index(j).Uint())
|
||||||
off++
|
off++
|
||||||
}
|
}
|
||||||
case "NSEC": // NSEC/NSEC3
|
case "nsec": // NSEC/NSEC3
|
||||||
// This is the uint16 type bitmap
|
// This is the uint16 type bitmap
|
||||||
if val.Field(i).Len() == 0 {
|
if val.Field(i).Len() == 0 {
|
||||||
// Do absolutely nothing
|
// Do absolutely nothing
|
||||||
|
@ -577,8 +593,6 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
||||||
copy(msg[off:off+len(s)], s)
|
copy(msg[off:off+len(s)], s)
|
||||||
off += len(s)
|
off += len(s)
|
||||||
case "txt":
|
case "txt":
|
||||||
// Counted string: 1 byte length, but the string may be longer
|
|
||||||
// than 255, in that case it should be multiple strings, for now:
|
|
||||||
fallthrough
|
fallthrough
|
||||||
case "":
|
case "":
|
||||||
// Counted string: 1 byte length.
|
// Counted string: 1 byte length.
|
||||||
|
@ -625,25 +639,25 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
switch val.Type().Field(i).Tag {
|
switch val.Type().Field(i).Tag {
|
||||||
default:
|
default:
|
||||||
println("dns: unknown tag unpacking struct")
|
println("dns: unknown tag unpacking slice", val.Type().Field(i).Tag)
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
case "A":
|
case "txt":
|
||||||
if off+net.IPv4len > len(msg) {
|
txt := make([]string,0)
|
||||||
println("dns: overflow unpacking A")
|
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
||||||
|
Txts:
|
||||||
|
l := int(msg[off])
|
||||||
|
if off + l + 1 > lenmsg {
|
||||||
|
println("dns: failure unpacking txt strings")
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
fv.Set(reflect.ValueOf(net.IPv4(msg[off], msg[off+1], msg[off+2], msg[off+3])))
|
txt = append(txt, string(msg[off+1:off+l]))
|
||||||
off += net.IPv4len
|
off += l
|
||||||
case "AAAA":
|
if off < rdlength {
|
||||||
if off+net.IPv6len > lenmsg {
|
// More
|
||||||
println("dns: overflow unpacking AAAA")
|
goto Txts
|
||||||
return lenmsg, false
|
|
||||||
}
|
}
|
||||||
fv.Set(reflect.ValueOf(net.IP{msg[off], msg[off+1], msg[off+2], msg[off+3], msg[off+4],
|
fv.Set(reflect.ValueOf(txt))
|
||||||
msg[off+5], msg[off+6], msg[off+7], msg[off+8], msg[off+9], msg[off+10],
|
case "opt": // EDNS
|
||||||
msg[off+11], msg[off+12], msg[off+13], msg[off+14], msg[off+15]}))
|
|
||||||
off += net.IPv6len
|
|
||||||
case "OPT": // EDNS
|
|
||||||
if off+2 > lenmsg {
|
if off+2 > lenmsg {
|
||||||
// This is an ENDNS0 (OPT Record) with no rdata
|
// This is an ENDNS0 (OPT Record) with no rdata
|
||||||
// We can savely return here.
|
// We can savely return here.
|
||||||
|
@ -659,7 +673,23 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
||||||
opt[0].Data = hex.EncodeToString(msg[off1 : off1+int(optlen)])
|
opt[0].Data = hex.EncodeToString(msg[off1 : off1+int(optlen)])
|
||||||
fv.Set(reflect.ValueOf(opt))
|
fv.Set(reflect.ValueOf(opt))
|
||||||
off = off1 + int(optlen)
|
off = off1 + int(optlen)
|
||||||
case "NSEC": // NSEC/NSEC3
|
case "a":
|
||||||
|
if off+net.IPv4len > len(msg) {
|
||||||
|
println("dns: overflow unpacking A")
|
||||||
|
return lenmsg, false
|
||||||
|
}
|
||||||
|
fv.Set(reflect.ValueOf(net.IPv4(msg[off], msg[off+1], msg[off+2], msg[off+3])))
|
||||||
|
off += net.IPv4len
|
||||||
|
case "aaaa":
|
||||||
|
if off+net.IPv6len > lenmsg {
|
||||||
|
println("dns: overflow unpacking AAAA")
|
||||||
|
return lenmsg, false
|
||||||
|
}
|
||||||
|
fv.Set(reflect.ValueOf(net.IP{msg[off], msg[off+1], msg[off+2], msg[off+3], msg[off+4],
|
||||||
|
msg[off+5], msg[off+6], msg[off+7], msg[off+8], msg[off+9], msg[off+10],
|
||||||
|
msg[off+11], msg[off+12], msg[off+13], msg[off+14], msg[off+15]}))
|
||||||
|
off += net.IPv6len
|
||||||
|
case "nsec": // NSEC/NSEC3
|
||||||
// Rest of the Record is the type bitmap
|
// Rest of the Record is the type bitmap
|
||||||
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
||||||
var endrr int
|
var endrr int
|
||||||
|
@ -868,7 +898,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
||||||
s = hex.EncodeToString(msg[off : off+size])
|
s = hex.EncodeToString(msg[off : off+size])
|
||||||
off += size
|
off += size
|
||||||
case "txt":
|
case "txt":
|
||||||
// 1 or multiple txt pieces
|
// 1 txt piece
|
||||||
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
||||||
Txt:
|
Txt:
|
||||||
if off >= lenmsg || off+1+int(msg[off]) > lenmsg {
|
if off >= lenmsg || off+1+int(msg[off]) > lenmsg {
|
||||||
|
@ -882,7 +912,7 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
||||||
}
|
}
|
||||||
off += n
|
off += n
|
||||||
if off < rdlength {
|
if off < rdlength {
|
||||||
// More to come
|
// More to
|
||||||
goto Txt
|
goto Txt
|
||||||
}
|
}
|
||||||
case "":
|
case "":
|
||||||
|
|
8
types.go
8
types.go
|
@ -491,7 +491,7 @@ func (rr *RR_DNAME) Len() int {
|
||||||
|
|
||||||
type RR_A struct {
|
type RR_A struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
A net.IP "A"
|
A net.IP "a"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_A) Header() *RR_Header {
|
func (rr *RR_A) Header() *RR_Header {
|
||||||
|
@ -508,7 +508,7 @@ func (rr *RR_A) Len() int {
|
||||||
|
|
||||||
type RR_AAAA struct {
|
type RR_AAAA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
AAAA net.IP "AAAA"
|
AAAA net.IP "aaaa"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_AAAA) Header() *RR_Header {
|
func (rr *RR_AAAA) Header() *RR_Header {
|
||||||
|
@ -584,7 +584,7 @@ func (rr *RR_RRSIG) Len() int {
|
||||||
type RR_NSEC struct {
|
type RR_NSEC struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
NextDomain string "domain-name"
|
NextDomain string "domain-name"
|
||||||
TypeBitMap []uint16 "NSEC"
|
TypeBitMap []uint16 "nsec"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_NSEC) Header() *RR_Header {
|
func (rr *RR_NSEC) Header() *RR_Header {
|
||||||
|
@ -769,7 +769,7 @@ type RR_NSEC3 struct {
|
||||||
Salt string "size-hex"
|
Salt string "size-hex"
|
||||||
HashLength uint8
|
HashLength uint8
|
||||||
NextDomain string "size-base32"
|
NextDomain string "size-base32"
|
||||||
TypeBitMap []uint16 "NSEC"
|
TypeBitMap []uint16 "nsec"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_NSEC3) Header() *RR_Header {
|
func (rr *RR_NSEC3) Header() *RR_Header {
|
||||||
|
|
Loading…
Reference in New Issue