* gcc.dg/guality/guality.exp: Skip on AIX.
[official-gcc.git] / libgo / go / net / multicast_test.go
blob8ff02a3c9333a53f11d07d13808920588082b37a
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package net
7 import (
8 "fmt"
9 "os"
10 "runtime"
11 "testing"
14 var ipv4MulticastListenerTests = []struct {
15 net string
16 gaddr *UDPAddr // see RFC 4727
18 {"udp", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
20 {"udp4", &UDPAddr{IP: IPv4(224, 0, 0, 254), Port: 12345}},
23 // TestIPv4MulticastListener tests both single and double listen to a
24 // test listener with same address family, same group address and same
25 // port.
26 func TestIPv4MulticastListener(t *testing.T) {
27 switch runtime.GOOS {
28 case "plan9":
29 t.Skipf("skipping test on %q", runtime.GOOS)
32 closer := func(cs []*UDPConn) {
33 for _, c := range cs {
34 if c != nil {
35 c.Close()
40 for _, ifi := range []*Interface{loopbackInterface(), nil} {
41 // Note that multicast interface assignment by system
42 // is not recommended because it usually relies on
43 // routing stuff for finding out an appropriate
44 // nexthop containing both network and link layer
45 // adjacencies.
46 if ifi == nil && !*testExternal {
47 continue
49 for _, tt := range ipv4MulticastListenerTests {
50 var err error
51 cs := make([]*UDPConn, 2)
52 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
53 t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
55 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
56 closer(cs)
57 t.Fatal(err)
59 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
60 closer(cs)
61 t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
63 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
64 closer(cs)
65 t.Fatal(err)
67 closer(cs)
72 var ipv6MulticastListenerTests = []struct {
73 net string
74 gaddr *UDPAddr // see RFC 4727
76 {"udp", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
77 {"udp", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
78 {"udp", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
79 {"udp", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
80 {"udp", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
81 {"udp", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
83 {"udp6", &UDPAddr{IP: ParseIP("ff01::114"), Port: 12345}},
84 {"udp6", &UDPAddr{IP: ParseIP("ff02::114"), Port: 12345}},
85 {"udp6", &UDPAddr{IP: ParseIP("ff04::114"), Port: 12345}},
86 {"udp6", &UDPAddr{IP: ParseIP("ff05::114"), Port: 12345}},
87 {"udp6", &UDPAddr{IP: ParseIP("ff08::114"), Port: 12345}},
88 {"udp6", &UDPAddr{IP: ParseIP("ff0e::114"), Port: 12345}},
91 // TestIPv6MulticastListener tests both single and double listen to a
92 // test listener with same address family, same group address and same
93 // port.
94 func TestIPv6MulticastListener(t *testing.T) {
95 switch runtime.GOOS {
96 case "plan9", "solaris":
97 t.Skipf("skipping test on %q", runtime.GOOS)
99 if !supportsIPv6 {
100 t.Skip("ipv6 is not supported")
102 if os.Getuid() != 0 {
103 t.Skip("skipping test; must be root")
106 closer := func(cs []*UDPConn) {
107 for _, c := range cs {
108 if c != nil {
109 c.Close()
114 for _, ifi := range []*Interface{loopbackInterface(), nil} {
115 // Note that multicast interface assignment by system
116 // is not recommended because it usually relies on
117 // routing stuff for finding out an appropriate
118 // nexthop containing both network and link layer
119 // adjacencies.
120 if ifi == nil && (!*testExternal || !*testIPv6) {
121 continue
123 for _, tt := range ipv6MulticastListenerTests {
124 var err error
125 cs := make([]*UDPConn, 2)
126 if cs[0], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
127 t.Fatalf("First ListenMulticastUDP on %v failed: %v", ifi, err)
129 if err := checkMulticastListener(cs[0], tt.gaddr.IP); err != nil {
130 closer(cs)
131 t.Fatal(err)
133 if cs[1], err = ListenMulticastUDP(tt.net, ifi, tt.gaddr); err != nil {
134 closer(cs)
135 t.Fatalf("Second ListenMulticastUDP on %v failed: %v", ifi, err)
137 if err := checkMulticastListener(cs[1], tt.gaddr.IP); err != nil {
138 closer(cs)
139 t.Fatal(err)
141 closer(cs)
146 func checkMulticastListener(c *UDPConn, ip IP) error {
147 if ok, err := multicastRIBContains(ip); err != nil {
148 return err
149 } else if !ok {
150 return fmt.Errorf("%q not found in multicast RIB", ip.String())
152 la := c.LocalAddr()
153 if la, ok := la.(*UDPAddr); !ok || la.Port == 0 {
154 return fmt.Errorf("got %v; expected a proper address with non-zero port number", la)
156 return nil
159 func multicastRIBContains(ip IP) (bool, error) {
160 switch runtime.GOOS {
161 case "netbsd", "openbsd", "plan9", "solaris", "windows":
162 return true, nil // not implemented yet
163 case "linux":
164 if runtime.GOARCH == "arm" || runtime.GOARCH == "alpha" {
165 return true, nil // not implemented yet
168 ift, err := Interfaces()
169 if err != nil {
170 return false, err
172 for _, ifi := range ift {
173 ifmat, err := ifi.MulticastAddrs()
174 if err != nil {
175 return false, err
177 for _, ifma := range ifmat {
178 if ifma.(*IPAddr).IP.Equal(ip) {
179 return true, nil
183 return false, nil