diff options
Diffstat (limited to 'src/pkg/net/udp_test.go')
| -rw-r--r-- | src/pkg/net/udp_test.go | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/src/pkg/net/udp_test.go b/src/pkg/net/udp_test.go index 220422e13..b3cafb096 100644 --- a/src/pkg/net/udp_test.go +++ b/src/pkg/net/udp_test.go @@ -5,6 +5,7 @@ package net import ( + "fmt" "reflect" "runtime" "testing" @@ -22,6 +23,11 @@ var resolveUDPAddrTests = []struct { {"udp", "[::1]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1}, nil}, {"udp6", "[::1]:65534", &UDPAddr{IP: ParseIP("::1"), Port: 65534}, nil}, + {"udp", "[::1%en0]:1", &UDPAddr{IP: ParseIP("::1"), Port: 1, Zone: "en0"}, nil}, + {"udp6", "[::1%911]:2", &UDPAddr{IP: ParseIP("::1"), Port: 2, Zone: "911"}, nil}, + {"udp6", "[fe80::1]:3", &UDPAddr{IP: ParseIP("fe80::1"), Port: 3, Zone: "name"}, nil}, + {"udp6", "[fe80::1]:4", &UDPAddr{IP: ParseIP("fe80::1"), Port: 4, Zone: "index"}, nil}, + {"", "127.0.0.1:0", &UDPAddr{IP: IPv4(127, 0, 0, 1), Port: 0}, nil}, // Go 1.0 behavior {"", "[::1]:0", &UDPAddr{IP: ParseIP("::1"), Port: 0}, nil}, // Go 1.0 behavior @@ -30,6 +36,24 @@ var resolveUDPAddrTests = []struct { func TestResolveUDPAddr(t *testing.T) { for _, tt := range resolveUDPAddrTests { + if tt.addr != nil && (tt.addr.Zone == "name" || tt.addr.Zone == "index") { + ifi := loopbackInterface() + if ifi == nil { + continue + } + i := last(tt.litAddr, ']') + if i > 0 { + switch tt.addr.Zone { + case "name": + tt.litAddr = tt.litAddr[:i] + "%" + ifi.Name + tt.litAddr[i:] + tt.addr.Zone = zoneToString(ifi.Index) + case "index": + index := fmt.Sprintf("%v", ifi.Index) + tt.litAddr = tt.litAddr[:i] + "%" + index + tt.litAddr[i:] + tt.addr.Zone = index + } + } + } addr, err := ResolveUDPAddr(tt.net, tt.litAddr) if err != tt.err { t.Fatalf("ResolveUDPAddr(%v, %v) failed: %v", tt.net, tt.litAddr, err) @@ -146,3 +170,78 @@ func TestUDPConnLocalName(t *testing.T) { } } } + +func TestIPv6LinkLocalUnicastUDP(t *testing.T) { + if testing.Short() || !*testExternal { + t.Skip("skipping test to avoid external network") + } + if !supportsIPv6 { + t.Skip("ipv6 is not supported") + } + ifi := loopbackInterface() + if ifi == nil { + t.Skip("loopback interface not found") + } + laddr := ipv6LinkLocalUnicastAddr(ifi) + if laddr == "" { + t.Skip("ipv6 unicast address on loopback not found") + } + + type test struct { + net, addr string + nameLookup bool + } + var tests = []test{ + {"udp", "[" + laddr + "%" + ifi.Name + "]:0", false}, + {"udp6", "[" + laddr + "%" + ifi.Name + "]:0", false}, + } + switch runtime.GOOS { + case "darwin", "freebsd", "openbsd", "netbsd": + tests = append(tests, []test{ + {"udp", "[localhost%" + ifi.Name + "]:0", true}, + {"udp6", "[localhost%" + ifi.Name + "]:0", true}, + }...) + case "linux": + tests = append(tests, []test{ + {"udp", "[ip6-localhost%" + ifi.Name + "]:0", true}, + {"udp6", "[ip6-localhost%" + ifi.Name + "]:0", true}, + }...) + } + for _, tt := range tests { + c1, err := ListenPacket(tt.net, tt.addr) + if err != nil { + // It might return "LookupHost returned no + // suitable address" error on some platforms. + t.Logf("ListenPacket failed: %v", err) + continue + } + defer c1.Close() + if la, ok := c1.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", la) + } + + c2, err := Dial(tt.net, c1.LocalAddr().String()) + if err != nil { + t.Fatalf("Dial failed: %v", err) + } + defer c2.Close() + if la, ok := c2.LocalAddr().(*UDPAddr); !ok || !tt.nameLookup && la.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", la) + } + if ra, ok := c2.RemoteAddr().(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", ra) + } + + if _, err := c2.Write([]byte("UDP OVER IPV6 LINKLOCAL TEST")); err != nil { + t.Fatalf("Conn.Write failed: %v", err) + } + b := make([]byte, 32) + if _, from, err := c1.ReadFrom(b); err != nil { + t.Fatalf("PacketConn.ReadFrom failed: %v", err) + } else { + if ra, ok := from.(*UDPAddr); !ok || !tt.nameLookup && ra.Zone == "" { + t.Fatalf("got %v; expected a proper address with zone identifier", ra) + } + } + } +} |
