RawRdlength seems to work;

This commit is contained in:
Miek Gieben 2012-01-12 21:10:29 +01:00
parent 4a5a144c53
commit 7ddb5feb69
2 changed files with 57 additions and 20 deletions

9
msg.go
View File

@ -880,7 +880,7 @@ func packRR(rr RR, msg []byte, off int, compression map[string]int, compress boo
if !ok { if !ok {
return len(msg), false return len(msg), false
} }
RawSetRdLength(msg, off, off1) RawSetRdlength(msg, off, off1)
return off1, true return off1, true
} }
@ -892,7 +892,14 @@ func unpackRR(msg []byte, off int) (rr RR, off1 int, ok bool) {
if off, ok = unpackStruct(&h, msg, off); !ok { if off, ok = unpackStruct(&h, msg, off); !ok {
return nil, len(msg), false return nil, len(msg), false
} }
rrtype, rdlength, off4 := RawTypeRdlength(msg, off0)
if rrtype == 0 {
return nil, len(msg), false
}
end := off + int(h.Rdlength) end := off + int(h.Rdlength)
println(h.Rdlength, "me l", rdlength)
println(h.Rrtype, "me t", rrtype)
println(end, "me tl", off4+int(rdlength))
// make an rr of that type and re-unpack. // make an rr of that type and re-unpack.
// again inefficient but doesn't need to be fast. TODO speed // again inefficient but doesn't need to be fast. TODO speed

View File

@ -14,13 +14,12 @@ func RawSetId(msg []byte, off int, id uint16) bool {
return true return true
} }
// RawSetRdLength sets the rdlength in the header of // RawSetRdlength sets the rdlength in the header of
// the RR. The offset 'off' must be positioned at the // the RR. The offset 'off' must be positioned at the
// start of the header of the RR. // start of the header of the RR, 'end' must be the
func RawSetRdLength(msg []byte, off, end int) bool { // end of the RR.
// We are at the start of the header, walk the func RawSetRdlength(msg []byte, off, end int) bool {
// domainname (might be compressed), and set the // We are at the start of the header, walk the domainname (might be compressed)
// length
Loop: Loop:
for { for {
if off > len(msg) { if off > len(msg) {
@ -35,21 +34,52 @@ Loop:
break Loop break Loop
} }
case 0xC0:
// pointer, next byte included, ends domainname
off++
break Loop
}
}
// The domainname has been seen, we at the start of the fixed part in the header.
// Type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length.
off += 2 + 2 + 4
if off+1 > len(msg) {
return false
}
//off+1 is the end of the header, 'end' is the end of the rr
//so 'end' - 'off+2' is the lenght of the rdata
msg[off], msg[off+1] = packUint16(uint16(end - (off + 2)))
return true
}
// RawSetRdlength return the type and length as found
// in the RR header.
func RawTypeRdlength(msg []byte, off int) (uint16, uint16, int) {
Loop:
for {
if off > len(msg) {
return 0, 0, off
}
c := int(msg[off])
off++
switch c & 0xC00 {
case 0x00:
if c == 0x00 {
// End of the domainname
break Loop
}
case 0xC0: case 0xC0:
// pointer, next byte included, ends domainnames // pointer, next byte included, ends domainnames
off++ off++
break Loop break Loop
} }
} }
// The domainname has been seen, we at the start off--
// of the fixed part in the header if off+8 > len(msg) {
// type is 2 bytes, class is 2 bytes, ttl 4 and then 2 bytes for the length return 0, 0, off
off += 2 + 2 + 4
if off+1 > len(msg) {
return false
} }
//off+1 is the end of the header, 'end' is the end of the rr t, off := unpackUint16(msg, off) // type
//so 'end' - 'off+2' is the lenght of the rdata l, off := unpackUint16(msg, off+6) // length
msg[off], msg[off+1] = packUint16(uint16(end - (off+2))) return t, l, off
return true
} }