mirror of
				https://github.com/coredns/coredns.git
				synced 2025-10-30 09:43:17 -04:00 
			
		
		
		
	* Implement notifies for transfer plugin (#3972) * Fix notifies in transfer plugin Signed-off-by: Miek Gieben <miek@miek.nl> * Make it compile Signed-off-by: Miek Gieben <miek@miek.nl> * Port more plugins Signed-off-by: Miek Gieben <miek@miek.nl> * golint Signed-off-by: Miek Gieben <miek@miek.nl> * Fix tests Signed-off-by: Miek Gieben <miek@miek.nl> * Fix notifies in transfer plugin Signed-off-by: Miek Gieben <miek@miek.nl> * Make it compile Signed-off-by: Miek Gieben <miek@miek.nl> * Port more plugins Signed-off-by: Miek Gieben <miek@miek.nl> * golint Signed-off-by: Miek Gieben <miek@miek.nl> * Fix tests Signed-off-by: Miek Gieben <miek@miek.nl> * Fix tests Signed-off-by: Miek Gieben <miek@miek.nl> * really fix test Signed-off-by: Miek Gieben <miek@miek.nl> * Implement ixfr fallback and unify file and auto for transfering Signed-off-by: Miek Gieben <miek@miek.nl> * Add transfer tests copied and modified from #3452 Signed-off-by: Miek Gieben <miek@miek.nl> * Test correct selection of plugin Signed-off-by: Miek Gieben <miek@miek.nl> * add upstream back in Signed-off-by: Miek Gieben <miek@miek.nl> * Implement ixfr fallback and unify file and auto for transfering Signed-off-by: Miek Gieben <miek@miek.nl> * fix test Signed-off-by: Miek Gieben <miek@miek.nl> * properly merge Signed-off-by: Miek Gieben <miek@miek.nl> * Remove plugin/kubernetes/setup_transfer_test.go Signed-off-by: Yong Tang <yong.tang.github@outlook.com> Co-authored-by: Miek Gieben <miek@miek.nl>
		
			
				
	
	
		
			179 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			179 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package file
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"path/filepath"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/coredns/coredns/plugin/file/tree"
 | |
| 	"github.com/coredns/coredns/plugin/pkg/upstream"
 | |
| 
 | |
| 	"github.com/miekg/dns"
 | |
| )
 | |
| 
 | |
| // Zone is a structure that contains all data related to a DNS zone.
 | |
| type Zone struct {
 | |
| 	origin  string
 | |
| 	origLen int
 | |
| 	file    string
 | |
| 	*tree.Tree
 | |
| 	Apex
 | |
| 	Expired bool
 | |
| 
 | |
| 	sync.RWMutex
 | |
| 
 | |
| 	StartupOnce  sync.Once
 | |
| 	TransferFrom []string
 | |
| 
 | |
| 	ReloadInterval time.Duration
 | |
| 	reloadShutdown chan bool
 | |
| 
 | |
| 	Upstream *upstream.Upstream // Upstream for looking up external names during the resolution process.
 | |
| }
 | |
| 
 | |
| // Apex contains the apex records of a zone: SOA, NS and their potential signatures.
 | |
| type Apex struct {
 | |
| 	SOA    *dns.SOA
 | |
| 	NS     []dns.RR
 | |
| 	SIGSOA []dns.RR
 | |
| 	SIGNS  []dns.RR
 | |
| }
 | |
| 
 | |
| // NewZone returns a new zone.
 | |
