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 ) {
2025-01-10 23:43:16 +08:00
//fmt.Printf("DEBUG: RRtoRC(%v, %q)\n", rr, origin)
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 ( )
2025-01-10 23:43:16 +08:00
rc := & RecordConfig {
Type : dns . TypeToString [ header . Rrtype ] ,
TTL : header . Ttl ,
Original : rr ,
}
//fmt.Printf("DEBUG: header.Name=%q origin=%q\n", header.Name, origin)
//rc.SetLabelFromFQDN(strings.TrimSuffix(header.Name, "."), origin)
//fmt.Printf("DEBUG: RRtoRC(%q, %q)\n", rc.Name, rc.NameFQDN)
//fmt.Printf("DEBUG: name=%q nameFQDN=%q\n", rc.Name, rc.NameFQDN)
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 :
2025-01-10 23:43:16 +08:00
err = rc . SetTargetA ( 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 )
2024-05-01 23:37:15 +08:00
case * dns . HTTPS :
err = rc . SetTargetSVCB ( v . Priority , v . Target , v . Value )
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 )
2024-05-01 23:37:15 +08:00
case * dns . SVCB :
err = rc . SetTargetSVCB ( v . Priority , v . Target , v . Value )
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
}
2025-01-10 23:43:16 +08:00
// Must be done after any .SetTarget*(*) calls since they may clear the .NameFQDN field.
rc . SetLabelFromFQDN ( header . Name , origin )
//fmt.Printf("DEBUG: end RRtoRC(%q, %q)\n", rc.Name, rc.NameFQDN)
2021-07-06 23:03:29 +08:00
return * rc , nil
2020-02-18 21:59:18 +08:00
}