remove config.go

This commit is contained in:
Miek Gieben 2011-04-18 22:08:12 +02:00
parent bce6b62bc0
commit 19bfc93c5a
7 changed files with 217 additions and 247 deletions

View File

@ -9,7 +9,6 @@ TARG=dns
GOFILES=\ GOFILES=\
clientconfig.go\ clientconfig.go\
client.go\ client.go\
config.go\
defaults.go\ defaults.go\
dns.go\ dns.go\
dnssec.go\ dnssec.go\

104
client.go
View File

@ -28,10 +28,11 @@ type RequestWriter interface {
// hijacked connections...? // hijacked connections...?
type reply struct { type reply struct {
client *Client client *Client
addr string addr string
req *Msg req *Msg
conn net.Conn conn net.Conn
tsigTimersOnly bool
} }
type Request struct { type Request struct {
@ -118,14 +119,15 @@ func (mux *QueryMux) QueryDNS(w RequestWriter, r *Msg) {
// TODO add: LocalAddr // TODO add: LocalAddr
type Client struct { type Client struct {
Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one Net string // if "tcp" a TCP query will be initiated, otherwise an UDP one
Addr string // address to call Addr string // address to call
Attempts int // number of attempts Attempts int // number of attempts
Retry bool // retry with TCP Retry bool // retry with TCP
ChannelQuery chan *Request // read DNS request from this channel ChannelQuery chan *Request // read DNS request from this channel
ChannelReply chan []*Msg // read DNS request from this channel ChannelReply chan []*Msg // read DNS request from this channel
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
TsigSecret map[string]string // secret(s) for Tsig map[<zonename>]<base64 secret>
} }
func NewClient() *Client { func NewClient() *Client {
@ -234,15 +236,15 @@ func (w *reply) Receive() (*Msg, os.Error) {
p = make([]byte, MaxMsgSize) p = make([]byte, MaxMsgSize)
case "udp": case "udp":
p = make([]byte, DefaultMsgSize) p = make([]byte, DefaultMsgSize)
} }
n, err := w.readClient(p) n, err := w.readClient(p)
if err != nil { if err != nil {
return nil, err return nil, err
} }
p = p[:n] p = p[:n]
if ok := m.Unpack(p); !ok { if ok := m.Unpack(p); !ok {
return nil, ErrUnpack return nil, ErrUnpack
} }
return m, nil return m, nil
} }
@ -253,32 +255,32 @@ func (w *reply) readClient(p []byte) (n int, err os.Error) {
switch w.Client().Net { switch w.Client().Net {
case "tcp": case "tcp":
if len(p) < 1 { if len(p) < 1 {
return 0, io.ErrShortBuffer return 0, io.ErrShortBuffer
} }
n, err = w.conn.(*net.TCPConn).Read(p[0:2]) n, err = w.conn.(*net.TCPConn).Read(p[0:2])
if err != nil || n != 2 { if err != nil || n != 2 {
return n, err return n, err
} }
l, _ := unpackUint16(p[0:2], 0) l, _ := unpackUint16(p[0:2], 0)
if l == 0 { if l == 0 {
return 0, ErrShortRead return 0, ErrShortRead
} }
if int(l) > len(p) { if int(l) > len(p) {
return int(l), io.ErrShortBuffer return int(l), io.ErrShortBuffer
} }
n, err = w.conn.(*net.TCPConn).Read(p[:l]) n, err = w.conn.(*net.TCPConn).Read(p[:l])
if err != nil { if err != nil {
return n, err return n, err
} }
i := n i := n
for i < int(l) { for i < int(l) {
j, err := w.conn.(*net.TCPConn).Read(p[i:int(l)]) j, err := w.conn.(*net.TCPConn).Read(p[i:int(l)])
if err != nil { if err != nil {
return i, err return i, err
} }
i += j i += j
} }
n = i n = i
case "udp": case "udp":
n, _, err = w.conn.(*net.UDPConn).ReadFromUDP(p) n, _, err = w.conn.(*net.UDPConn).ReadFromUDP(p)
if err != nil { if err != nil {
@ -288,7 +290,15 @@ func (w *reply) readClient(p []byte) (n int, err os.Error) {
return return
} }
// Send a msg to the address specified in w.
// If the message m contains a TSIG record the transaction
// signature is calculated.
func (w *reply) Send(m *Msg) os.Error { func (w *reply) Send(m *Msg) os.Error {
if m.IsTsig() {
// Do tsig
}
out, ok := m.Pack() out, ok := m.Pack()
if !ok { if !ok {
return ErrPack return ErrPack

View File

@ -1,13 +0,0 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Generic configuration that is used for nameserver.
// It is meant to be as generic as possible.
package dns
type Config interface {
// Returns any Tsig information.
Tsig() *Tsig
}

View File

@ -47,7 +47,7 @@ func (dns *Msg) IsNotify() (ok bool) {
ok = dns.MsgHdr.Opcode == OpcodeNotify ok = dns.MsgHdr.Opcode == OpcodeNotify
ok = ok && dns.Question[0].Qclass == ClassINET ok = ok && dns.Question[0].Qclass == ClassINET
ok = ok && dns.Question[0].Qtype == TypeSOA ok = ok && dns.Question[0].Qtype == TypeSOA
return ok return
} }
// Create a dns msg suitable for requesting an ixfr. // Create a dns msg suitable for requesting an ixfr.
@ -78,7 +78,7 @@ func (dns *Msg) IsAxfr() (ok bool) {
ok = dns.MsgHdr.Opcode == OpcodeQuery ok = dns.MsgHdr.Opcode == OpcodeQuery
ok = ok && dns.Question[0].Qclass == ClassINET ok = ok && dns.Question[0].Qclass == ClassINET
ok = ok && dns.Question[0].Qtype == TypeAXFR ok = ok && dns.Question[0].Qtype == TypeAXFR
return ok return
} }
// Is the message a valid ixfr request packet? // Is the message a valid ixfr request packet?
@ -89,5 +89,22 @@ func (dns *Msg) IsIxfr() (ok bool) {
ok = dns.MsgHdr.Opcode == OpcodeQuery ok = dns.MsgHdr.Opcode == OpcodeQuery
ok = ok && dns.Question[0].Qclass == ClassINET ok = ok && dns.Question[0].Qclass == ClassINET
ok = ok && dns.Question[0].Qtype == TypeIXFR ok = ok && dns.Question[0].Qtype == TypeIXFR
return ok return
}
// Has a message a TSIG record as the last record?
func (dns *Msg) IsTsig() (ok bool) {
if len(dns.Extra) > 0 {
return dns.Extra[0].Header().Rrtype == TypeTSIG
}
return
}
func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned uint64) {
t := new(RR_TSIG)
t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
t.Algorithm = algo
t.Fudge = fudge
t.TimeSigned = timesigned
dns.Extra = append(dns.Extra, t)
} }

154
server.go
View File

@ -70,19 +70,19 @@ func (f HandlerFunc) ServeDNS(w ResponseWriter, r *Msg) {
// Helper handlers // Helper handlers
func Refused(w ResponseWriter, r *Msg) { func Refused(w ResponseWriter, r *Msg) {
m := new(Msg) m := new(Msg)
m.SetReply(r) m.SetReply(r)
m.MsgHdr.Rcode = RcodeRefused m.MsgHdr.Rcode = RcodeRefused
m.MsgHdr.Authoritative = false m.MsgHdr.Authoritative = false
buf, _ := m.Pack() buf, _ := m.Pack()
w.Write(buf) w.Write(buf)
} }
// RefusedHandler return a REFUSED answer // RefusedHandler return a REFUSED answer
func RefusedHandler() Handler { return HandlerFunc(Refused) } func RefusedHandler() Handler { return HandlerFunc(Refused) }
func ListenAndServe(addr string, network string, handler Handler) os.Error { func ListenAndServe(addr string, network string, handler Handler) os.Error {
server := &Server{Addr: addr, Network: network, Handler: handler} server := &Server{Addr: addr, Net: network, Handler: handler}
return server.ListenAndServe() return server.ListenAndServe()
} }
@ -90,19 +90,19 @@ func zoneMatch(pattern, zone string) (ok bool) {
if len(pattern) == 0 { if len(pattern) == 0 {
return return
} }
i:=0 i := 0
for { for {
ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i] ok = pattern[len(pattern)-1-i] == zone[len(zone)-1-i]
i++ i++
if !ok { if !ok {
break break
} }
if len(pattern)-1-i < 0 || len(zone)-1-i < 0{ if len(pattern)-1-i < 0 || len(zone)-1-i < 0 {
break break
} }
} }
return return
} }
@ -125,11 +125,11 @@ func (mux *ServeMux) Handle(pattern string, handler Handler) {
if pattern == "" { if pattern == "" {
panic("dns: invalid pattern " + pattern) panic("dns: invalid pattern " + pattern)
} }
if pattern[len(pattern)-1] != '.' { // no ending . if pattern[len(pattern)-1] != '.' { // no ending .
mux.m[pattern + "."] = handler mux.m[pattern+"."] = handler
} else { } else {
mux.m[pattern]= handler mux.m[pattern] = handler
} }
} }
func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) { func (mux *ServeMux) HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
@ -158,7 +158,7 @@ func HandleFunc(pattern string, handler func(ResponseWriter, *Msg)) {
// A Server defines parameters for running an DNS server. // A Server defines parameters for running an DNS server.
type Server struct { type Server struct {
Addr string // address to listen on, ":dns" if empty Addr string // address to listen on, ":dns" if empty
Network string // if "tcp" it will invoke a TCP listener, otherwise an UDP one Net string // if "tcp" it will invoke a TCP listener, otherwise an UDP one
Handler Handler // handler to invoke, dns.DefaultServeMux if nil Handler Handler // handler to invoke, dns.DefaultServeMux if nil
ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections ReadTimeout int64 // the net.Conn.SetReadTimeout value for new connections
WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections WriteTimeout int64 // the net.Conn.SetWriteTimeout value for new connections
@ -169,7 +169,7 @@ type Server struct {
// read requests and then call handler to reply to them. // read requests and then call handler to reply to them.
// Handler is typically nil, in which case the DefaultServeMux is used. // Handler is typically nil, in which case the DefaultServeMux is used.
func ServeTCP(l *net.TCPListener, handler Handler) os.Error { func ServeTCP(l *net.TCPListener, handler Handler) os.Error {
srv := &Server{Handler: handler, Network: "tcp"} srv := &Server{Handler: handler, Net: "tcp"}
return srv.ServeTCP(l) return srv.ServeTCP(l)
} }
@ -178,7 +178,7 @@ func ServeTCP(l *net.TCPListener, handler Handler) os.Error {
// read requests and then call handler to reply to them. // read requests and then call handler to reply to them.
// Handler is typically nil, in which case the DefaultServeMux is used. // Handler is typically nil, in which case the DefaultServeMux is used.
func ServeUDP(l *net.UDPConn, handler Handler) os.Error { func ServeUDP(l *net.UDPConn, handler Handler) os.Error {
srv := &Server{Handler: handler, Network: "udp"} srv := &Server{Handler: handler, Net: "udp"}
return srv.ServeUDP(l) return srv.ServeUDP(l)
} }
@ -188,7 +188,7 @@ func (srv *Server) ListenAndServe() os.Error {
if addr == "" { if addr == "" {
addr = ":domain" addr = ":domain"
} }
switch srv.Network { switch srv.Net {
case "tcp": case "tcp":
a, e := net.ResolveTCPAddr(addr) a, e := net.ResolveTCPAddr(addr)
if e != nil { if e != nil {
@ -323,60 +323,60 @@ func (c *conn) close() {
// Serve a new connection. // Serve a new connection.
func (c *conn) serve() { func (c *conn) serve() {
for { for {
// Request has been read in ServeUDP or ServeTCP // Request has been read in ServeUDP or ServeTCP
w := new(response) w := new(response)
w.conn = c w.conn = c
req := new(Msg) req := new(Msg)
if !req.Unpack(c.request) { if !req.Unpack(c.request) {
break break
} }
w.req = req w.req = req
c.handler.ServeDNS(w, w.req) // this does the writing back to the client c.handler.ServeDNS(w, w.req) // this does the writing back to the client
if c.hijacked { if c.hijacked {
return return
} }
break // TODO(mg) Why is this a loop anyway break // TODO(mg) Why is this a loop anyway
} }
if c._TCP != nil { if c._TCP != nil {
c.close() // Listen and Serve is closed then c.close() // Listen and Serve is closed then
} }
} }
func (w *response) Write(data []byte) (n int, err os.Error) { func (w *response) Write(data []byte) (n int, err os.Error) {
switch { switch {
case w.conn._UDP != nil: case w.conn._UDP != nil:
n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr) n, err = w.conn._UDP.WriteTo(data, w.conn.remoteAddr)
if err != nil { if err != nil {
return 0, err return 0, err
} }
case w.conn._TCP != nil: case w.conn._TCP != nil:
// TODO(mg) len(data) > 64K // TODO(mg) len(data) > 64K
l := make([]byte, 2) l := make([]byte, 2)
l[0], l[1] = packUint16(uint16(len(data))) l[0], l[1] = packUint16(uint16(len(data)))
n, err = w.conn._TCP.Write(l) n, err = w.conn._TCP.Write(l)
if err != nil { if err != nil {
return n, err return n, err
} }
if n != 2 { if n != 2 {
return n, io.ErrShortWrite return n, io.ErrShortWrite
} }
n, err = w.conn._TCP.Write(data) n, err = w.conn._TCP.Write(data)
if err != nil { if err != nil {
return n, err return n, err
} }
i := n i := n
if i < len(data) { if i < len(data) {
j, err := w.conn._TCP.Write(data[i:len(data)]) j, err := w.conn._TCP.Write(data[i:len(data)])
if err != nil { if err != nil {
return i, err return i, err
} }
i += j i += j
} }
n = i n = i
} }
return n, nil return n, nil
} }
// RemoteAddr implements the ResponseWriter.RemoteAddr method // RemoteAddr implements the ResponseWriter.RemoteAddr method

139
tsig.go
View File

@ -21,49 +21,6 @@ import (
// tsig.TimeSigned = uint64(time.Seconds()) // tsig.TimeSigned = uint64(time.Seconds())
// tsig.Secret = "so6ZGir4GPAqINNh9U5c3A==" // Secret encoded in base64. // tsig.Secret = "so6ZGir4GPAqINNh9U5c3A==" // Secret encoded in base64.
type TsigWriter struct {
secrets map[string]string
w io.Writer
name string
fudge uint16
algorithm string
timersOnly bool
}
// NewTsigWriter creates a new writer that implements TSIG, secrets
// should contain a mapping from key names to secrets. A message
// should be written with the TSIG record appends. Tsig
func NewTsigWriter(w io.Writer, secrets map[string]string) *TsigWriter {
t := new(TsigWriter)
t.secrets = secrets
return t
}
func (t *TsigWriter) Write(p []byte) (int, os.Error) {
return 0, nil
}
type Tsig struct {
// The name of the key.
Name string
// Fudge to take into account.
Fudge uint16
// When is the TSIG created
TimeSigned uint64
// Which algorithm is used.
Algorithm string
// Tsig secret encoded in base64.
Secret string
// MAC (if known)
MAC string
// Request MAC
RequestMAC string
// Only include the timers in the MAC if set to true.
TimersOnly bool
}
// HMAC hashing codes. These are transmitted as domain names. // HMAC hashing codes. These are transmitted as domain names.
const ( const (
HmacMD5 = "hmac-md5.sig-alg.reg.int." HmacMD5 = "hmac-md5.sig-alg.reg.int."
@ -101,50 +58,42 @@ type timerWireFmt struct {
Fudge uint16 Fudge uint16
} }
// Add a Tsig to add message. // Add a Tsig to an message. // Must return the mac
func (t *Tsig) Generate(msg []byte) ([]byte, os.Error) { func TsigGenerate(m *Msg, secret string, timersOnly bool) (*Msg, os.Error) {
rawsecret, err := packBase64([]byte(t.Secret)) if !m.IsTsig() {
panic("TSIG not last RR in additional")
}
rawsecret, err := packBase64([]byte(secret))
if err != nil { if err != nil {
return nil, err return nil, err
} }
if t.Fudge == 0 {
t.Fudge = 300
}
if t.TimeSigned == 0 {
t.TimeSigned = uint64(time.Seconds())
}
buf, err := t.Buffer(msg) rr := m.Extra[len(m.Extra)-1].(*RR_TSIG)
m.Extra = m.Extra[0:len(m.Extra)-1] // kill the TSIG from the msg
buf, err := tsigBuffer(m, rr, timersOnly)
if err != nil { if err != nil {
return nil, err return nil, err
} }
t := new(RR_TSIG)
h := hmac.NewMD5([]byte(rawsecret)) h := hmac.NewMD5([]byte(rawsecret))
io.WriteString(h, string(buf)) io.WriteString(h, string(buf))
t.MAC = hex.EncodeToString(h.Sum()) // Size is half! t.MAC = hex.EncodeToString(h.Sum()) // Size is half!
// Create TSIG and add it to the message. t.Hdr = RR_Header{Name: rr.Hdr.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0}
q := new(Msg) t.Fudge = t.Fudge
if !q.Unpack(msg) { t.TimeSigned = t.TimeSigned
return nil, ErrUnpack t.Algorithm = t.Algorithm
} t.OrigId = m.MsgHdr.Id
t.MAC = t.MAC
t.MACSize = uint16(len(t.MAC) / 2)
rr := new(RR_TSIG) m.Extra = append(m.Extra, t)
rr.Hdr = RR_Header{Name: t.Name, Rrtype: TypeTSIG, Class: ClassANY, Ttl: 0} return m, nil
rr.Fudge = t.Fudge
rr.TimeSigned = t.TimeSigned
rr.Algorithm = t.Algorithm
rr.OrigId = q.Id
rr.MAC = t.MAC
rr.MACSize = uint16(len(t.MAC) / 2)
q.Extra = append(q.Extra, rr)
send, ok := q.Pack()
if !ok {
return send, ErrPack
}
return send, nil
} }
/*
// Verify a TSIG on a message. // Verify a TSIG on a message.
// If the signature does not validate err contains the // If the signature does not validate err contains the
// error. If the it validates err is nil // error. If the it validates err is nil
@ -164,25 +113,32 @@ func (t *Tsig) Verify(msg []byte) (bool, os.Error) {
return false, err return false, err
} }
// Time needs to be checked */ // Time needs to be checked
h := hmac.NewMD5([]byte(rawsecret)) h := hmac.NewMD5([]byte(rawsecret))
io.WriteString(h, string(buf)) io.WriteString(h, string(buf))
return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC), nil return strings.ToUpper(hex.EncodeToString(h.Sum())) == strings.ToUpper(t.MAC), nil
} }
*/
// Create a wiredata buffer for the MAC calculation. // Create a wiredata buffer for the MAC calculation.
func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) { func tsigBuffer(msg *Msg, rr *RR_TSIG, timersOnly bool) ([]byte, os.Error) {
var ( var (
macbuf []byte macbuf []byte
buf []byte buf []byte
) )
if rr.TimeSigned == 0 {
rr.TimeSigned = uint64(time.Seconds())
}
if rr.Fudge == 0 {
rr.Fudge = 300
}
if t.RequestMAC != "" { if rr.MAC != "" {
m := new(macWireFmt) m := new(macWireFmt)
m.MACSize = uint16(len(t.RequestMAC) / 2) m.MACSize = uint16(len(rr.MAC) / 2)
m.MAC = t.RequestMAC m.MAC = rr.MAC
macbuf = make([]byte, len(t.RequestMAC)) // reqmac should be twice as long macbuf = make([]byte, len(rr.MAC)) // reqmac should be twice as long
n, ok := packStruct(m, macbuf, 0) n, ok := packStruct(m, macbuf, 0)
if !ok { if !ok {
return nil, ErrSigGen return nil, ErrSigGen
@ -191,10 +147,10 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
} }
tsigvar := make([]byte, DefaultMsgSize) tsigvar := make([]byte, DefaultMsgSize)
if t.TimersOnly { if timersOnly {
tsig := new(timerWireFmt) tsig := new(timerWireFmt)
tsig.TimeSigned = t.TimeSigned tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = t.Fudge tsig.Fudge = rr.Fudge
n, ok1 := packStruct(tsig, tsigvar, 0) n, ok1 := packStruct(tsig, tsigvar, 0)
if !ok1 { if !ok1 {
return nil, ErrSigGen return nil, ErrSigGen
@ -202,12 +158,12 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
tsigvar = tsigvar[:n] tsigvar = tsigvar[:n]
} else { } else {
tsig := new(tsigWireFmt) tsig := new(tsigWireFmt)
tsig.Name = strings.ToLower(t.Name) tsig.Name = strings.ToLower(rr.Hdr.Name)
tsig.Class = ClassANY tsig.Class = ClassANY
tsig.Ttl = 0 tsig.Ttl = 0
tsig.Algorithm = strings.ToLower(t.Algorithm) tsig.Algorithm = strings.ToLower(rr.Algorithm)
tsig.TimeSigned = t.TimeSigned tsig.TimeSigned = rr.TimeSigned
tsig.Fudge = t.Fudge tsig.Fudge = rr.Fudge
tsig.Error = 0 tsig.Error = 0
tsig.OtherLen = 0 tsig.OtherLen = 0
tsig.OtherData = "" tsig.OtherData = ""
@ -217,15 +173,17 @@ func (t *Tsig) Buffer(msg []byte) ([]byte, os.Error) {
} }
tsigvar = tsigvar[:n] tsigvar = tsigvar[:n]
} }
if t.RequestMAC != "" { if rr.MAC != "" {
x := append(macbuf, msg...) msgbuf, _ := msg.Pack()
x := append(macbuf, msgbuf...)
buf = append(x, tsigvar...) buf = append(x, tsigvar...)
} else { } else {
buf = append(msg, tsigvar...) msgbuf, _ := msg.Pack()
buf = append(msgbuf, tsigvar...)
} }
return buf, nil return buf, nil
} }
/*
// Strip the TSIG from the pkt. // Strip the TSIG from the pkt.
func (t *Tsig) stripTsig(orig []byte) ([]byte, os.Error) { func (t *Tsig) stripTsig(orig []byte) ([]byte, os.Error) {
// Copied from msg.go's Unpack() // Copied from msg.go's Unpack()
@ -292,3 +250,4 @@ func (t *Tsig) stripTsig(orig []byte) ([]byte, os.Error) {
} }
return msg[:tsigoff], nil return msg[:tsigoff], nil
} }
*/

30
xfr.go
View File

@ -8,31 +8,31 @@ import (
// section contains an AXFR type an Axfr is performed. If q's question // section contains an AXFR type an Axfr is performed. If q's question
// section contains an IXFR type an Ixfr is performed. // section contains an IXFR type an Ixfr is performed.
func (c *Client) XfrReceive(q *Msg, a string) ([]*Msg, os.Error) { func (c *Client) XfrReceive(q *Msg, a string) ([]*Msg, os.Error) {
w := new(reply) w := new(reply)
w.client = c w.client = c
w.addr = a w.addr = a
w.req = q // is this needed?? w.req = q // is this needed TODO(mg)
if err := w.Send(q); err != nil { if err := w.Send(q); err != nil {
return nil, err return nil, err
} }
// conn should be set now // conn should be set now
switch q.Question[0].Qtype { switch q.Question[0].Qtype {
case TypeAXFR: case TypeAXFR:
return w.axfrReceive() return w.axfrReceive()
case TypeIXFR: case TypeIXFR:
// return w.ixfrReceive() // return w.ixfrReceive()
} }
panic("not reached") panic("not reached")
return nil, nil return nil, nil
} }
func (w *reply) axfrReceive() ([]*Msg, os.Error) { func (w *reply) axfrReceive() ([]*Msg, os.Error) {
axfr := make([]*Msg, 0) // use append ALL the time? axfr := make([]*Msg, 0) // use append ALL the time?
first := true first := true
for { for {
in, err := w.Receive() in, err := w.Receive()
axfr = append(axfr, in) axfr = append(axfr, in)
if err != nil { if err != nil {
return axfr, err return axfr, err
} }
@ -45,9 +45,7 @@ func (w *reply) axfrReceive() ([]*Msg, os.Error) {
} }
if !first { if !first {
//if d.Tsig != nil { w.tsigTimersOnly = true // Subsequent envelopes use this.
// d.Tsig.TimersOnly = true // Subsequent envelopes use this.
//}
if !checkXfrSOA(in, false) { if !checkXfrSOA(in, false) {
// Soa record not the last one // Soa record not the last one
continue continue