coredns/middleware/file/xfr.go
Miek Gieben f58f1e4285 Add secondary support
Allow specifying a primary server and retrieve the zone's content.

Add tests and an Expired bool to zone struct, to stop server zones

that are expired. The zone is retrieved on Startup, no updates of

changed content are done. We also don't respond to notifies yet.
2016-04-03 09:02:34 +01:00

61 lines
1.3 KiB
Go

package file
import (
"fmt"
"github.com/miekg/coredns/middleware"
"github.com/miekg/dns"
"golang.org/x/net/context"
)
type (
Xfr struct {
*Zone
}
)
// Serve an AXFR (or maybe later an IXFR) as well.
func (x Xfr) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
state := middleware.State{W: w, Req: r}
if !x.TransferAllowed(state) {
return dns.RcodeServerFailure, nil
}
if state.QType() != dns.TypeAXFR {
return 0, fmt.Errorf("file: xfr called with non transfer type: %d", state.QType())
}
if state.Proto() == "udp" {
return 0, fmt.Errorf("file: xfr called with udp")
}
records := x.All()
if len(records) == 0 {
return dns.RcodeServerFailure, nil
}
ch := make(chan *dns.Envelope)
defer close(ch)
tr := new(dns.Transfer)
go tr.Out(w, r, ch)
j, l := 0, 0
records = append(records, records[0]) // add closing SOA to the end
for i, r := range records {
l += dns.Len(r)
if l > transferLength {
ch <- &dns.Envelope{RR: records[j:i]}
l = 0
j = i
}
}
if j < len(records) {
ch <- &dns.Envelope{RR: records[j:]}
}
w.Hijack()
// w.Close() // Client closes connection
return dns.RcodeSuccess, nil
}
//const transferLength = 10e3 // Start a new envelop after message reaches this size.
const transferLength = 100 // Start a new envelop after message reaches this size.