mirror of
https://github.com/miekg/dns.git
synced 2025-12-16 17:21:17 +01:00
Implement compressible domain names
This commit is contained in:
parent
974c28d1b1
commit
b5d73f1eff
2
dns.go
2
dns.go
@ -173,7 +173,7 @@ type Exchange struct {
|
|||||||
// There are many types of messages,
|
// There are many types of messages,
|
||||||
// but they all share the same header.
|
// but they all share the same header.
|
||||||
type RR_Header struct {
|
type RR_Header struct {
|
||||||
Name string "domain-name"
|
Name string "cdomain-name"
|
||||||
Rrtype uint16
|
Rrtype uint16
|
||||||
Class uint16
|
Class uint16
|
||||||
Ttl uint32
|
Ttl uint32
|
||||||
|
|||||||
52
msg.go
52
msg.go
@ -26,7 +26,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const MaxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
|
const MaxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrUnpack error = &Error{Err: "unpacking failed"}
|
ErrUnpack error = &Error{Err: "unpacking failed"}
|
||||||
@ -214,21 +214,21 @@ func PackDomainName(s string, msg []byte, off int, compression map[string]int) (
|
|||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
msg[off] = byte(i - begin)
|
msg[off] = byte(i - begin)
|
||||||
offset := off
|
offset := off
|
||||||
off++
|
off++
|
||||||
for j := begin; j < i; j++ {
|
for j := begin; j < i; j++ {
|
||||||
msg[off] = bs[j]
|
msg[off] = bs[j]
|
||||||
off++
|
off++
|
||||||
}
|
}
|
||||||
str, _, ok := UnpackDomainName(msg, offset)
|
str, _, ok := UnpackDomainName(msg, offset)
|
||||||
if !ok {
|
if !ok {
|
||||||
// hmmm how can this be?
|
// hmmm how can this be?
|
||||||
}
|
}
|
||||||
if compression != nil {
|
if compression != nil {
|
||||||
if _, ok := compression[str]; !ok {
|
if _, ok := compression[str]; !ok {
|
||||||
compression[str] = offset
|
compression[str] = offset
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
begin = i + 1
|
begin = i + 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -462,7 +462,13 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
|||||||
copy(msg[off:off+len(b64)], b64)
|
copy(msg[off:off+len(b64)], b64)
|
||||||
off += len(b64)
|
off += len(b64)
|
||||||
case "domain-name":
|
case "domain-name":
|
||||||
off, ok = PackDomainName(s, msg, off, compression)
|
fallthrough // No compression
|
||||||
|
case "cdomain-name":
|
||||||
|
if val.Type().Field(i).Tag == "cdomain-name" {
|
||||||
|
off, ok = PackDomainName(s, msg, off, compression)
|
||||||
|
} else {
|
||||||
|
off, ok = PackDomainName(s, msg, off, nil)
|
||||||
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
//fmt.Fprintf(os.Stderr, "dns: overflow packing domain-name")
|
//fmt.Fprintf(os.Stderr, "dns: overflow packing domain-name")
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
@ -476,10 +482,10 @@ func packStructValue(val reflect.Value, msg []byte, off int, compression map[str
|
|||||||
//fmt.Fprintf(os.Stderr, "dns: overflow packing (size-)hex string")
|
//fmt.Fprintf(os.Stderr, "dns: overflow packing (size-)hex string")
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
if off+hex.DecodedLen(len(s)) > lenmsg {
|
if off+hex.DecodedLen(len(s)) > lenmsg {
|
||||||
// Overflow
|
// Overflow
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
copy(msg[off:off+hex.DecodedLen(len(s))], h)
|
copy(msg[off:off+hex.DecodedLen(len(s))], h)
|
||||||
off += hex.DecodedLen(len(s))
|
off += hex.DecodedLen(len(s))
|
||||||
case "size":
|
case "size":
|
||||||
@ -664,10 +670,10 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo
|
|||||||
case "hex":
|
case "hex":
|
||||||
// Rest of the RR is hex encoded, network order an issue here?
|
// Rest of the RR is hex encoded, network order an issue here?
|
||||||
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint())
|
||||||
if off+rdlength > lenmsg {
|
if off+rdlength > lenmsg {
|
||||||
// too large
|
// too large
|
||||||
return lenmsg, false
|
return lenmsg, false
|
||||||
}
|
}
|
||||||
var consumed int
|
var consumed int
|
||||||
switch val.Type().Name() {
|
switch val.Type().Name() {
|
||||||
case "RR_DS":
|
case "RR_DS":
|
||||||
@ -956,7 +962,7 @@ func (h *MsgHdr) String() string {
|
|||||||
// Pack a msg: convert it to wire format.
|
// Pack a msg: convert it to wire format.
|
||||||
func (dns *Msg) Pack() (msg []byte, ok bool) {
|
func (dns *Msg) Pack() (msg []byte, ok bool) {
|
||||||
var dh Header
|
var dh Header
|
||||||
compression := make(map[string]int) // Compression pointer mappings
|
compression := make(map[string]int) // Compression pointer mappings
|
||||||
|
|
||||||
// Convert convenient Msg into wire-like Header.
|
// Convert convenient Msg into wire-like Header.
|
||||||
dh.Id = dns.Id
|
dh.Id = dns.Id
|
||||||
@ -997,7 +1003,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
|
|||||||
dh.Nscount = uint16(len(ns))
|
dh.Nscount = uint16(len(ns))
|
||||||
dh.Arcount = uint16(len(extra))
|
dh.Arcount = uint16(len(extra))
|
||||||
|
|
||||||
// TODO: still too much, but better than 64K
|
// TODO: still too much, but better than 64K
|
||||||
msg = make([]byte, dns.Len()*6)
|
msg = make([]byte, dns.Len()*6)
|
||||||
|
|
||||||
// Pack it in: header and then the pieces.
|
// Pack it in: header and then the pieces.
|
||||||
@ -1022,7 +1028,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
fmt.Printf("**%v\n", compression)
|
fmt.Printf("**%v\n", compression)
|
||||||
return msg[:off], true
|
return msg[:off], true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Function defined in this subpackage work on []byte and but still
|
// Function defined in this subpackage work on []byte and but still
|
||||||
// provide some higher level functions.
|
// provide some higher level functions.
|
||||||
|
|
||||||
|
|||||||
24
types.go
24
types.go
@ -129,7 +129,7 @@ const (
|
|||||||
|
|
||||||
// DNS queries.
|
// DNS queries.
|
||||||
type Question struct {
|
type Question struct {
|
||||||
Name string "domain-name" // "domain-name" specifies encoding
|
Name string "cdomain-name" // "cdomain-name" specifies encoding (and may be compressed)
|
||||||
Qtype uint16
|
Qtype uint16
|
||||||
Qclass uint16
|
Qclass uint16
|
||||||
}
|
}
|
||||||
@ -174,7 +174,7 @@ func (rr *RR_ANY) Len() int {
|
|||||||
|
|
||||||
type RR_CNAME struct {
|
type RR_CNAME struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Cname string "domain-name"
|
Cname string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_CNAME) Header() *RR_Header {
|
func (rr *RR_CNAME) Header() *RR_Header {
|
||||||
@ -210,7 +210,7 @@ func (rr *RR_HINFO) Len() int {
|
|||||||
|
|
||||||
type RR_MB struct {
|
type RR_MB struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mb string "domain-name"
|
Mb string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_MB) Header() *RR_Header {
|
func (rr *RR_MB) Header() *RR_Header {
|
||||||
@ -228,7 +228,7 @@ func (rr *RR_MB) Len() int {
|
|||||||
|
|
||||||
type RR_MG struct {
|
type RR_MG struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mg string "domain-name"
|
Mg string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_MG) Header() *RR_Header {
|
func (rr *RR_MG) Header() *RR_Header {
|
||||||
@ -246,8 +246,8 @@ func (rr *RR_MG) Len() int {
|
|||||||
|
|
||||||
type RR_MINFO struct {
|
type RR_MINFO struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Rmail string "domain-name"
|
Rmail string "cdomain-name"
|
||||||
Email string "domain-name"
|
Email string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_MINFO) Header() *RR_Header {
|
func (rr *RR_MINFO) Header() *RR_Header {
|
||||||
@ -266,7 +266,7 @@ func (rr *RR_MINFO) Len() int {
|
|||||||
|
|
||||||
type RR_MR struct {
|
type RR_MR struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Mr string "domain-name"
|
Mr string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_MR) Header() *RR_Header {
|
func (rr *RR_MR) Header() *RR_Header {
|
||||||
@ -285,7 +285,7 @@ func (rr *RR_MR) Len() int {
|
|||||||
type RR_MX struct {
|
type RR_MX struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Pref uint16
|
Pref uint16
|
||||||
Mx string "domain-name"
|
Mx string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_MX) Header() *RR_Header {
|
func (rr *RR_MX) Header() *RR_Header {
|
||||||
@ -303,7 +303,7 @@ func (rr *RR_MX) Len() int {
|
|||||||
|
|
||||||
type RR_NS struct {
|
type RR_NS struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ns string "domain-name"
|
Ns string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_NS) Header() *RR_Header {
|
func (rr *RR_NS) Header() *RR_Header {
|
||||||
@ -321,7 +321,7 @@ func (rr *RR_NS) Len() int {
|
|||||||
|
|
||||||
type RR_PTR struct {
|
type RR_PTR struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ptr string "domain-name"
|
Ptr string "cdomain-name"
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rr *RR_PTR) Header() *RR_Header {
|
func (rr *RR_PTR) Header() *RR_Header {
|
||||||
@ -339,8 +339,8 @@ func (rr *RR_PTR) Len() int {
|
|||||||
|
|
||||||
type RR_SOA struct {
|
type RR_SOA struct {
|
||||||
Hdr RR_Header
|
Hdr RR_Header
|
||||||
Ns string "domain-name"
|
Ns string "cdomain-name"
|
||||||
Mbox string "domain-name"
|
Mbox string "cdomain-name"
|
||||||
Serial uint32
|
Serial uint32
|
||||||
Refresh uint32
|
Refresh uint32
|
||||||
Retry uint32
|
Retry uint32
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user