happyDomain/utils/dns.go

106 lines
2.8 KiB
Go

// This file is part of the happyDomain (R) project.
// Copyright (c) 2020-2024 happyDomain
// Authors: Pierre-Olivier Mercier, et al.
//
// This program is offered under a commercial and under the AGPL license.
// For commercial licensing, contact us at <contact@happydomain.org>.
//
// For AGPL licensing:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
package utils
import (
"strings"
"github.com/StackExchange/dnscontrol/v4/models"
"github.com/miekg/dns"
)
// SplitN splits a string into N sized string chunks.
// This function is a copy of https://github.com/miekg/dns/blob/master/types.go#L1509
// awaiting its exportation
func SplitN(s string, n int) []string {
if len(s) < n {
return []string{s}
}
sx := []string{}
p, i := 0, n
for {
if i <= len(s) {
sx = append(sx, s[p:i])
} else {
sx = append(sx, s[p:])
break
}
p, i = p+n, i+n
}
return sx
}
// IsDNSSECType returns true if the given rrtype is generally autogenerated by
// NS server.
func IsDNSSECType(rrtype uint16) bool {
return rrtype == dns.TypeNSEC ||
rrtype == dns.TypeNSEC3 ||
rrtype == dns.TypeNSEC3PARAM ||
rrtype == dns.TypeDNSKEY ||
rrtype == dns.TypeRRSIG
}
// DomainFQDN normalizes the domain by adding the origin if it is relative (not
// ended by .).
func DomainFQDN(subdomain string, origin string) string {
if subdomain == "" || subdomain[len(subdomain)-1] == '.' {
return subdomain
} else if subdomain == "@" {
return origin
} else {
return subdomain + "." + origin
}
}
// DomainJoin appends each relative domains passed as argument.
func DomainJoin(domains ...string) (ret string) {
for _, d := range domains {
if d == "@" {
break
} else if d != "" {
ret += "." + d
}
if len(ret) > 0 && ret[len(ret)-1] == '.' {
break
}
}
if len(ret) >= 1 {
ret = ret[1:]
}
return
}
// DomainJoin appends each relative domains passed as argument.
func NewRecordConfig(domain string, rtype string, ttl uint32, origin string) *models.RecordConfig {
return &models.RecordConfig{
Name: strings.TrimSuffix(strings.TrimSuffix(DomainJoin(domain), origin), "."),
NameFQDN: strings.TrimSuffix(DomainJoin(domain), "."),
Type: rtype,
TTL: ttl,
}
}