Update LocalInterfaces() to comply with spec

Resolves #466
This commit is contained in:
Konstantin Itskov
2019-03-03 21:15:43 -08:00
committed by Sean DuBois
parent dc966e04a9
commit 30763bbf3f
+36 -3
View File
@@ -18,21 +18,34 @@ func localInterfaces() (ips []net.IP) {
if iface.Flags&net.FlagLoopback != 0 {
continue // loopback interface
}
addrs, err := iface.Addrs()
if err != nil {
return ips
}
for _, addr := range addrs {
var ip net.IP
switch v := addr.(type) {
switch addr := addr.(type) {
case *net.IPNet:
ip = v.IP
ip = addr.IP
case *net.IPAddr:
ip = v.IP
ip = addr.IP
}
if ip == nil || ip.IsLoopback() {
continue
}
// The conditions of invalidation written below are defined in
// https://tools.ietf.org/html/rfc8445#section-5.1.1.1
if ipv4 := ip.To4(); ipv4 == nil {
if !isSupportedIPv6(ip) {
continue
}
}
ips = append(ips, ip)
}
}
@@ -48,3 +61,23 @@ func (a *atomicError) Load() error {
err, _ := a.v.Load().(struct{ error })
return err.error
}
func isSupportedIPv6(ip net.IP) bool {
if len(ip) != net.IPv6len ||
!isZeros(ip[0:12]) || // !(IPv4-compatible IPv6)
ip[0] == 0xfe && ip[1]&0xc0 == 0xc0 || // !(IPv6 site-local unicast)
ip.IsLinkLocalUnicast() ||
ip.IsLinkLocalMulticast() {
return false
}
return true
}
func isZeros(ip net.IP) bool {
for i := 0; i < len(ip); i++ {
if ip[i] != 0 {
return false
}
}
return true
}