func (zone *ZoneFile) Messages() []*Message {
	return zone.messages
}
Messages return all pre-generated DNS messages.
package dns
import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	libio "github.com/shuLhan/share/lib/io"
)
type ZoneFile struct {
	Path     string `json:"-"`
	Name     string
	SOA      ResourceRecord
	Records  zoneRecords
	messages []*Message
}
func NewZoneFile(file, name string) *ZoneFile {
	return &ZoneFile{
		Path: file,
		Name: name,
		SOA: ResourceRecord{
			Type: QueryTypeSOA,
			Value: &RDataSOA{
				MName: name,
			},
		},
		Records: make(zoneRecords),
	}
}
func LoadZoneDir(dir string) (zoneFiles map[string]*ZoneFile, err error) {
	if len(dir) == 0 {
		return nil, nil
	}
	d, err := os.Open(dir)
	if err != nil {
		return nil, fmt.Errorf("LoadZoneDir: %w", err)
	}
	fis, err := d.Readdir(0)
	if err != nil {
		err = d.Close()
		if err != nil {
			return nil, fmt.Errorf("LoadZoneDir: %w", err)
		}
		return nil, fmt.Errorf("LoadZoneDir: %w", err)
	}
	zoneFiles = make(map[string]*ZoneFile)
	for x := 0; x < len(fis); x++ {
		if fis[x].IsDir() {
			continue
		}
		name := fis[x].Name()
		if name[0] == '.' {
			continue
		}
		zoneFilePath := filepath.Join(dir, name)
		zoneFile, err := ParseZoneFile(zoneFilePath, "", 0)
		if err != nil {
			return zoneFiles, fmt.Errorf("LoadZoneDir %q: %w", dir, err)
		}
		zoneFiles[name] = zoneFile
	}
	err = d.Close()
	if err != nil {
		return zoneFiles, fmt.Errorf(" LoadZoneDir %q: %w", dir, err)
	}
	return zoneFiles, nil
}
func ParseZoneFile(file, origin string, ttl uint32) (*ZoneFile, error) {
	var err error
	m := newZoneParser(file)
	m.ttl = ttl
	if len(origin) > 0 {
		m.origin = origin
	} else {
		m.origin = filepath.Base(file)
	}
	m.origin = strings.ToLower(m.origin)
	m.reader, err = libio.NewReader(file)
	if err != nil {
		return nil, fmt.Errorf("ParseZoneFile %q: %w", file, err)
	}
	err = m.parse()
	if err != nil {
		return nil, fmt.Errorf("ParseZoneFile %q: %w", file, err)
	}
	m.zone.Name = m.origin
	zone := m.zone
	m.zone = nil
	return zone, nil
}
func (zone *ZoneFile) Add(rr *ResourceRecord) (err error) {
	if rr.Type == QueryTypeSOA {
		zone.SOA = *rr
	} else {
		zone.Records.add(rr)
	}
	for _, msg := range zone.messages {
		if msg.Question.Name != rr.Name {
			continue
		}
		if msg.Question.Type != rr.Type {
			continue
		}
		if msg.Question.Class != rr.Class {
			continue
		}
		return msg.AddAnswer(rr)
	}
	msg := &Message{
		Header: SectionHeader{
			IsAA:    true,
			QDCount: 1,
			ANCount: 1,
		},
		Question: SectionQuestion{
			Name:  rr.Name,
			Type:  rr.Type,
			Class: rr.Class,
		},
		Answer: []ResourceRecord{*rr},
	}
	zone.messages = append(zone.messages, msg)
	return nil
}
func (zone *ZoneFile) Delete() (err error) {
	return os.Remove(zone.Path)
}