Merge conflict resolved

This commit is contained in:
Miek Gieben 2014-01-05 14:09:03 +00:00
commit 5c37b9e564
3 changed files with 80 additions and 11 deletions

2
msg.go
View File

@ -1300,8 +1300,6 @@ func (dns *Msg) Pack() (msg []byte, err error) {
var compression map[string]int
if dns.Compress {
compression = make(map[string]int) // Compression pointer mappings
} else {
compression = nil
}
// Convert convenient Msg into wire-like Header.

53
pool.go Normal file
View File

@ -0,0 +1,53 @@
package dns
import (
"container/list"
"time"
)
func mkBuf(size int) []byte { return make([]byte, size) }
type queued struct {
when time.Time
buf []byte
}
func pool(size int) (get, give chan []byte) {
get = make(chan []byte, 400) // TODO(miek): this number is arbitrary
give = make(chan []byte, 400)
go func() {
q := new(list.List)
for {
e := q.Front()
if e == nil {
q.PushFront(queued{when: time.Now(), buf: mkBuf(size)})
e = q.Front()
}
timeout := time.NewTimer(time.Minute)
select {
case b := <-give:
timeout.Stop()
q.PushFront(queued{when: time.Now(), buf: b})
case get <- e.Value.(queued).buf:
timeout.Stop()
q.Remove(e)
case <-timeout.C:
e := q.Front()
for e != nil {
n := e.Next()
if time.Since(e.Value.(queued).when) > time.Minute {
q.Remove(e)
e.Value = nil
}
e = n
}
}
}
}()
return
}

View File

@ -202,6 +202,8 @@ type Server struct {
WriteTimeout time.Duration // the net.Conn.SetWriteTimeout value for new connections
IdleTimeout func() time.Duration // TCP idle timeout for multiple queries, if nil, defaults to 8 * time.Second (RFC 5966)
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
Pool bool // if true use a pool to recycle buffers for UDP queries
get, give chan []byte // channels for the pool
}
// ListenAndServe starts a nameserver on the configured address in *Server.
@ -210,6 +212,12 @@ func (srv *Server) ListenAndServe() error {
if addr == "" {
addr = ":domain"
}
if srv.UDPSize == 0 {
srv.UDPSize = MinMsgSize
}
if srv.Pool {
srv.get, srv.give = pool(srv.UDPSize)
}
switch srv.Net {
case "tcp", "tcp4", "tcp6":
a, e := net.ResolveTCPAddr(srv.Net, addr)
@ -269,9 +277,6 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
if handler == nil {
handler = DefaultServeMux
}
if srv.UDPSize == 0 {
srv.UDPSize = MinMsgSize
}
rtimeout := dnsTimeout
if srv.ReadTimeout != 0 {
rtimeout = srv.ReadTimeout
@ -279,6 +284,7 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
for {
m, a, e := srv.readUDP(l, rtimeout)
if e != nil {
// TODO(miek): logging?
continue
}
go srv.serve(a, handler, m, l, nil)
@ -292,7 +298,11 @@ func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, t *net
q := 0
Redo:
req := new(Msg)
if req.Unpack(m) != nil { // Send a FormatError back
err := req.Unpack(m)
if srv.Pool && u != nil {
srv.give <- m[:srv.UDPSize]
}
if err != nil { // Send a FormatError back
x := new(Msg)
x.SetRcodeFormatError(req)
w.WriteMsg(x)
@ -346,11 +356,11 @@ func (srv *Server) readTCP(conn *net.TCPConn, timeout time.Duration) ([]byte, er
if err != nil {
return nil, err
}
return nil, ErrConn
return nil, ErrShortRead
}
length, _ := unpackUint16(l, 0)
if length == 0 {
return nil, ErrConn
return nil, ErrShortRead
}
m := make([]byte, int(length))
n, err = conn.Read(m[:int(length)])
@ -358,7 +368,7 @@ func (srv *Server) readTCP(conn *net.TCPConn, timeout time.Duration) ([]byte, er
if err != nil {
return nil, err
}
return nil, ErrConn
return nil, ErrShortRead
}
i := n
for i < int(length) {
@ -374,10 +384,18 @@ func (srv *Server) readTCP(conn *net.TCPConn, timeout time.Duration) ([]byte, er
}
func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, net.Addr, error) {
m := make([]byte, srv.UDPSize)
var m []byte
if srv.Pool {
m = <-srv.get
} else {
m = make([]byte, srv.UDPSize)
}
n, a, e := conn.ReadFromUDP(m)
if e != nil || n == 0 {
return nil, nil, ErrConn
if e != nil {
return nil, nil, e
}
return nil, nil, ErrShortRead
}
m = m[:n]
return m, a, nil