| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | // Package auto implements an on-the-fly loading file backend. | 
					
						
							|  |  |  | package auto | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-04-22 08:34:35 +01:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 	"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" | 
					
						
							| 
									
										
										
										
											2018-02-16 03:44:50 -05:00
										 |  |  | 	"github.com/coredns/coredns/plugin/pkg/upstream" | 
					
						
							| 
									
										
										
										
											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" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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. | 
					
						
							| 
									
										
										
										
											2018-11-13 16:46:48 -05:00
										 |  |  | 		transferTo     []string | 
					
						
							| 
									
										
										
										
											2018-09-29 17:50:49 +02:00
										 |  |  | 		ReloadInterval time.Duration | 
					
						
							| 
									
										
										
										
											2019-01-13 16:54:49 +00:00
										 |  |  | 		upstream       *upstream.Upstream // Upstream for looking up names during the resolution process. | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:53 -08:00
										 |  |  | // ServeDNS implements the plugin.Handler interface. | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | func (a Auto) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { | 
					
						
							| 
									
										
										
										
											2019-03-26 14:37:30 +00:00
										 |  |  | 	state := request.Request{W: w, Req: r} | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 	qname := state.Name() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-03-01 17:14:53 -08:00
										 |  |  | 	// Precheck with the origins, i.e. are we allowed to look 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) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-03-26 14:37:30 +00:00
										 |  |  | 	answer, ns, extra, result := z.Lookup(ctx, state, qname) | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	m := new(dns.Msg) | 
					
						
							|  |  |  | 	m.SetReply(r) | 
					
						
							| 
									
										
										
										
											2018-12-30 17:05:08 +01:00
										 |  |  | 	m.Authoritative = true | 
					
						
							| 
									
										
										
										
											2016-10-17 18:37:56 +01:00
										 |  |  | 	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 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	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" } |