Classify DNS names as apex domains or hostnames using the Public Suffix List (golang.org/x/net/publicsuffix). Correctly handles multi-level TLDs like .co.uk and .com.au.
62 lines
1.4 KiB
Go
62 lines
1.4 KiB
Go
// Package config provides application configuration via Viper.
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"golang.org/x/net/publicsuffix"
|
|
)
|
|
|
|
// ClassifyTarget determines whether a DNS name is an apex domain
|
|
// (eTLD+1) or a hostname (subdomain of an eTLD+1). Returns
|
|
// "domain" or "hostname". Returns an error if the name is itself
|
|
// a public suffix (e.g. "co.uk") or otherwise invalid.
|
|
func ClassifyTarget(name string) (string, error) {
|
|
// Normalize: lowercase, strip trailing dot.
|
|
name = strings.ToLower(strings.TrimSuffix(name, "."))
|
|
|
|
if name == "" {
|
|
return "", fmt.Errorf("empty target name")
|
|
}
|
|
|
|
apex, err := publicsuffix.EffectiveTLDPlusOne(name)
|
|
if err != nil {
|
|
return "", fmt.Errorf(
|
|
"invalid target %q: %w", name, err,
|
|
)
|
|
}
|
|
|
|
if name == apex {
|
|
return "domain", nil
|
|
}
|
|
|
|
return "hostname", nil
|
|
}
|
|
|
|
// classifyTargets splits a list of DNS names into apex domains
|
|
// and hostnames using the Public Suffix List.
|
|
func classifyTargets(
|
|
targets []string,
|
|
) (domains, hostnames []string, err error) {
|
|
for _, target := range targets {
|
|
kind, classifyErr := ClassifyTarget(target)
|
|
if classifyErr != nil {
|
|
return nil, nil, classifyErr
|
|
}
|
|
|
|
switch kind {
|
|
case "domain":
|
|
domains = append(domains, strings.ToLower(
|
|
strings.TrimSuffix(target, "."),
|
|
))
|
|
case "hostname":
|
|
hostnames = append(hostnames, strings.ToLower(
|
|
strings.TrimSuffix(target, "."),
|
|
))
|
|
}
|
|
}
|
|
|
|
return domains, hostnames, nil
|
|
}
|