Cleanup and removals (#377)

* Cleanup and removals

Gut rawmsg.go as most functions are not used. Reword some documentation.
Add more types to be checked for name compression.

* Yeah, we do use these

* Remove this function as well - only used one
This commit is contained in:
Miek Gieben 2016-06-13 19:44:38 +01:00 committed by GitHub
parent b51e305bc6
commit e6b37d00af
5 changed files with 64 additions and 122 deletions

21
dns.go
View File

@ -3,17 +3,15 @@ package dns
import "strconv" import "strconv"
const ( const (
year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits. year68 = 1 << 31 // For RFC1982 (Serial Arithmetic) calculations in 32 bits.
// DefaultMsgSize is the standard default for messages larger than 512 bytes. defaultTtl = 3600 // Default internal TTL.
DefaultMsgSize = 4096
// MinMsgSize is the minimal size of a DNS packet. DefaultMsgSize = 4096 // DefaultMsgSize is the standard default for messages larger than 512 bytes.
MinMsgSize = 512 MinMsgSize = 512 // MinMsgSize is the minimal size of a DNS packet.
// MaxMsgSize is the largest possible DNS packet. MaxMsgSize = 65535 // MaxMsgSize is the largest possible DNS packet.
MaxMsgSize = 65535
defaultTtl = 3600 // Default internal TTL.
) )
// Error represents a DNS error // Error represents a DNS error.
type Error struct{ err string } type Error struct{ err string }
func (e *Error) Error() string { func (e *Error) Error() string {
@ -30,6 +28,7 @@ type RR interface {
Header() *RR_Header Header() *RR_Header
// String returns the text representation of the resource record. // String returns the text representation of the resource record.
String() string String() string
// copy returns a copy of the RR // copy returns a copy of the RR
copy() RR copy() RR
// len returns the length (in octets) of the uncompressed RR in wire format. // len returns the length (in octets) of the uncompressed RR in wire format.
@ -44,10 +43,10 @@ type RR_Header struct {
Rrtype uint16 Rrtype uint16
Class uint16 Class uint16
Ttl uint32 Ttl uint32
Rdlength uint16 // length of data after header Rdlength uint16 // Length of data after header.
} }
// Header returns itself. This is here to make RR_Header implement the RR interface. // Header returns itself. This is here to make RR_Header implements the RR interface.
func (h *RR_Header) Header() *RR_Header { return h } func (h *RR_Header) Header() *RR_Header { return h }
// Just to implement the RR interface. // Just to implement the RR interface.

110
msg.go
View File

@ -35,40 +35,27 @@ func init() {
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 (
// ErrAlg indicates an error with the (DNSSEC) algorithm. ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
ErrAlg error = &Error{err: "bad algorithm"} ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
// ErrAuth indicates an error in the TSIG authentication. ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used it too small for the message.
ErrAuth error = &Error{err: "bad authentication"} ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being uses before it is initialized.
// ErrBuf indicates that the buffer used it too small for the message. ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
ErrBuf error = &Error{err: "buffer size too small"} ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
// ErrConnEmpty indicates a connection is being uses before it is initialized. ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
ErrConnEmpty error = &Error{err: "conn has no connection"} ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
// ErrExtendedRcode ... ErrKey error = &Error{err: "bad key"}
ErrExtendedRcode error = &Error{err: "bad extended rcode"} ErrKeySize error = &Error{err: "bad key size"}
// ErrFqdn indicates that a domain name does not have a closing dot. ErrNoSig error = &Error{err: "no signature found"}
ErrFqdn error = &Error{err: "domain must be fully qualified"} ErrPrivKey error = &Error{err: "bad private key"}
// ErrId indicates there is a mismatch with the message's ID. ErrRcode error = &Error{err: "bad rcode"}
ErrId error = &Error{err: "id mismatch"} ErrRdata error = &Error{err: "bad rdata"}
// ErrKeyAlg indicates that the algorithm in the key is not valid. ErrRRset error = &Error{err: "bad rrset"}
ErrKeyAlg error = &Error{err: "bad key algorithm"} ErrSecret error = &Error{err: "no secrets defined"}
ErrKey error = &Error{err: "bad key"} ErrShortRead error = &Error{err: "short read"}
ErrKeySize error = &Error{err: "bad key size"} ErrSig error = &Error{err: "bad signature"} // ErrSig indicates that a signature can not be cryptographically validated.
ErrNoSig error = &Error{err: "no signature found"} ErrSoa error = &Error{err: "no SOA"} // ErrSOA indicates that no SOA RR was seen when doing zone transfers.
ErrPrivKey error = &Error{err: "bad private key"} ErrTime error = &Error{err: "bad time"} // ErrTime indicates a timing error in TSIG authentication.
ErrRcode error = &Error{err: "bad rcode"} ErrTruncated error = &Error{err: "failed to unpack truncated message"} // ErrTruncated indicates that we failed to unpack a truncated message. We unpacked as much as we had so Msg can still be used, if desired.
ErrRdata error = &Error{err: "bad rdata"}
ErrRRset error = &Error{err: "bad rrset"}
ErrSecret error = &Error{err: "no secrets defined"}
ErrShortRead error = &Error{err: "short read"}
// ErrSig indicates that a signature can not be cryptographically validated.
ErrSig error = &Error{err: "bad signature"}
// ErrSOA indicates that no SOA RR was seen when doing zone transfers.
ErrSoa error = &Error{err: "no SOA"}
// ErrTime indicates a timing error in TSIG authentication.
ErrTime error = &Error{err: "bad time"}
// ErrTruncated indicates that we failed to unpack a truncated message.
// We unpacked as much as we had so Msg can still be used, if desired.
ErrTruncated error = &Error{err: "failed to unpack truncated message"}
) )
// Id, by default, returns a 16 bits random number to be used as a // Id, by default, returns a 16 bits random number to be used as a
@ -79,6 +66,13 @@ var (
// dns.Id = func() uint16 { return 3 } // dns.Id = func() uint16 { return 3 }
var Id func() uint16 = id var Id func() uint16 = id
// id returns a 16 bits random number to be used as a
// message id. The random provided should be good enough.
func id() uint16 {
id32 := rand.Uint32()
return uint16(id32)
}
// MsgHdr is a a manually-unpacked version of (id, bits). // MsgHdr is a a manually-unpacked version of (id, bits).
type MsgHdr struct { type MsgHdr struct {
Id uint16 Id uint16
@ -97,7 +91,7 @@ type MsgHdr struct {
// Msg contains the layout of a DNS message. // Msg contains the layout of a DNS message.
type Msg struct { type Msg struct {
MsgHdr MsgHdr
Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format. This not part of the official DNS packet format. Compress bool `json:"-"` // If true, the message will be compressed when converted to wire format.
Question []Question // Holds the RR(s) of the question section. Question []Question // Holds the RR(s) of the question section.
Answer []RR // Holds the RR(s) of the answer section. Answer []RR // Holds the RR(s) of the answer section.
Ns []RR // Holds the RR(s) of the authority section. Ns []RR // Holds the RR(s) of the authority section.
@ -131,7 +125,7 @@ var RcodeToString = map[int]string{
RcodeNameError: "NXDOMAIN", RcodeNameError: "NXDOMAIN",
RcodeNotImplemented: "NOTIMPL", RcodeNotImplemented: "NOTIMPL",
RcodeRefused: "REFUSED", RcodeRefused: "REFUSED",
RcodeYXDomain: "YXDOMAIN", // From RFC 2136 RcodeYXDomain: "YXDOMAIN", // See RFC 2136
RcodeYXRrset: "YXRRSET", RcodeYXRrset: "YXRRSET",
RcodeNXRrset: "NXRRSET", RcodeNXRrset: "NXRRSET",
RcodeNotAuth: "NOTAUTH", RcodeNotAuth: "NOTAUTH",
@ -147,12 +141,6 @@ var RcodeToString = map[int]string{
RcodeBadCookie: "BADCOOKIE", RcodeBadCookie: "BADCOOKIE",
} }
// Rather than write the usual handful of routines to pack and
// unpack every message that can appear on the wire, we use
// reflection to write a generic pack/unpack for structs and then
// use it. Thus, if in the future we need to define new message
// structs, no new pack/unpack/printing code needs to be written.
// Domain names are a sequence of counted strings // Domain names are a sequence of counted strings
// split at the dots. They end with a zero-length string. // split at the dots. They end with a zero-length string.
@ -575,6 +563,7 @@ func PackRR(rr RR, msg []byte, off int, compression map[string]int, compress boo
if err != nil { if err != nil {
return len(msg), err return len(msg), err
} }
// TODO(miek): Not sure if this is needed? If removed we can remove rawmsg.go as well.
if rawSetRdlength(msg, off, off1) { if rawSetRdlength(msg, off, off1) {
return off1, nil return off1, nil
} }
@ -679,6 +668,7 @@ func (dns *Msg) Pack() (msg []byte, err error) {
// PackBuffer packs a Msg, using the given buffer buf. If buf is too small // PackBuffer packs a Msg, using the given buffer buf. If buf is too small
// a new buffer is allocated. // a new buffer is allocated.
func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) { func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
// We use a similar function in tsig.go's stripTsig.
var ( var (
dh Header dh Header
compression map[string]int compression map[string]int
@ -1001,7 +991,7 @@ func compressionLenSearch(c map[string]int, s string) (int, bool) {
return 0, false return 0, false
} }
// TODO(miek): should add all types, because the all can be *used* for compression. // TODO(miek): should add all types, because the all can be *used* for compression. Autogenerate from msg_generate and put in zmsg.go
func compressionLenHelperType(c map[string]int, r RR) { func compressionLenHelperType(c map[string]int, r RR) {
switch x := r.(type) { switch x := r.(type) {
case *NS: case *NS:
@ -1027,11 +1017,23 @@ func compressionLenHelperType(c map[string]int, r RR) {
compressionLenHelper(c, x.Md) compressionLenHelper(c, x.Md)
case *RT: case *RT:
compressionLenHelper(c, x.Host) compressionLenHelper(c, x.Host)
case *RP:
compressionLenHelper(c, x.Mbox)
compressionLenHelper(c, x.Txt)
case *MINFO: case *MINFO:
compressionLenHelper(c, x.Rmail) compressionLenHelper(c, x.Rmail)
compressionLenHelper(c, x.Email) compressionLenHelper(c, x.Email)
case *AFSDB: case *AFSDB:
compressionLenHelper(c, x.Hostname) compressionLenHelper(c, x.Hostname)
case *SRV:
compressionLenHelper(c, x.Target)
case *NAPTR:
compressionLenHelper(c, x.Replacement)
case *RRSIG:
compressionLenHelper(c, x.SignerName)
case *NSEC:
compressionLenHelper(c, x.NextDomain)
// HIP?
} }
} }
@ -1044,6 +1046,8 @@ func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
return compressionLenSearch(c, x.Mx) return compressionLenSearch(c, x.Mx)
case *CNAME: case *CNAME:
return compressionLenSearch(c, x.Target) return compressionLenSearch(c, x.Target)
case *DNAME:
return compressionLenSearch(c, x.Target)
case *PTR: case *PTR:
return compressionLenSearch(c, x.Ptr) return compressionLenSearch(c, x.Ptr)
case *SOA: case *SOA:
@ -1078,28 +1082,14 @@ func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
return 0, false return 0, false
} }
// id returns a 16 bits random number to be used as a
// message id. The random provided should be good enough.
func id() uint16 {
id32 := rand.Uint32()
return uint16(id32)
}
// Copy returns a new RR which is a deep-copy of r. // Copy returns a new RR which is a deep-copy of r.
func Copy(r RR) RR { func Copy(r RR) RR { r1 := r.copy(); return r1 }
r1 := r.copy()
return r1
}
// Len returns the length (in octets) of the uncompressed RR in wire format. // Len returns the length (in octets) of the uncompressed RR in wire format.
func Len(r RR) int { func Len(r RR) int { return r.len() }
return r.len()
}
// Copy returns a new *Msg which is a deep-copy of dns. // Copy returns a new *Msg which is a deep-copy of dns.
func (dns *Msg) Copy() *Msg { func (dns *Msg) Copy() *Msg { return dns.CopyTo(new(Msg)) }
return dns.CopyTo(new(Msg))
}
// CopyTo copies the contents to the provided message using a deep-copy and returns the copy. // CopyTo copies the contents to the provided message using a deep-copy and returns the copy.
func (dns *Msg) CopyTo(r1 *Msg) *Msg { func (dns *Msg) CopyTo(r1 *Msg) *Msg {

View File

@ -11,8 +11,7 @@ type saltWireFmt struct {
Salt string `dns:"size-hex"` Salt string `dns:"size-hex"`
} }
// HashName hashes a string (label) according to RFC 5155. It returns the hashed string in // HashName hashes a string (label) according to RFC 5155. It returns the hashed string in uppercase.
// uppercase.
func HashName(label string, ha uint8, iter uint16, salt string) string { func HashName(label string, ha uint8, iter uint16, salt string) string {
saltwire := new(saltWireFmt) saltwire := new(saltWireFmt)
saltwire.Salt = salt saltwire.Salt = salt

View File

@ -2,54 +2,6 @@ package dns
import "encoding/binary" import "encoding/binary"
// These raw* functions do not use reflection, they directly set the values
// in the buffer. There are faster than their reflection counterparts.
// RawSetId sets the message id in buf.
func rawSetId(msg []byte, i uint16) bool {
if len(msg) < 2 {
return false
}
binary.BigEndian.PutUint16(msg, i)
return true
}
// rawSetQuestionLen sets the length of the question section.
func rawSetQuestionLen(msg []byte, i uint16) bool {
if len(msg) < 6 {
return false
}
binary.BigEndian.PutUint16(msg[4:], i)
return true
}
// rawSetAnswerLen sets the length of the answer section.
func rawSetAnswerLen(msg []byte, i uint16) bool {
if len(msg) < 8 {
return false
}
binary.BigEndian.PutUint16(msg[6:], i)
return true
}
// rawSetsNsLen sets the length of the authority section.
func rawSetNsLen(msg []byte, i uint16) bool {
if len(msg) < 10 {
return false
}
binary.BigEndian.PutUint16(msg[8:], i)
return true
}
// rawSetExtraLen sets the length of the additional section.
func rawSetExtraLen(msg []byte, i uint16) bool {
if len(msg) < 12 {
return false
}
binary.BigEndian.PutUint16(msg[10:], i)
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, 'end' must be the // start of the header of the RR, 'end' must be the

View File

@ -141,7 +141,9 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
return nil, "", err return nil, "", err
} }
mbuf = append(mbuf, tbuf...) mbuf = append(mbuf, tbuf...)
rawSetExtraLen(mbuf, uint16(len(m.Extra)+1)) // Update the ArCount directly in the buffer.
binary.BigEndian.PutUint16(mbuf[10:], uint16(len(m.Extra)+1))
return mbuf, t.MAC, nil return mbuf, t.MAC, nil
} }