// 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 }