*
* Copyright (c) 2025 Bocloud Technologies Co., Ltd.
* installer is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain n copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*
*/
package net
import (
"net"
"os"
"regexp"
"strings"
"github.com/pkg/errors"
)
const (
DefaultDNSServer = "8.8.8.8:53"
IPv4NetworkPrefixStart = 0
IPv4NetworkPrefixLength = 3
)
func ValidIP(ip string) bool {
if ip == "" {
return false
}
if net.ParseIP(ip) != nil {
return true
}
return false
}
func GetExternalIP() (string, error) {
probeAddr := os.Getenv("EXTERNAL_IP_PROBE_ADDRESS")
if probeAddr == "" {
probeAddr = DefaultDNSServer
}
conn, err := net.Dial("udp", probeAddr)
if err != nil {
return "127.0.0.1", err
}
defer conn.Close()
localAddr := conn.LocalAddr()
udpAddr, ok := localAddr.(*net.UDPAddr)
if !ok {
return "", errors.New("failed to convert local address to UDPAddr")
}
ip := strings.Split(udpAddr.String(), ":")[0]
return ip, nil
}
func SameNetworkSegment(ip1, ip2 string) bool {
prefix1 := strings.Split(ip1, ".")[IPv4NetworkPrefixStart:IPv4NetworkPrefixLength]
prefix2 := strings.Split(ip2, ".")[IPv4NetworkPrefixStart:IPv4NetworkPrefixLength]
if strings.Join(prefix1, "") == strings.Join(prefix2, "") {
return true
}
return false
}
const dns1123LabelFmt string = "[a-z0-9]([-a-z0-9]*[a-z0-9])?"
const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"
const dns1123SubdomainErrorMsg string = "a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"
const DNS1123SubdomainMaxLength int = 253
var dns1123SubdomainRegexp = regexp.MustCompile("^" + dns1123SubdomainFmt + "$")
func IsDNS1123Subdomain(value string) error {
if len(value) > DNS1123SubdomainMaxLength {
return errors.Errorf("must be no more than %d characters", DNS1123SubdomainMaxLength)
}
if !dns1123SubdomainRegexp.MatchString(value) {
return errors.Errorf("%q is not valid domain, a lowercase RFC 1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com')", value)
}
return nil
}