1
0
mirror of https://github.com/go-kratos/kratos.git synced 2025-03-19 21:18:07 +02:00
kratos/internal/host/host.go

68 lines
1.5 KiB
Go
Raw Normal View History

2021-02-17 17:14:47 +08:00
package host
import (
"net"
"strconv"
)
2021-05-31 16:55:30 +08:00
func isValidIP(addr string) bool {
2021-04-08 17:45:11 +08:00
ip := net.ParseIP(addr)
if ip4 := ip.To4(); ip4 != nil {
2021-05-31 16:55:30 +08:00
return !ip4.IsLoopback()
2021-02-17 17:14:47 +08:00
}
2021-04-08 17:45:11 +08:00
// Following RFC 4193, Section 3. Private Address Space which says:
// The Internet Assigned Numbers Authority (IANA) has reserved the
// following block of the IPv6 address space for local internets:
// FC00:: - FDFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF (FC00::/7 prefix)
return len(ip) == net.IPv6len && ip[0]&0xfe == 0xfc
2021-02-17 17:14:47 +08:00
}
// Port return a real port.
func Port(lis net.Listener) (int, bool) {
if addr, ok := lis.Addr().(*net.TCPAddr); ok {
return addr.Port, true
}
return 0, false
}
// Extract returns a private addr and port.
2021-04-08 17:45:11 +08:00
func Extract(hostPort string, lis net.Listener) (string, error) {
addr, port, err := net.SplitHostPort(hostPort)
2021-02-17 17:14:47 +08:00
if err != nil {
return "", err
}
if lis != nil {
if p, ok := Port(lis); ok {
port = strconv.Itoa(p)
}
}
if len(addr) > 0 && (addr != "0.0.0.0" && addr != "[::]" && addr != "::") {
return net.JoinHostPort(addr, port), nil
}
ifaces, err := net.Interfaces()
if err != nil {
2021-03-05 22:40:38 +08:00
return "", err
2021-02-17 17:14:47 +08:00
}
for _, iface := range ifaces {
addrs, err := iface.Addrs()
if err != nil {
continue
}
for _, rawAddr := range addrs {
var ip net.IP
switch addr := rawAddr.(type) {
case *net.IPAddr:
ip = addr.IP
case *net.IPNet:
ip = addr.IP
default:
continue
}
2021-05-31 16:55:30 +08:00
if isValidIP(ip.String()) {
2021-02-17 17:14:47 +08:00
return net.JoinHostPort(ip.String(), port), nil
}
}
}
return "", nil
}