| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | // Package auto implements an on-the-fly loading file backend.
 | 
					
						
							|  |  |  | package auto
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import (
 | 
					
						
							|  |  |  | 	"regexp"
 | 
					
						
							|  |  |  | 	"time"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	"github.com/coredns/coredns/plugin"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/file"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/metrics"
 | 
					
						
							|  |  |  | 	"github.com/coredns/coredns/plugin/proxy"
 | 
					
						
							| 
									
										
										
										
											2017-02-21 22:51:47 -08:00
										 |  |  | 	"github.com/coredns/coredns/request"
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/miekg/dns"
 | 
					
						
							|  |  |  | 	"golang.org/x/net/context"
 | 
					
						
							|  |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | type (
 | 
					
						
							|  |  |  | 	// Auto holds the zones and the loader configuration for automatically loading zones.
 | 
					
						
							|  |  |  | 	Auto struct {
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 		Next plugin.Handler
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 		*Zones
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 		metrics *metrics.Metrics
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 		loader
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	loader struct {
 | 
					
						
							|  |  |  | 		directory string
 | 
					
						
							|  |  |  | 		template  string
 | 
					
						
							|  |  |  | 		re        *regexp.Regexp
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// In the future this should be something like ZoneMeta that contains all this stuff.
 | 
					
						
							|  |  |  | 		transferTo []string
 | 
					
						
							|  |  |  | 		noReload   bool
 | 
					
						
							| 
									
										
										
										
											2016-11-10 07:48:47 +00:00
										 |  |  | 		proxy      proxy.Proxy // Proxy for looking up names during the resolution process
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		duration time.Duration
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | // ServeDNS implements the plugin.Handle interface.
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | func (a Auto) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) {
 | 
					
						
							|  |  |  | 	state := request.Request{W: w, Req: r}
 | 
					
						
							|  |  |  | 	qname := state.Name()
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// TODO(miek): match the qname better in the map
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Precheck with the origins, i.e. are we allowed to looks here.
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	zone := plugin.Zones(a.Zones.Origins()).Matches(qname)
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 	if zone == "" {
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 		return plugin.NextOrFailure(a.Name(), a.Next, ctx, w, r)
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Now the real zone.
 | 
					
						
							| 
									
										
										
										
											2017-09-14 09:36:06 +01:00
										 |  |  | 	zone = plugin.Zones(a.Zones.Names()).Matches(qname)
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	a.Zones.RLock()
 | 
					
						
							|  |  |  | 	z, ok := a.Zones.Z[zone]
 | 
					
						
							|  |  |  | 	a.Zones.RUnlock()
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-07 11:12:20 +00:00
										 |  |  | 	if !ok || z == nil {
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 		return dns.RcodeServerFailure, nil
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if state.QType() == dns.TypeAXFR || state.QType() == dns.TypeIXFR {
 | 
					
						
							|  |  |  | 		xfr := file.Xfr{Zone: z}
 | 
					
						
							|  |  |  | 		return xfr.ServeDNS(ctx, w, r)
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-10 12:58:40 +00:00
										 |  |  | 	answer, ns, extra, result := z.Lookup(state, qname)
 | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m := new(dns.Msg)
 | 
					
						
							|  |  |  | 	m.SetReply(r)
 | 
					
						
							|  |  |  | 	m.Authoritative, m.RecursionAvailable, m.Compress = true, true, true
 | 
					
						
							|  |  |  | 	m.Answer, m.Ns, m.Extra = answer, ns, extra
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	switch result {
 | 
					
						
							|  |  |  | 	case file.Success:
 | 
					
						
							|  |  |  | 	case file.NoData:
 | 
					
						
							|  |  |  | 	case file.NameError:
 | 
					
						
							|  |  |  | 		m.Rcode = dns.RcodeNameError
 | 
					
						
							|  |  |  | 	case file.Delegation:
 | 
					
						
							|  |  |  | 		m.Authoritative = false
 | 
					
						
							|  |  |  | 	case file.ServerFailure:
 | 
					
						
							|  |  |  | 		return dns.RcodeServerFailure, nil
 | 
					
						
							|  |  |  | 	}
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	state.SizeAndDo(m)
 | 
					
						
							|  |  |  | 	m, _ = state.Scrub(m)
 | 
					
						
							|  |  |  | 	w.WriteMsg(m)
 | 
					
						
							|  |  |  | 	return dns.RcodeSuccess, nil
 | 
					
						
							|  |  |  | }
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-27 11:48:37 +00:00
										 |  |  | // Name implements the Handler interface.
 | 
					
						
							| 
									
										
										
										
											2016-10-26 10:01:52 +01:00
										 |  |  | func (a Auto) Name() string { return "auto" }
 |