2020-02-18 21:59:18 +08:00
package models
// methods that make RecordConfig meet the dns.RR interface.
import (
"fmt"
"strings"
"github.com/miekg/dns"
)
// String returns the text representation of the resource record.
func ( rc * RecordConfig ) String ( ) string {
return rc . GetTargetCombined ( )
}
// Conversions
// RRtoRC converts dns.RR to RecordConfig
2021-07-06 23:03:29 +08:00
func RRtoRC ( rr dns . RR , origin string ) ( RecordConfig , error ) {
2023-12-05 06:45:25 +08:00
return helperRRtoRC ( rr , origin , false )
}
// RRtoRCTxtBug converts dns.RR to RecordConfig. Compensates for the backslash bug in github.com/miekg/dns/issues/1384.
func RRtoRCTxtBug ( rr dns . RR , origin string ) ( RecordConfig , error ) {
return helperRRtoRC ( rr , origin , true )
}
// helperRRtoRC converts dns.RR to RecordConfig. If fixBug is true, replaces `\\` to `\` in TXT records to compensate for github.com/miekg/dns/issues/1384.
func helperRRtoRC ( rr dns . RR , origin string , fixBug bool ) ( RecordConfig , error ) {
2020-02-18 21:59:18 +08:00
// Convert's dns.RR into our native data type (RecordConfig).
// Records are translated directly with no changes.
header := rr . Header ( )
rc := new ( RecordConfig )
rc . Type = dns . TypeToString [ header . Rrtype ]
rc . TTL = header . Ttl
rc . Original = rr
rc . SetLabelFromFQDN ( strings . TrimSuffix ( header . Name , "." ) , origin )
2021-07-06 23:03:29 +08:00
var err error
2020-02-18 21:59:18 +08:00
switch v := rr . ( type ) { // #rtype_variations
case * dns . A :
2021-07-06 23:03:29 +08:00
err = rc . SetTarget ( v . A . String ( ) )
2020-02-18 21:59:18 +08:00
case * dns . AAAA :
2021-07-06 23:03:29 +08:00
err = rc . SetTarget ( v . AAAA . String ( ) )
2020-02-18 21:59:18 +08:00
case * dns . CAA :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetCAA ( v . Flag , v . Tag , v . Value )
2020-02-18 21:59:18 +08:00
case * dns . CNAME :
2021-07-06 23:03:29 +08:00
err = rc . SetTarget ( v . Target )
2023-08-22 17:09:50 +08:00
case * dns . DHCID :
err = rc . SetTarget ( v . Digest )
2024-04-03 02:28:57 +08:00
case * dns . DNAME :
err = rc . SetTarget ( v . Target )
2020-05-30 22:40:21 +08:00
case * dns . DS :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetDS ( v . KeyTag , v . Algorithm , v . DigestType , v . Digest )
2024-04-22 21:54:12 +08:00
case * dns . DNSKEY :
err = rc . SetTargetDNSKEY ( v . Flags , v . Protocol , v . Algorithm , v . PublicKey )
2023-03-17 02:04:20 +08:00
case * dns . LOC :
err = rc . SetTargetLOC ( v . Version , v . Latitude , v . Longitude , v . Altitude , v . Size , v . HorizPre , v . VertPre )
2020-02-18 21:59:18 +08:00
case * dns . MX :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetMX ( v . Preference , v . Mx )
2023-03-29 07:30:01 +08:00
case * dns . NAPTR :
err = rc . SetTargetNAPTR ( v . Order , v . Preference , v . Flags , v . Service , v . Regexp , v . Replacement )
2020-02-18 21:59:18 +08:00
case * dns . NS :
2021-07-06 23:03:29 +08:00
err = rc . SetTarget ( v . Ns )
2020-02-18 21:59:18 +08:00
case * dns . PTR :
2021-07-06 23:03:29 +08:00
err = rc . SetTarget ( v . Ptr )
2020-02-18 21:59:18 +08:00
case * dns . SOA :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetSOA ( v . Ns , v . Mbox , v . Serial , v . Refresh , v . Retry , v . Expire , v . Minttl )
2020-02-18 21:59:18 +08:00
case * dns . SRV :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetSRV ( v . Priority , v . Weight , v . Port , v . Target )
2020-02-18 21:59:18 +08:00
case * dns . SSHFP :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetSSHFP ( v . Algorithm , v . Type , v . FingerPrint )
2020-02-18 21:59:18 +08:00
case * dns . TLSA :
2021-07-06 23:03:29 +08:00
err = rc . SetTargetTLSA ( v . Usage , v . Selector , v . MatchingType , v . Certificate )
2020-02-18 21:59:18 +08:00
case * dns . TXT :
2023-12-05 06:45:25 +08:00
if fixBug {
t := strings . Join ( v . Txt , "" )
te := t
te = strings . ReplaceAll ( te , ` \\ ` , ` \ ` )
te = strings . ReplaceAll ( te , ` \" ` , ` " ` )
err = rc . SetTargetTXT ( te )
} else {
err = rc . SetTargetTXTs ( v . Txt )
}
2020-02-18 21:59:18 +08:00
default :
2021-12-14 22:47:32 +08:00
return * rc , fmt . Errorf ( "rrToRecord: Unimplemented zone record type=%s (%v)" , rc . Type , rr )
2020-02-18 21:59:18 +08:00
}
if err != nil {
2021-07-06 23:03:29 +08:00
return * rc , fmt . Errorf ( "unparsable record received: %w" , err )
2020-02-18 21:59:18 +08:00
}
2021-07-06 23:03:29 +08:00
return * rc , nil
2020-02-18 21:59:18 +08:00
}