| func NewZone(name, file string) *Zone {
 | |
| 	return &Zone{
 | |
| 		origin:         dns.Fqdn(name),
 | |
| 		origLen:        dns.CountLabel(dns.Fqdn(name)),
 | |
| 		file:           filepath.Clean(file),
 | |
| 		Tree:           &tree.Tree{},
 | |
| 		reloadShutdown: make(chan bool),
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Copy copies a zone.
 | |
| func (z *Zone) Copy() *Zone {
 | |
| 	z1 := NewZone(z.origin, z.file)
 | |
| 	z1.TransferFrom = z.TransferFrom
 | |
| 	z1.Expired = z.Expired
 | |
| 
 | |
| 	z1.Apex = z.Apex
 | |
| 	return z1
 | |
| }
 | |
| 
 | |
| // CopyWithoutApex copies zone z without the Apex records.
 | |
| func (z *Zone) CopyWithoutApex() *Zone {
 | |
| 	z1 := NewZone(z.origin, z.file)
 | |
| 	z1.TransferFrom = z.TransferFrom
 | |
| 	z1.Expired = z.Expired
 | |
| 
 | |
| 	return z1
 | |
| }
 | |
| 
 | |
| // Insert inserts r into z.
 | |
| func (z *Zone) Insert(r dns.RR) error {
 | |
| 	r.Header().Name = strings.ToLower(r.Header().Name)
 | |
| 
 | |
| 	switch h := r.Header().Rrtype; h {
 | |
| 	case dns.TypeNS:
 | |
| 		r.(*dns.NS).Ns = strings.ToLower(r.(*dns.NS).Ns)
 | |
| 
 | |
| 		if r.Header().Name == z.origin {
 | |
| 			z.Apex.NS = append(z.Apex.NS, r)
 | |
| 			return nil
 | |
| 		}
 | |
| 	case dns.TypeSOA:
 | |
| 		r.(*dns.SOA).Ns = strings.ToLower(r.(*dns.SOA).Ns)
 | |
| 		r.(*dns.SOA).Mbox = strings.ToLower(r.(*dns.SOA).Mbox)
 | |
| 
 | |
| 		z.Apex.SOA = r.(*dns.SOA)
 | |
| 		return nil
 | |
| 	case dns.TypeNSEC3, dns.TypeNSEC3PARAM:
 | |
| 		return fmt.Errorf("NSEC3 zone is not supported, dropping RR: %s for zone: %s", r.Header().Name, z.origin)
 | |
| 	case dns.TypeRRSIG:
 | |
| 		x := r.(*dns.RRSIG)
 | |
| 		switch x.TypeCovered {
 | |
| 		case dns.TypeSOA:
 | |
| 			z.Apex.SIGSOA = append(z.Apex.SIGSOA, x)
 | |
| 			return nil
 | |
| 		case dns.TypeNS:
 | |
| 			if r.Header().Name == z.origin {
 | |
| 				z.Apex.SIGNS = append(z.Apex.SIGNS, x)
 | |
| 				return nil
 | |
| 			}
 | |
| 		}
 | |
| 	case dns.TypeCNAME:
 | |
| 		r.(*dns.CNAME).Target = strings.ToLower(r.(*dns.CNAME).Target)
 | |
| 	case dns.TypeMX:
 | |
| 		r.(*dns.MX).Mx = strings.ToLower(r.(*dns.MX).Mx)
 | |
| 	case dns.TypeSRV:
 | |
| 		r.(*dns.SRV).Target = strings.ToLower(r.(*dns.SRV).Target)
 | |
| 	}
 | |
| 
 | |
| 	z.Tree.Insert(r)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // File retrieves the file path in a safe way.
 | |
| func (z *Zone) File() string {
 | |
| 	z.RLock()
 | |
| 	defer z.RUnlock()
 | |
| 	return z.file
 | |
| }
 | |
| 
 | |
| // SetFile updates the file path in a safe way.
 | |
| func (z *Zone) SetFile(path string) {
 | |
| 	z.Lock()
 | |
| 	z.file = path
 | |
| 	z.Unlock()
 | |
| }
 | |
| 
 | |
| // ApexIfDefined returns the apex nodes from z. The SOA record is the first record, if it does not exist, an error is returned.
 | |
| func (z *Zone) ApexIfDefined() ([]dns.RR, error) {
 | |
| 	z.RLock()
 | |
| 	defer z.RUnlock()
 | |
| 	if z.Apex.SOA == nil {
 | |
| 		return nil, fmt.Errorf("no SOA")
 | |
| 	}
 | |
| 
 | |
| 	rrs := []dns.RR{z.Apex.SOA}
 | |
| 
 | |
| 	if len(z.Apex.SIGSOA) > 0 {
 | |
| 		rrs = append(rrs, z.Apex.SIGSOA...)
 | |
| 	}
 | |
| 	if len(z.Apex.NS) > 0 {
 | |
| 		rrs = append(rrs, z.Apex.NS...)
 | |
| 	}
 | |
| 	if len(z.Apex.SIGNS) > 0 {
 | |
| 		rrs = append(rrs, z.Apex.SIGNS...)
 | |
| 	}
 | |
| 
 | |
| 	return rrs, nil
 | |
| }
 | |
| 
 | |
| // NameFromRight returns the labels from the right, staring with the
 | |
| // origin and then i labels extra. When we are overshooting the name
 | |
| // the returned boolean is set to true.
 | |
| func (z *Zone) nameFromRight(qname string, i int) (string, bool) {
 | |
| 	if i <= 0 {
 | |
| 		return z.origin, false
 | |
| 	}
 | |
| 
 | |
| 	for j := 1; j <= z.origLen; j++ {
 | |
| 		if _, shot := dns.PrevLabel(qname, j); shot {
 | |
| 			return qname, shot
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	k := 0
 | |
| 	var shot bool
 | |
| 	for j := 1; j <= i; j++ {
 | |
| 		k, shot = dns.PrevLabel(qname, j+z.origLen)
 | |
| 		if shot {
 | |
| 			return qname, shot
 | |
| 		}
 | |
| 	}
 | |
| 	return qname[k:], false
 | |
| }
 |