github.com/binbinly/pkg@v0.0.11-0.20240321014439-f4fbf666eb0f/util/host.go (about) 1 package util 2 3 import ( 4 "fmt" 5 "net" 6 "os" 7 "strconv" 8 ) 9 10 // ExtractHostPort from address 11 func ExtractHostPort(addr string) (host string, port uint64, err error) { 12 var ports string 13 host, ports, err = net.SplitHostPort(addr) 14 if err != nil { 15 return 16 } 17 port, err = strconv.ParseUint(ports, 10, 16) //nolint:gomnd 18 if err != nil { 19 return 20 } 21 return 22 } 23 24 // Port return a real port. 25 func Port(lis net.Listener) (int, bool) { 26 if addr, ok := lis.Addr().(*net.TCPAddr); ok { 27 return addr.Port, true 28 } 29 return 0, false 30 } 31 32 // Hostname 获取主机名 33 func Hostname() string { 34 name, err := os.Hostname() 35 if err != nil { 36 name = "unknown" 37 } 38 return name 39 } 40 41 // Extract returns a private addr and port. 42 func Extract(hostPort string, lis net.Listener) (string, error) { 43 if hostPort == "" { 44 return "", fmt.Errorf("hostPort cannot be empty") 45 } 46 47 addr, port, err := net.SplitHostPort(hostPort) 48 if err != nil && lis == nil { 49 return "", err 50 } 51 if lis != nil { 52 if p, ok := Port(lis); ok { 53 port = strconv.Itoa(p) 54 } else { 55 return "", fmt.Errorf("failed to extract port: %v", lis.Addr()) 56 } 57 } 58 if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]" && addr != "::") { 59 return net.JoinHostPort(addr, port), nil 60 } 61 ifaces, err := net.Interfaces() 62 if err != nil { 63 return "", err 64 } 65 for _, iface := range ifaces { 66 addrs, err := iface.Addrs() 67 if err != nil { 68 continue 69 } 70 for _, rawAddr := range addrs { 71 var ip net.IP 72 switch addr := rawAddr.(type) { 73 case *net.IPAddr: 74 ip = addr.IP 75 case *net.IPNet: 76 ip = addr.IP 77 default: 78 continue 79 } 80 81 if ip == nil { 82 continue 83 } 84 85 if isValidIP(ip.String()) { 86 return net.JoinHostPort(ip.String(), port), nil 87 } 88 } 89 } 90 return "", nil 91 } 92 93 func isValidIP(ip string) bool { 94 parsedIP := net.ParseIP(ip) 95 if parsedIP == nil { 96 return false 97 } 98 return parsedIP.IsGlobalUnicast() 99 }