// Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved. package models import ( "github.com/TeaOSLab/EdgeCommon/pkg/dnsconfigs" "github.com/iwind/TeaGo/types" "github.com/miekg/dns" "net" "strings" ) type NSRecord struct { Id int64 Name string Type dnsconfigs.RecordType Value string MXPriority int32 SRVPriority int32 SRVWeight int32 SRVPort int32 CAAFlag int32 CAATag string Ttl int32 Weight int32 Version int64 RouteIds []string DomainId int64 } func (this *NSRecord) ToRRAnswer(questionName string, rrClass uint16) dns.RR { if this.Ttl <= 0 { this.Ttl = 60 } switch this.Type { case dnsconfigs.RecordTypeA: return &dns.A{ Hdr: this.ToRRHeader(questionName, dns.TypeA, rrClass), A: net.ParseIP(this.Value), } case dnsconfigs.RecordTypeCNAME: var value = this.Value if !strings.HasSuffix(value, ".") { value += "." } return &dns.CNAME{ Hdr: this.ToRRHeader(questionName, dns.TypeCNAME, rrClass), Target: value, } case dnsconfigs.RecordTypeAAAA: return &dns.AAAA{ Hdr: this.ToRRHeader(questionName, dns.TypeAAAA, rrClass), AAAA: net.ParseIP(this.Value), } case dnsconfigs.RecordTypeNS: var value = this.Value if !strings.HasSuffix(value, ".") { value += "." } return &dns.NS{ Hdr: this.ToRRHeader(questionName, dns.TypeNS, rrClass), Ns: value, } case dnsconfigs.RecordTypeMX: var value = this.Value if !strings.HasSuffix(value, ".") { value += "." } var preference uint16 = 0 var priority = this.MXPriority if priority >= 0 { if priority > 65535 { priority = 65535 } preference = types.Uint16(priority) } return &dns.MX{ Hdr: this.ToRRHeader(questionName, dns.TypeMX, rrClass), Preference: preference, Mx: value, } case dnsconfigs.RecordTypeSRV: var priority uint16 = 10 if this.SRVPriority > 0 { priority = uint16(this.SRVPriority) } var weight uint16 = 10 if this.SRVWeight > 0 { weight = uint16(this.SRVWeight) } var port uint16 = 0 if this.SRVPort > 0 { port = uint16(this.SRVPort) } var value = this.Value if !strings.HasSuffix(value, ".") { value += "." } return &dns.SRV{ Hdr: this.ToRRHeader(questionName, dns.TypeSRV, rrClass), Priority: priority, Weight: weight, Port: port, Target: value, } case dnsconfigs.RecordTypeTXT: var values []string var runes = []rune(this.Value) const maxChars = 255 for { if len(runes) <= maxChars { values = append(values, string(runes)) break } values = append(values, string(runes[:maxChars])) runes = runes[maxChars:] if len(runes) == 0 { break } } return &dns.TXT{ Hdr: this.ToRRHeader(questionName, dns.TypeTXT, rrClass), Txt: values, // TODO 可以添加多个 } case dnsconfigs.RecordTypeCAA: var flag uint8 = 0 if this.CAAFlag >= 0 && this.CAAFlag <= 128 { flag = uint8(this.CAAFlag) } var tag = this.CAATag if tag != "issue" && tag != "issuewild" && tag != "iodef" { tag = "issue" } return &dns.CAA{ Hdr: this.ToRRHeader(questionName, dns.TypeCAA, rrClass), Flag: flag, // 0-128 Tag: tag, // issue|issuewild|iodef Value: this.Value, } } return nil } func (this *NSRecord) ToRRHeader(questionName string, rrType uint16, rrClass uint16) dns.RR_Header { return dns.RR_Header{ Name: questionName, Rrtype: rrType, Class: rrClass, Ttl: uint32(this.Ttl), } }