From b5d73f1effeae7884f0e4f73daff2d082c132c2f Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Wed, 11 Jan 2012 11:19:07 +0100 Subject: [PATCH] Implement compressible domain names --- dns.go | 2 +- msg.go | 52 +++++++++++++++++++++++++++++----------------------- rawmsg.go | 4 ---- types.go | 24 ++++++++++++------------ 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/dns.go b/dns.go index 9f5c693c..1106d6a6 100644 --- a/dns.go +++ b/dns.go @@ -173,7 +173,7 @@ type Exchange struct { // There are many types of messages, // but they all share the same header. type RR_Header struct { - Name string "domain-name" + Name string "cdomain-name" Rrtype uint16 Class uint16 Ttl uint32 diff --git a/msg.go b/msg.go index 66b38485..18413ff1 100644 --- a/msg.go +++ b/msg.go @@ -26,7 +26,7 @@ import ( "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 ( 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 } msg[off] = byte(i - begin) - offset := off + offset := off off++ for j := begin; j < i; j++ { msg[off] = bs[j] off++ } - str, _, ok := UnpackDomainName(msg, offset) - if !ok { - // hmmm how can this be? - } - if compression != nil { - if _, ok := compression[str]; !ok { - compression[str] = offset - } - } + str, _, ok := UnpackDomainName(msg, offset) + if !ok { + // hmmm how can this be? + } + if compression != nil { + if _, ok := compression[str]; !ok { + compression[str] = offset + } + } 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) off += len(b64) 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 { //fmt.Fprintf(os.Stderr, "dns: overflow packing domain-name") 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") return lenmsg, false } - if off+hex.DecodedLen(len(s)) > lenmsg { - // Overflow - return lenmsg, false - } + if off+hex.DecodedLen(len(s)) > lenmsg { + // Overflow + return lenmsg, false + } copy(msg[off:off+hex.DecodedLen(len(s))], h) off += hex.DecodedLen(len(s)) case "size": @@ -664,10 +670,10 @@ func unpackStructValue(val reflect.Value, msg []byte, off int) (off1 int, ok boo case "hex": // Rest of the RR is hex encoded, network order an issue here? rdlength := int(val.FieldByName("Hdr").FieldByName("Rdlength").Uint()) - if off+rdlength > lenmsg { - // too large - return lenmsg, false - } + if off+rdlength > lenmsg { + // too large + return lenmsg, false + } var consumed int switch val.Type().Name() { case "RR_DS": @@ -956,7 +962,7 @@ func (h *MsgHdr) String() string { // Pack a msg: convert it to wire format. func (dns *Msg) Pack() (msg []byte, ok bool) { 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. dh.Id = dns.Id @@ -997,7 +1003,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) { dh.Nscount = uint16(len(ns)) 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) // Pack it in: header and then the pieces. @@ -1022,7 +1028,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) { if !ok { return nil, false } - fmt.Printf("**%v\n", compression) + fmt.Printf("**%v\n", compression) return msg[:off], true } diff --git a/rawmsg.go b/rawmsg.go index 599b8749..8f800548 100644 --- a/rawmsg.go +++ b/rawmsg.go @@ -4,10 +4,6 @@ package dns -import ( - "fmt" -) - // Function defined in this subpackage work on []byte and but still // provide some higher level functions. diff --git a/types.go b/types.go index 6f573314..dbb113be 100644 --- a/types.go +++ b/types.go @@ -129,7 +129,7 @@ const ( // DNS queries. 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 Qclass uint16 } @@ -174,7 +174,7 @@ func (rr *RR_ANY) Len() int { type RR_CNAME struct { Hdr RR_Header - Cname string "domain-name" + Cname string "cdomain-name" } func (rr *RR_CNAME) Header() *RR_Header { @@ -210,7 +210,7 @@ func (rr *RR_HINFO) Len() int { type RR_MB struct { Hdr RR_Header - Mb string "domain-name" + Mb string "cdomain-name" } func (rr *RR_MB) Header() *RR_Header { @@ -228,7 +228,7 @@ func (rr *RR_MB) Len() int { type RR_MG struct { Hdr RR_Header - Mg string "domain-name" + Mg string "cdomain-name" } func (rr *RR_MG) Header() *RR_Header { @@ -246,8 +246,8 @@ func (rr *RR_MG) Len() int { type RR_MINFO struct { Hdr RR_Header - Rmail string "domain-name" - Email string "domain-name" + Rmail string "cdomain-name" + Email string "cdomain-name" } func (rr *RR_MINFO) Header() *RR_Header { @@ -266,7 +266,7 @@ func (rr *RR_MINFO) Len() int { type RR_MR struct { Hdr RR_Header - Mr string "domain-name" + Mr string "cdomain-name" } func (rr *RR_MR) Header() *RR_Header { @@ -285,7 +285,7 @@ func (rr *RR_MR) Len() int { type RR_MX struct { Hdr RR_Header Pref uint16 - Mx string "domain-name" + Mx string "cdomain-name" } func (rr *RR_MX) Header() *RR_Header { @@ -303,7 +303,7 @@ func (rr *RR_MX) Len() int { type RR_NS struct { Hdr RR_Header - Ns string "domain-name" + Ns string "cdomain-name" } func (rr *RR_NS) Header() *RR_Header { @@ -321,7 +321,7 @@ func (rr *RR_NS) Len() int { type RR_PTR struct { Hdr RR_Header - Ptr string "domain-name" + Ptr string "cdomain-name" } func (rr *RR_PTR) Header() *RR_Header { @@ -339,8 +339,8 @@ func (rr *RR_PTR) Len() int { type RR_SOA struct { Hdr RR_Header - Ns string "domain-name" - Mbox string "domain-name" + Ns string "cdomain-name" + Mbox string "cdomain-name" Serial uint32 Refresh uint32 Retry uint32