瀏覽代碼

go.net/ipv4: make sure whether the interface under test is routed

Some multicast tests depend on proper IP routing because multicasting
requires an unicast source address for its delivery. We call a network
interface that can route IP traffic to neighbors a routed interface
conventionally. This CL makes sure that the interface under test is a
routed interface to avoid using non-routed network interfaces for IP
routing.

Also removes unnecessary build tag.

Fixes golang/go#6709.

R=dave
CC=golang-dev
https://golang.org/cl/21260043
Mikio Hara 12 年之前
父節點
當前提交
dcb9639725
共有 1 個文件被更改,包括 31 次插入20 次删除
  1. 31 20
      ipv4/mocktransponder_test.go

+ 31 - 20
ipv4/mocktransponder_test.go

@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-// +build darwin freebsd linux netbsd openbsd
-
 package ipv4_test
 
 import (
@@ -75,6 +73,10 @@ func writeThenReadDatagram(t *testing.T, i int, c *ipv4.RawConn, wb []byte, src,
 	return b
 }
 
+func isUnicast(ip net.IP) bool {
+	return ip.To4() != nil && (ip.IsLoopback() || ip.IsLinkLocalUnicast() || ip.IsGlobalUnicast())
+}
+
 // LoopbackInterface returns a logical network interface for loopback
 // tests.
 func loopbackInterface() *net.Interface {
@@ -83,8 +85,24 @@ func loopbackInterface() *net.Interface {
 		return nil
 	}
 	for _, ifi := range ift {
-		if ifi.Flags&net.FlagLoopback != 0 {
-			return &ifi
+		if ifi.Flags&net.FlagLoopback == 0 || ifi.Flags&net.FlagUp == 0 {
+			continue
+		}
+		ifat, err := ifi.Addrs()
+		if err != nil {
+			continue
+		}
+		for _, ifa := range ifat {
+			switch ifa := ifa.(type) {
+			case *net.IPAddr:
+				if isUnicast(ifa.IP) {
+					return &ifi
+				}
+			case *net.IPNet:
+				if isUnicast(ifa.IP) {
+					return &ifi
+				}
+			}
 		}
 	}
 	return nil
@@ -94,31 +112,24 @@ func loopbackInterface() *net.Interface {
 // enabled network interface.  It also returns a unicast IPv4 address
 // that can be used for listening on ifi.
 func isMulticastAvailable(ifi *net.Interface) (net.IP, bool) {
-	if ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
+	if ifi == nil || ifi.Flags&net.FlagUp == 0 || ifi.Flags&net.FlagMulticast == 0 {
 		return nil, false
 	}
 	ifat, err := ifi.Addrs()
 	if err != nil {
 		return nil, false
 	}
-	if len(ifat) == 0 {
-		return nil, false
-	}
-	var ip net.IP
 	for _, ifa := range ifat {
-		switch v := ifa.(type) {
+		switch ifa := ifa.(type) {
 		case *net.IPAddr:
-			ip = v.IP
+			if isUnicast(ifa.IP) {
+				return ifa.IP, true
+			}
 		case *net.IPNet:
-			ip = v.IP
-		default:
-			continue
-		}
-		if ip.To4() == nil {
-			ip = nil
-			continue
+			if isUnicast(ifa.IP) {
+				return ifa.IP, true
+			}
 		}
-		break
 	}
-	return ip, true
+	return nil, false
 }