For prometheus use the plain value, not a pointer and change all usages. Allow AXFR to be requested over udp as well and some other more log printed when commencing an AXFR.
59 lines
1.3 KiB
Go
59 lines
1.3 KiB
Go
package file
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
|
|
"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("xfr called with non transfer type: %d", state.QType())
|
|
}
|
|
|
|
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
|
|
log.Printf("[INFO] Outgoing transfer of %d records of zone %s to %s started", len(records), x.name, state.IP())
|
|
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 = 1000 // Start a new envelop after message reaches this size in bytes. Intentionally small to test multi envelope parsing.
|