mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-11 16:24:11 +01:00
73 lines
1.7 KiB
Go
73 lines
1.7 KiB
Go
package dns
|
|
|
|
import (
|
|
"net"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// GetHostname is a var to allow tests to stub os.Hostname.
|
|
var GetHostname = os.Hostname
|
|
|
|
// IsDomain validates a DNS domain (FQDN or single label not allowed here). It must have at least one dot.
|
|
// Each label must match IsLabel (except overall length and hyphen rules already covered by regex logic).
|
|
func IsDomain(d string) bool {
|
|
d = strings.TrimSuffix(strings.ToLower(strings.TrimSpace(d)), ".")
|
|
if d == "" || strings.Count(d, ".") < 1 || len(d) > 253 {
|
|
return false
|
|
}
|
|
if _, bad := ReservedDomains[d]; bad {
|
|
return false
|
|
}
|
|
if IsLocalSuffix(d) {
|
|
return false
|
|
}
|
|
for p := range strings.SplitSeq(d, ".") {
|
|
if !IsLabel(p) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// GetSystemDomain tries to determine a usable cluster domain from system configuration.
|
|
// It uses the system hostname and returns the domain (everything after the first dot) when valid and not reserved.
|
|
func GetSystemDomain() string {
|
|
hn, _ := GetHostname()
|
|
hn = strings.ToLower(strings.TrimSpace(hn))
|
|
|
|
if hn == "" {
|
|
return ""
|
|
}
|
|
|
|
if _, bad := NonUniqueHostnames[hn]; bad {
|
|
return ""
|
|
}
|
|
|
|
// If hostname contains a dot, take the domain part.
|
|
if i := strings.IndexByte(hn, '.'); i > 0 && i < len(hn)-1 {
|
|
dom := hn[i+1:]
|
|
if IsDomain(dom) {
|
|
return dom
|
|
}
|
|
}
|
|
|
|
// Try reverse lookup to get FQDN domain, then validate.
|
|
if addrs, err := net.LookupAddr(hn); err == nil {
|
|
for _, fqdn := range addrs {
|
|
fqdn = strings.TrimSuffix(strings.ToLower(fqdn), ".")
|
|
if fqdn == "" || fqdn == hn {
|
|
continue
|
|
}
|
|
if i := strings.IndexByte(fqdn, '.'); i > 0 && i < len(fqdn)-1 {
|
|
dom := fqdn[i+1:]
|
|
if IsDomain(dom) {
|
|
return dom
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ""
|
|
}
|