Fix handling of non fully qualified domain names
When PackDomain sees such a name it calls panic. All panic now use the prefix 'dns:'
This commit is contained in:
parent
8bc979fe1e
commit
e4fb00c34d
20
dns_test.go
20
dns_test.go
|
@ -111,8 +111,24 @@ func TestPack(t *testing.T) {
|
|||
t.Fail()
|
||||
}
|
||||
}
|
||||
ns := NewRR("pool.ntp.org. 390 IN NS a.ntpns.org")
|
||||
t.Log("ns", ns.String())
|
||||
x := new(Msg)
|
||||
ns, _ := NewRR("pool.ntp.org. 390 IN NS a.ntpns.org")
|
||||
ns.(*RR_NS).Ns = "a.ntpns.org."
|
||||
x.Ns = append(m.Ns, ns)
|
||||
x.Ns = append(m.Ns, ns)
|
||||
x.Ns = append(m.Ns, ns)
|
||||
// This crashes due to the fact the a.ntpns.org isn't a FQDN
|
||||
// How to recover() from a remove panic()?
|
||||
if _, ok := x.Pack(); !ok {
|
||||
t.Log("Packing failed")
|
||||
t.Fail()
|
||||
}
|
||||
x.Answer = make([]RR, 1)
|
||||
x.Answer[0], err = NewRR(rr[0])
|
||||
if _, ok := x.Pack(); !ok {
|
||||
t.Log("Packing failed")
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestCompressLenght(t *testing.T) {
|
||||
|
|
18
msg.go
18
msg.go
|
@ -205,8 +205,7 @@ func PackDomainName(s string, msg []byte, off int, compression map[string]int, c
|
|||
// Add trailing dot to canonicalize name.
|
||||
lenmsg := len(msg)
|
||||
if n := len(s); n == 0 || s[n-1] != '.' {
|
||||
// Make it fully qualified
|
||||
s += "."
|
||||
panic("dns: name not fully qualified")
|
||||
}
|
||||
// Each dot ends a segment of the name.
|
||||
// We trade each dot byte for a length byte.
|
||||
|
@ -235,13 +234,23 @@ func PackDomainName(s string, msg []byte, off int, compression map[string]int, c
|
|||
if i-begin >= 1<<6 { // top two bits of length must be clear
|
||||
return lenmsg, false
|
||||
}
|
||||
// off can already (we're in a loop) be bigger than len(msg)
|
||||
// this happens when a name isn't fully qualified
|
||||
if off+1 > len(msg) {
|
||||
return lenmsg, false
|
||||
}
|
||||
msg[off] = byte(i - begin)
|
||||
offset := off
|
||||
off++
|
||||
// TODO(mg): because of the new check above, this can go. But
|
||||
// just leave it as is for the moment.
|
||||
if off > lenmsg {
|
||||
return lenmsg, false
|
||||
}
|
||||
for j := begin; j < i; j++ {
|
||||
if off+1 > len(msg) {
|
||||
return lenmsg, false
|
||||
}
|
||||
msg[off] = bs[j]
|
||||
off++
|
||||
if off > lenmsg {
|
||||
|
@ -1210,7 +1219,7 @@ func (dns *Msg) Pack() (msg []byte, ok bool) {
|
|||
dh.Arcount = uint16(len(extra))
|
||||
|
||||
// TODO(mg): still a little too much, but better than 64K...
|
||||
msg = make([]byte, dns.Len()+1)
|
||||
msg = make([]byte, dns.Len()+10)
|
||||
|
||||
// Pack it in: header and then the pieces.
|
||||
off := 0
|
||||
|
@ -1328,7 +1337,8 @@ func (dns *Msg) String() string {
|
|||
|
||||
// Len return the message length when in (un)compressed wire format.
|
||||
// If dns.Compress is true compression is taken into account, currently
|
||||
// this only counts owner name compression.
|
||||
// this only counts owner name compression. There is no check for
|
||||
// nil valued sections (allocated, but contains no RRs).
|
||||
func (dns *Msg) Len() int {
|
||||
// Message header is always 12 bytes
|
||||
l := 12
|
||||
|
|
|
@ -256,7 +256,7 @@ forever:
|
|||
}
|
||||
go d.serve()
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
||||
// ServeUDP starts a UDP listener for the server.
|
||||
|
@ -290,7 +290,7 @@ func (srv *Server) ServeUDP(l *net.UDPConn) error {
|
|||
}
|
||||
go d.serve()
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
||||
func newConn(t *net.TCPConn, u *net.UDPConn, a net.Addr, buf []byte, handler Handler, tsig map[string]string) (*conn, error) {
|
||||
|
|
2
tsig.go
2
tsig.go
|
@ -155,7 +155,7 @@ type timerWireFmt struct {
|
|||
// If something goes wrong an error is returned, otherwise it is nil.
|
||||
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
|
||||
if m.IsTsig() == nil {
|
||||
panic("TSIG not last RR in additional")
|
||||
panic("dns: TSIG not last RR in additional")
|
||||
}
|
||||
// If we barf here, the caller is to blame
|
||||
rawsecret, err := packBase64([]byte(secret))
|
||||
|
|
4
types.go
4
types.go
|
@ -883,7 +883,7 @@ func (rr *RR_NSEC) String() string {
|
|||
|
||||
func (rr *RR_NSEC) Len() int {
|
||||
l := len(rr.NextDomain) + 1
|
||||
return rr.Hdr.Len() + l + 32
|
||||
return rr.Hdr.Len() + l + 32 + 1
|
||||
// TODO: +32 is max type bitmap
|
||||
}
|
||||
|
||||
|
@ -1420,7 +1420,7 @@ func cmToString(mantissa, exponent uint8) string {
|
|||
}
|
||||
return s
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
||||
// Map of constructors for each RR wire type.
|
||||
|
|
|
@ -57,7 +57,7 @@ func (u *Msg) NameNotUsed(rr []RR) {
|
|||
// "RRset exists (value dependent -- with rdata)" RRs. RFC 2136 section 2.4.2.
|
||||
func (u *Msg) RRsetUsedRdata(rr []RR) {
|
||||
if len(u.Question) == 0 {
|
||||
panic("empty question section")
|
||||
panic("dns: empty question section")
|
||||
}
|
||||
u.Answer = make([]RR, len(rr))
|
||||
for i, r := range rr {
|
||||
|
@ -104,7 +104,7 @@ func (u *Msg) RRsetNotUsed(rr []RR) {
|
|||
// RRsetAddRdata creates a dynamic update packet that adds an complete RRset, see RFC 2136 section 2.5.1
|
||||
func (u *Msg) RRsetAddRdata(rr []RR) {
|
||||
if len(u.Question) == 0 {
|
||||
panic("empty question section")
|
||||
panic("dns: empty question section")
|
||||
}
|
||||
u.Ns = make([]RR, len(rr))
|
||||
for i, r := range rr {
|
||||
|
|
6
xfr.go
6
xfr.go
|
@ -50,7 +50,7 @@ func (c *Client) XfrReceive(q *Msg, a string) (chan *XfrMsg, error) {
|
|||
default:
|
||||
return nil, ErrXfrType
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
||||
func (w *reply) axfrReceive(c chan *XfrMsg) {
|
||||
|
@ -84,7 +84,7 @@ func (w *reply) axfrReceive(c chan *XfrMsg) {
|
|||
c <- &XfrMsg{Request: w.req, Reply: in, Rtt: w.rtt, RemoteAddr: w.conn.RemoteAddr(), Error: nil}
|
||||
}
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
||||
func (w *reply) ixfrReceive(c chan *XfrMsg) {
|
||||
|
@ -132,7 +132,7 @@ func (w *reply) ixfrReceive(c chan *XfrMsg) {
|
|||
c <- &XfrMsg{Request: w.req, Reply: in, Rtt: w.rtt, RemoteAddr: w.conn.RemoteAddr()}
|
||||
}
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
||||
// XfrSend performs an outgoing Ixfr or Axfr. The function is [AI]xfr agnostic, it is
|
||||
|
|
|
@ -155,5 +155,5 @@ func modToPrintf(s string) (string, int, string) {
|
|||
default:
|
||||
return "%0" + xs[1] + xs[2], offset, ""
|
||||
}
|
||||
panic("not reached")
|
||||
panic("dns: not reached")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue