NEW RECORD TYPE: HTTPS & SVCB (#2919)

Thanks so much for this contribution!  I have a feeling that a lot of people are going to need these records soon!
This commit is contained in:
Florian Ritterhoff 2024-05-01 17:37:15 +02:00 committed by GitHub
parent eae96860cd
commit 3a9b413175
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 297 additions and 17 deletions

View file

@ -80,12 +80,14 @@ func matrixData() *FeatureMatrix {
DomainModifierAlias = "[`ALIAS`](language-reference/domain-modifiers/ALIAS.md)"
DomainModifierCaa = "[`CAA`](language-reference/domain-modifiers/CAA.md)"
DomainModifierDnssec = "[`AUTODNSSEC`](language-reference/domain-modifiers/AUTODNSSEC_ON.md)"
DomainModifierHttps = "[`HTTPS`](language-reference/domain-modifiers/HTTPS.md)"
DomainModifierLoc = "[`LOC`](language-reference/domain-modifiers/LOC.md)"
DomainModifierNaptr = "[`NAPTR`](language-reference/domain-modifiers/NAPTR.md)"
DomainModifierPtr = "[`PTR`](language-reference/domain-modifiers/PTR.md)"
DomainModifierSoa = "[`SOA`](language-reference/domain-modifiers/SOA.md)"
DomainModifierSrv = "[`SRV`](language-reference/domain-modifiers/SRV.md)"
DomainModifierSshfp = "[`SSHFP`](language-reference/domain-modifiers/SSHFP.md)"
DomainModifierSvcb = "[`SVCB`](language-reference/domain-modifiers/SVCB.md)"
DomainModifierTlsa = "[`TLSA`](language-reference/domain-modifiers/TLSA.md)"
DomainModifierDs = "[`DS`](language-reference/domain-modifiers/DS.md)"
DomainModifierDhcid = "[`DHCID`](language-reference/domain-modifiers/DHCID.md)"
@ -106,12 +108,14 @@ func matrixData() *FeatureMatrix {
DomainModifierAlias,
DomainModifierCaa,
DomainModifierDnssec,
DomainModifierHttps,
DomainModifierLoc,
DomainModifierNaptr,
DomainModifierPtr,
DomainModifierSoa,
DomainModifierSrv,
DomainModifierSshfp,
DomainModifierSvcb,
DomainModifierTlsa,
DomainModifierDs,
DomainModifierDhcid,
@ -207,6 +211,10 @@ func matrixData() *FeatureMatrix {
DomainModifierDnskey,
providers.CanUseDNSKEY,
)
setCapability(
DomainModifierHttps,
providers.CanUseHTTPS,
)
setCapability(
DomainModifierLoc,
providers.CanUseLOC,
@ -231,6 +239,10 @@ func matrixData() *FeatureMatrix {
DomainModifierSshfp,
providers.CanUseSSHFP,
)
setCapability(
DomainModifierSvcb,
providers.CanUseSVCB,
)
setCapability(
DomainModifierTlsa,
providers.CanUseTLSA,

View file

@ -357,6 +357,8 @@ func formatDsl(rec *models.RecordConfig, defaultTTL uint32) string {
target = fmt.Sprintf(`"%s", "%s", %d, %d, %d, %d, %d`, rec.GetTargetField(), rec.SoaMbox, rec.SoaSerial, rec.SoaRefresh, rec.SoaRetry, rec.SoaExpire, rec.SoaMinttl)
case "SRV":
target = fmt.Sprintf(`%d, %d, %d, "%s"`, rec.SrvPriority, rec.SrvWeight, rec.SrvPort, rec.GetTargetField())
case "SVCB", "HTTPS":
target = fmt.Sprintf(`%d, "%s", "%s"`, rec.SvcPriority, rec.GetTargetField(), rec.SvcParams)
case "TLSA":
target = fmt.Sprintf(`%d, %d, %d, "%s"`, rec.TlsaUsage, rec.TlsaSelector, rec.TlsaMatchingType, rec.GetTargetField())
case "TXT":

View file

@ -46,6 +46,7 @@
* [DefaultTTL](language-reference/domain-modifiers/DefaultTTL.md)
* [DnsProvider](language-reference/domain-modifiers/DnsProvider.md)
* [FRAME](language-reference/domain-modifiers/FRAME.md)
* [HTTPS](language-reference/domain-modifiers/HTTPS.md)
* [IGNORE](language-reference/domain-modifiers/IGNORE.md)
* [IGNORE_NAME](language-reference/domain-modifiers/IGNORE_NAME.md)
* [IGNORE_TARGET](language-reference/domain-modifiers/IGNORE_TARGET.md)
@ -69,6 +70,7 @@
* [SPF_BUILDER](language-reference/domain-modifiers/SPF_BUILDER.md)
* [SRV](language-reference/domain-modifiers/SRV.md)
* [SSHFP](language-reference/domain-modifiers/SSHFP.md)
* [SVCB](language-reference/domain-modifiers/SVCB.md)
* [TLSA](language-reference/domain-modifiers/TLSA.md)
* [TXT](language-reference/domain-modifiers/TXT.md)
* [URL](language-reference/domain-modifiers/URL.md)

View file

@ -0,0 +1,32 @@
---
name: HTTPS
parameters:
- name
- priority
- target
- params
- modifiers...
parameter_types:
name: string
priority: number
target: string
params: string
"modifiers...": RecordModifier[]
---
HTTPS adds an HTTPS record to a domain. The name should be the relative label for the record. Use `@` for the domain apex. The HTTPS record is a special form of the SVCB resource record.
The priority must be a positive number, the address should be an ip address, either a string, or a numeric value obtained via [IP](../top-level-functions/IP.md).
The params may be configured to specify the `alpn`, `ipv4hint`, `ipv6hint`, `ech` or `port` setting. Several params may be joined by a space. Not existing params may be specified as an empty string `""`
Modifiers can be any number of [record modifiers](https://docs.dnscontrol.org/language-reference/record-modifiers) or JSON objects, which will be merged into the record's metadata.
{% code title="dnsconfig.js" %}
```javascript
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
HTTPS("@", 1, ".", "ipv4hint=123.123.123.123 alpn=h3,h2 port=443"),
HTTPS("@", 1, "test.com", "")
);
```
{% endcode %}

View file

@ -0,0 +1,31 @@
---
name: SVCB
parameters:
- name
- priority
- target
- params
- modifiers...
parameter_types:
name: string
priority: number
target: string
params: string
"modifiers...": RecordModifier[]
---
SVCB adds an SVCB record to a domain. The name should be the relative label for the record. Use `@` for the domain apex.
The priority must be a positive number, the address should be an ip address, either a string, or a numeric value obtained via [IP](../top-level-functions/IP.md).
The params may be configured to specify the `alpn`, `ipv4hint`, `ipv6hint`, `ech` or `port` setting. Several params may be joined by a space. Not existing params may be specified as an empty string `""`
Modifiers can be any number of [record modifiers](https://docs.dnscontrol.org/language-reference/record-modifiers) or JSON objects, which will be merged into the record's metadata.
{% code title="dnsconfig.js" %}
```javascript
D("example.com", REG_MY_PROVIDER, DnsProvider(DSP_MY_PROVIDER),
SVCB("@", 1, ".", "ipv4hint=123.123.123.123 alpn=h3,h2 port=443")
);
```
{% endcode %}

View file

@ -528,6 +528,13 @@ func dnskey(name string, flags uint16, protocol, algorithm uint8, publicKey stri
return r
}
func https(name string, priority uint16, target string, params string) *models.RecordConfig {
r := makeRec(name, target, "HTTPS")
r.SvcPriority = priority
r.SvcParams = params
return r
}
func ignoreName(labelSpec string) *models.RecordConfig {
return ignore(labelSpec, "*", "*")
}
@ -620,6 +627,13 @@ func sshfp(name string, algorithm uint8, fingerprint uint8, target string) *mode
return r
}
func svcb(name string, priority uint16, target string, params string) *models.RecordConfig {
r := makeRec(name, target, "SVCB")
r.SvcPriority = priority
r.SvcParams = params
return r
}
func ovhdkim(name, target string) *models.RecordConfig {
return makeOvhNativeRecord(name, target, "DKIM")
}
@ -1016,6 +1030,23 @@ func makeTests() []*TestGroup {
tc("Change back to CNAME", cname("foo", "google2.com.")),
),
testgroup("HTTPS",
tc("Create a HTTPS record", https("@", 1, "test.com.", "port=80")),
tc("Change HTTPS priority", https("@", 2, "test.com.", "port=80")),
tc("Change HTTPS target", https("@", 2, ".", "port=80")),
tc("Change HTTPS params", https("@", 2, ".", "port=99")),
tc("Change HTTPS params-empty", https("@", 2, ".", "")),
tc("Change HTTPS all", https("@", 3, "example.com.", "port=100")),
),
testgroup("SVCB",
tc("Create a HTTPS record", https("@", 1, "test.com.", "port=80")),
tc("Change HTTPS priority", https("@", 2, "test.com.", "port=80")),
tc("Change HTTPS target", https("@", 2, ".", "port=80")),
tc("Change HTTPS params", https("@", 2, ".", "port=99")),
tc("Change HTTPS params-empty", https("@", 2, ".", "")),
tc("Change HTTPS all", https("@", 3, "example.com.", "port=100")),
),
//// Test edge cases from various types.
// Narrative: Every DNS record type has some weird edge-case that

View file

@ -54,6 +54,8 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (RecordConfig, error) {
err = rc.SetTargetDS(v.KeyTag, v.Algorithm, v.DigestType, v.Digest)
case *dns.DNSKEY:
err = rc.SetTargetDNSKEY(v.Flags, v.Protocol, v.Algorithm, v.PublicKey)
case *dns.HTTPS:
err = rc.SetTargetSVCB(v.Priority, v.Target, v.Value)
case *dns.LOC:
err = rc.SetTargetLOC(v.Version, v.Latitude, v.Longitude, v.Altitude, v.Size, v.HorizPre, v.VertPre)
case *dns.MX:
@ -70,6 +72,8 @@ func helperRRtoRC(rr dns.RR, origin string, fixBug bool) (RecordConfig, error) {
err = rc.SetTargetSRV(v.Priority, v.Weight, v.Port, v.Target)
case *dns.SSHFP:
err = rc.SetTargetSSHFP(v.Algorithm, v.Type, v.FingerPrint)
case *dns.SVCB:
err = rc.SetTargetSVCB(v.Priority, v.Target, v.Value)
case *dns.TLSA:
err = rc.SetTargetTLSA(v.Usage, v.Selector, v.MatchingType, v.Certificate)
case *dns.TXT:

View file

@ -141,7 +141,7 @@ func (dc *DomainConfig) Punycode() error {
rec.SetTarget(t)
case "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE":
rec.SetTarget(rec.GetTargetField())
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "LOC", "NAPTR", "SOA", "SSHFP", "TXT", "TLSA", "AZURE_ALIAS":
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS":
// Nothing to do.
default:
return fmt.Errorf("Punycode rtype %v unimplemented", rec.Type)

View file

@ -22,6 +22,7 @@ import (
// ANAME // Technically not an official rtype yet.
// CAA
// CNAME
// HTTPS
// LOC
// MX
// NAPTR
@ -30,6 +31,7 @@ import (
// SOA
// SRV
// SSHFP
// SVCB
// TLSA
// TXT
// Pseudo-Types: (alphabetical)
@ -128,6 +130,8 @@ type RecordConfig struct {
SoaRetry uint32 `json:"soaretry,omitempty"`
SoaExpire uint32 `json:"soaexpire,omitempty"`
SoaMinttl uint32 `json:"soaminttl,omitempty"`
SvcPriority uint16 `json:"svcpriority,omitempty"`
SvcParams string `json:"svcparams,omitempty"`
TlsaUsage uint8 `json:"tlsausage,omitempty"`
TlsaSelector uint8 `json:"tlsaselector,omitempty"`
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
@ -200,6 +204,8 @@ func (rc *RecordConfig) UnmarshalJSON(b []byte) error {
SoaRetry uint32 `json:"soaretry,omitempty"`
SoaExpire uint32 `json:"soaexpire,omitempty"`
SoaMinttl uint32 `json:"soaminttl,omitempty"`
SvcPriority uint16 `json:"svcpriority,omitempty"`
SvcParams string `json:"svcparams,omitempty"`
TlsaUsage uint8 `json:"tlsausage,omitempty"`
TlsaSelector uint8 `json:"tlsaselector,omitempty"`
TlsaMatchingType uint8 `json:"tlsamatchingtype,omitempty"`
@ -381,6 +387,10 @@ func (rc *RecordConfig) ToRR() dns.RR {
rr.(*dns.DNSKEY).Protocol = rc.DnskeyProtocol
rr.(*dns.DNSKEY).Algorithm = rc.DnskeyAlgorithm
rr.(*dns.DNSKEY).PublicKey = rc.DnskeyPublicKey
case dns.TypeHTTPS:
rr.(*dns.HTTPS).Priority = rc.SvcPriority
rr.(*dns.HTTPS).Target = rc.GetTargetField()
rr.(*dns.HTTPS).Value = rc.GetSVCBValue()
case dns.TypeLOC:
// fmt.Printf("ToRR long: %d, lat:%d, sz: %d, hz:%d, vt:%d\n", rc.LocLongitude, rc.LocLatitude, rc.LocSize, rc.LocHorizPre, rc.LocVertPre)
// fmt.Printf("ToRR rc: %+v\n", *rc)
@ -424,6 +434,10 @@ func (rc *RecordConfig) ToRR() dns.RR {
rr.(*dns.SSHFP).Algorithm = rc.SshfpAlgorithm
rr.(*dns.SSHFP).Type = rc.SshfpFingerprint
rr.(*dns.SSHFP).FingerPrint = rc.GetTargetField()
case dns.TypeSVCB:
rr.(*dns.SVCB).Priority = rc.SvcPriority
rr.(*dns.SVCB).Target = rc.GetTargetField()
rr.(*dns.SVCB).Value = rc.GetSVCBValue()
case dns.TypeTLSA:
rr.(*dns.TLSA).Usage = rc.TlsaUsage
rr.(*dns.TLSA).MatchingType = rc.TlsaMatchingType
@ -483,6 +497,20 @@ func (rc *RecordConfig) Key() RecordKey {
return RecordKey{rc.NameFQDN, t}
}
func (rc *RecordConfig) GetSVCBValue() []dns.SVCBKeyValue {
record, err := dns.NewRR(fmt.Sprintf("%s %s %d %s %s", rc.NameFQDN, rc.Type, rc.SvcPriority, rc.target, rc.SvcParams))
if err != nil {
log.Fatalf("could not parse SVCB record: %s", err)
}
switch r := record.(type) {
case *dns.HTTPS:
return r.Value
case *dns.SVCB:
return r.Value
}
return nil
}
// Records is a list of *RecordConfig.
type Records []*RecordConfig
@ -580,7 +608,7 @@ func CanonicalizeTargets(recs []*RecordConfig, origin string) {
case "ALIAS", "ANAME", "CNAME", "DNAME", "DS", "DNSKEY", "MX", "NS", "NAPTR", "PTR", "SRV":
// Target is a hostname that might be a shortname. Turn it into a FQDN.
r.target = dnsutil.AddOrigin(r.target, originFQDN)
case "A", "AKAMAICDN", "CAA", "DHCID", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "IMPORT_TRANSFORM", "LOC", "SSHFP", "TLSA", "TXT":
case "A", "AKAMAICDN", "CAA", "DHCID", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE", "HTTPS", "IMPORT_TRANSFORM", "LOC", "SSHFP", "SVCB", "TLSA", "TXT":
// Do nothing.
case "SOA":
if r.target != "DEFAULT_NOT_SET." {

View file

@ -105,6 +105,8 @@ func (rc *RecordConfig) PopulateFromStringFunc(rtype, contents, origin string, t
return rc.SetTargetSRVString(contents)
case "SSHFP":
return rc.SetTargetSSHFPString(contents)
case "SVCB", "HTTPS":
return rc.SetTargetSVCBString(origin, contents)
case "TLSA":
return rc.SetTargetTLSAString(contents)
default:

44
models/t_svcb.go Normal file
View file

@ -0,0 +1,44 @@
package models
import (
"fmt"
"strings"
"github.com/miekg/dns"
)
// SetTargetSVCB sets the SVCB fields.
func (rc *RecordConfig) SetTargetSVCB(priority uint16, target string, params []dns.SVCBKeyValue) error {
rc.SvcPriority = priority
rc.SetTarget(target)
paramsStr := []string{}
for _, kv := range params {
paramsStr = append(paramsStr, fmt.Sprintf("%s=%s", kv.Key(), kv.String()))
}
rc.SvcParams = strings.Join(paramsStr, " ")
if rc.Type == "" {
rc.Type = "SVCB"
}
if rc.Type != "SVCB" && rc.Type != "HTTPS" {
panic("assertion failed: SetTargetSVCB called when .Type is not SVCB or HTTPS")
}
return nil
}
// SetTargetSVCBString is like SetTargetSVCB but accepts one big string and the origin so parsing can be done using miekg/dns.
func (rc *RecordConfig) SetTargetSVCBString(origin, contents string) error {
if rc.Type == "" {
rc.Type = "SVCB"
}
record, err := dns.NewRR(fmt.Sprintf("%s. %s %s", origin, rc.Type, contents))
if err != nil {
return fmt.Errorf("could not parse SVCB record: %s", err)
}
switch r := record.(type) {
case *dns.HTTPS:
return rc.SetTargetSVCB(r.Priority, r.Target, r.Value)
case *dns.SVCB:
return rc.SetTargetSVCB(r.Priority, r.Target, r.Value)
}
return nil
}

View file

@ -131,6 +131,9 @@ func (rc *RecordConfig) GetTargetDebug() string {
content += fmt.Sprintf(" srvpriority=%d srvweight=%d srvport=%d", rc.SrvPriority, rc.SrvWeight, rc.SrvPort)
case "SSHFP":
content += fmt.Sprintf(" sshfpalgorithm=%d sshfpfingerprint=%d", rc.SshfpAlgorithm, rc.SshfpFingerprint)
case "SVCB", "HTTPS":
// HTTPS is only a special subform of the SVCB Record
content += fmt.Sprintf(" priority=%d params=%v", rc.SvcPriority, rc.SvcParams)
case "TLSA":
content += fmt.Sprintf(" tlsausage=%d tlsaselector=%d tlsamatchingtype=%d", rc.TlsaUsage, rc.TlsaSelector, rc.TlsaMatchingType)
default:

View file

@ -449,6 +449,22 @@ var DNSKEY = recordBuilder('DNSKEY', {
},
});
// name, priority, target, params
var HTTPS = recordBuilder('HTTPS', {
args: [
['name', _.isString],
['priority', _.isNumber],
['target', _.isString],
['params', _.isString],
],
transform: function (record, args, modifiers) {
record.name = args.name;
record.svcpriority = args.priority;
record.target = args.target;
record.svcparams = args.params;
},
});
// PTR(name,target, recordModifiers...)
var PTR = recordBuilder('PTR');
@ -530,6 +546,22 @@ var SSHFP = recordBuilder('SSHFP', {
},
});
// name, priority, target, params
var SVCB = recordBuilder('SVCB', {
args: [
['name', _.isString],
['priority', _.isNumber],
['target', _.isString],
['params', _.isString],
],
transform: function (record, args, modifiers) {
record.name = args.name;
record.svcpriority = args.priority;
record.target = args.target;
record.svcparams = args.params;
},
});
// name, usage, selector, matchingtype, certificate
var TLSA = recordBuilder('TLSA', {
args: [

View file

@ -0,0 +1,4 @@
D("foo.com","none",
SVCB("@", 1, ".", ""),
HTTPS("@", 2, ".", 'alpn="h3,h2" port=443 ipv4hint=123.123.123.123 ipv6hint=dead::beaf')
);

View file

@ -0,0 +1,27 @@
{
"registrars": [],
"dns_providers": [],
"domains": [
{
"name": "foo.com",
"registrar": "none",
"dnsProviders": {},
"records": [
{
"type": "SVCB",
"name": "@",
"target": ".",
"svcpriority": 1
},
{
"type": "HTTPS",
"name": "@",
"svcparams": "alpn=\"h3,h2\" port=443 ipv4hint=123.123.123.123 ipv6hint=dead::beaf",
"svcpriority": 2,
"target": "."
}
]
}
]
}

View file

@ -63,6 +63,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
"DNAME": true,
"DS": true,
"DNSKEY": true,
"HTTPS": true,
"IMPORT_TRANSFORM": false,
"LOC": true,
"MX": true,
@ -72,6 +73,7 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
"SOA": true,
"SRV": true,
"SSHFP": true,
"SVCB": true,
"TLSA": true,
"TXT": true,
}
@ -224,7 +226,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
}
case "SRV":
check(checkTarget(target))
case "CAA", "DHCID", "DNSKEY", "DS", "IMPORT_TRANSFORM", "SSHFP", "TLSA", "TXT":
case "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "IMPORT_TRANSFORM", "SSHFP", "SVCB", "TLSA", "TXT":
default:
if rec.Metadata["orig_custom_type"] != "" {
// it is a valid custom type. We perform no validation on target
@ -685,6 +687,7 @@ var providerCapabilityChecks = []pairTypeCapability{
capabilityCheck("DHCID", providers.CanUseDHCID),
capabilityCheck("DNAME", providers.CanUseDNAME),
capabilityCheck("DNSKEY", providers.CanUseDNSKEY),
capabilityCheck("HTTPS", providers.CanUseHTTPS),
capabilityCheck("LOC", providers.CanUseLOC),
capabilityCheck("NAPTR", providers.CanUseNAPTR),
capabilityCheck("PTR", providers.CanUsePTR),
@ -692,6 +695,7 @@ var providerCapabilityChecks = []pairTypeCapability{
capabilityCheck("SOA", providers.CanUseSOA),
capabilityCheck("SRV", providers.CanUseSRV),
capabilityCheck("SSHFP", providers.CanUseSSHFP),
capabilityCheck("SVCB", providers.CanUseSVCB),
capabilityCheck("TLSA", providers.CanUseTLSA),
// DS needs special record-level checks

View file

@ -341,6 +341,8 @@ func TestWriteZoneFileEach(t *testing.T) {
d = append(d, mustNewRR(`dname.bosun.org. 300 IN DNAME example.com.`))
d = append(d, mustNewRR(`dnssec.bosun.org. 300 IN DS 31334 13 2 94cc505ebc36b1f4e051268b820efb230f1572d445e833bb5bf7380d6c2cbc0a`))
d = append(d, mustNewRR(`dnssec.bosun.org. 300 IN DNSKEY 257 3 13 rNR701yiOPHfqDP53GnsHZdlsRqI7O1ksk60rnFILZVk7Z4eTBd1U49oSkTNVNox9tb7N15N2hboXoMEyFFzcw==`))
d = append(d, mustNewRR(`bosun.org. 300 IN HTTPS 1 . alpn="h3,h2"`))
d = append(d, mustNewRR(`bosun.org. 300 IN SVCB 1 . alpn="h3,h2"`))
buf := &bytes.Buffer{}
writeZoneFileRR(buf, d, "bosun.org")
if buf.String() != testdataZFEach {
@ -359,6 +361,8 @@ var testdataZFEach = `$TTL 300
IN TXT "my text"
IN CAA 0 issue "letsencrypt.org"
IN DHCID AAIBY2/AuCccgoJbsaxcQc9TUapptP69lOjxfNuVAA2kjEA=
IN HTTPS 1 . alpn="h3,h2"
IN SVCB 1 . alpn="h3,h2"
4.5 IN PTR y.bosun.org.
_443._tcp IN TLSA 3 1 1 abcdef0
dname IN DNAME example.com.

View file

@ -80,6 +80,12 @@ func (z *ZoneGenData) Less(i, j int) bool {
if pa != pb {
return pa < pb
}
case "SVCB", "HTTPS":
// sort by priority. If they are equal, sort by record.
if a.SvcPriority == b.SvcPriority {
return a.GetTargetField() < b.GetTargetField()
}
return a.SvcPriority < b.SvcPriority
case "PTR":
//ta2, tb2 := a.(*dns.PTR), b.(*dns.PTR)
pa, pb := a.GetTargetField(), b.GetTargetField()

View file

@ -44,11 +44,13 @@ var features = providers.DocumentationNotes{
providers.CanConcur: providers.Cannot(),
providers.CanUseCAA: providers.Can(),
providers.CanUseDHCID: providers.Can(),
providers.CanUseHTTPS: providers.Can(),
providers.CanUseLOC: providers.Unimplemented(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),
providers.CanUseSVCB: providers.Can(),
providers.CanUseTLSA: providers.Can(),
providers.DocCreateDomains: providers.Cannot(),
providers.DocDualHost: providers.Cannot(),

View file

@ -40,12 +40,14 @@ var features = providers.DocumentationNotes{
providers.CanUseDNAME: providers.Can(),
providers.CanUseDS: providers.Can(),
providers.CanUseDNSKEY: providers.Can(),
providers.CanUseHTTPS: providers.Can(),
providers.CanUseLOC: providers.Can(),
providers.CanUseNAPTR: providers.Can(),
providers.CanUsePTR: providers.Can(),
providers.CanUseSOA: providers.Can(),
providers.CanUseSRV: providers.Can(),
providers.CanUseSSHFP: providers.Can(),
providers.CanUseSVCB: providers.Can(),
providers.CanUseTLSA: providers.Can(),
providers.DocCreateDomains: providers.Can("Driver just maintains list of zone files. It should automatically add missing ones."),
providers.DocDualHost: providers.Can(),

View file

@ -54,6 +54,9 @@ const (
// only for children records, not at the root of the zone.
CanUseDSForChildren
// CanUseHTTPS indicates the provider can handle HTTPS records
CanUseHTTPS
// CanUseLOC indicates whether service provider handles LOC records
CanUseLOC
@ -75,6 +78,9 @@ const (
// CanUseSSHFP indicates the provider can handle SSHFP records
CanUseSSHFP
// CanUseSVCB indicates the provider can handle SVCB records
CanUseSVCB
// CanUseTLSA indicates the provider can handle TLSA records
CanUseTLSA

View file

@ -19,23 +19,25 @@ func _() {
_ = x[CanUseDNAME-8]
_ = x[CanUseDS-9]
_ = x[CanUseDSForChildren-10]
_ = x[CanUseLOC-11]
_ = x[CanUseNAPTR-12]
_ = x[CanUsePTR-13]
_ = x[CanUseRoute53Alias-14]
_ = x[CanUseSOA-15]
_ = x[CanUseSRV-16]
_ = x[CanUseSSHFP-17]
_ = x[CanUseTLSA-18]
_ = x[CanUseDNSKEY-19]
_ = x[DocCreateDomains-20]
_ = x[DocDualHost-21]
_ = x[DocOfficiallySupported-22]
_ = x[CanUseHTTPS-11]
_ = x[CanUseLOC-12]
_ = x[CanUseNAPTR-13]
_ = x[CanUsePTR-14]
_ = x[CanUseRoute53Alias-15]
_ = x[CanUseSOA-16]
_ = x[CanUseSRV-17]
_ = x[CanUseSSHFP-18]
_ = x[CanUseSVCB-19]
_ = x[CanUseTLSA-20]
_ = x[CanUseDNSKEY-21]
_ = x[DocCreateDomains-22]
_ = x[DocDualHost-23]
_ = x[DocOfficiallySupported-24]
}
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported"
const _Capability_name = "CanAutoDNSSECCanConcurCanGetZonesCanUseAKAMAICDNCanUseAliasCanUseAzureAliasCanUseCAACanUseDHCIDCanUseDNAMECanUseDSCanUseDSForChildrenCanUseHTTPSCanUseLOCCanUseNAPTRCanUsePTRCanUseRoute53AliasCanUseSOACanUseSRVCanUseSSHFPCanUseSVCBCanUseTLSACanUseDNSKEYDocCreateDomainsDocDualHostDocOfficiallySupported"
var _Capability_index = [...]uint16{0, 13, 22, 33, 48, 59, 75, 84, 95, 106, 114, 133, 142, 153, 162, 180, 189, 198, 209, 219, 231, 247, 258, 280}
var _Capability_index = [...]uint16{0, 13, 22, 33, 48, 59, 75, 84, 95, 106, 114, 133, 144, 153, 164, 173, 191, 200, 209, 220, 230, 240, 252, 268, 279, 301}
func (i Capability) String() string {
if i >= Capability(len(_Capability_index)-1) {