multicastlistener_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. // Copyright 2012 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.
  4. package ipv4_test
  5. import (
  6. "net"
  7. "runtime"
  8. "testing"
  9. "golang.org/x/net/ipv4"
  10. "golang.org/x/net/nettest"
  11. )
  12. var udpMultipleGroupListenerTests = []net.Addr{
  13. &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}, // see RFC 4727
  14. &net.UDPAddr{IP: net.IPv4(224, 0, 0, 250)},
  15. &net.UDPAddr{IP: net.IPv4(224, 0, 0, 254)},
  16. }
  17. func TestUDPSinglePacketConnWithMultipleGroupListeners(t *testing.T) {
  18. switch runtime.GOOS {
  19. case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
  20. t.Skipf("not supported on %s", runtime.GOOS)
  21. }
  22. if testing.Short() {
  23. t.Skip("to avoid external network")
  24. }
  25. for _, gaddr := range udpMultipleGroupListenerTests {
  26. c, err := net.ListenPacket("udp4", "0.0.0.0:0") // wildcard address with no reusable port
  27. if err != nil {
  28. t.Fatal(err)
  29. }
  30. defer c.Close()
  31. p := ipv4.NewPacketConn(c)
  32. var mift []*net.Interface
  33. ift, err := net.Interfaces()
  34. if err != nil {
  35. t.Fatal(err)
  36. }
  37. for i, ifi := range ift {
  38. if _, err := nettest.MulticastSource("ip4", &ifi); err != nil {
  39. continue
  40. }
  41. if err := p.JoinGroup(&ifi, gaddr); err != nil {
  42. t.Fatal(err)
  43. }
  44. mift = append(mift, &ift[i])
  45. }
  46. for _, ifi := range mift {
  47. if err := p.LeaveGroup(ifi, gaddr); err != nil {
  48. t.Fatal(err)
  49. }
  50. }
  51. }
  52. }
  53. func TestUDPMultiplePacketConnWithMultipleGroupListeners(t *testing.T) {
  54. switch runtime.GOOS {
  55. case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
  56. t.Skipf("not supported on %s", runtime.GOOS)
  57. }
  58. if testing.Short() {
  59. t.Skip("to avoid external network")
  60. }
  61. for _, gaddr := range udpMultipleGroupListenerTests {
  62. c1, err := net.ListenPacket("udp4", "224.0.0.0:0") // wildcard address with reusable port
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. defer c1.Close()
  67. _, port, err := net.SplitHostPort(c1.LocalAddr().String())
  68. if err != nil {
  69. t.Fatal(err)
  70. }
  71. c2, err := net.ListenPacket("udp4", net.JoinHostPort("224.0.0.0", port)) // wildcard address with reusable port
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. defer c2.Close()
  76. var ps [2]*ipv4.PacketConn
  77. ps[0] = ipv4.NewPacketConn(c1)
  78. ps[1] = ipv4.NewPacketConn(c2)
  79. var mift []*net.Interface
  80. ift, err := net.Interfaces()
  81. if err != nil {
  82. t.Fatal(err)
  83. }
  84. for i, ifi := range ift {
  85. if _, err := nettest.MulticastSource("ip4", &ifi); err != nil {
  86. continue
  87. }
  88. for _, p := range ps {
  89. if err := p.JoinGroup(&ifi, gaddr); err != nil {
  90. t.Fatal(err)
  91. }
  92. }
  93. mift = append(mift, &ift[i])
  94. }
  95. for _, ifi := range mift {
  96. for _, p := range ps {
  97. if err := p.LeaveGroup(ifi, gaddr); err != nil {
  98. t.Fatal(err)
  99. }
  100. }
  101. }
  102. }
  103. }
  104. func TestUDPPerInterfaceSinglePacketConnWithSingleGroupListener(t *testing.T) {
  105. switch runtime.GOOS {
  106. case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
  107. t.Skipf("not supported on %s", runtime.GOOS)
  108. }
  109. if testing.Short() {
  110. t.Skip("to avoid external network")
  111. }
  112. gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
  113. type ml struct {
  114. c *ipv4.PacketConn
  115. ifi *net.Interface
  116. }
  117. var mlt []*ml
  118. ift, err := net.Interfaces()
  119. if err != nil {
  120. t.Fatal(err)
  121. }
  122. port := "0"
  123. for i, ifi := range ift {
  124. ip, err := nettest.MulticastSource("ip4", &ifi)
  125. if err != nil {
  126. continue
  127. }
  128. c, err := net.ListenPacket("udp4", net.JoinHostPort(ip.String(), port)) // unicast address with non-reusable port
  129. if err != nil {
  130. // The listen may fail when the serivce is
  131. // already in use, but it's fine because the
  132. // purpose of this is not to test the
  133. // bookkeeping of IP control block inside the
  134. // kernel.
  135. t.Log(err)
  136. continue
  137. }
  138. defer c.Close()
  139. if port == "0" {
  140. _, port, err = net.SplitHostPort(c.LocalAddr().String())
  141. if err != nil {
  142. t.Fatal(err)
  143. }
  144. }
  145. p := ipv4.NewPacketConn(c)
  146. if err := p.JoinGroup(&ifi, &gaddr); err != nil {
  147. t.Fatal(err)
  148. }
  149. mlt = append(mlt, &ml{p, &ift[i]})
  150. }
  151. for _, m := range mlt {
  152. if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
  153. t.Fatal(err)
  154. }
  155. }
  156. }
  157. func TestIPSingleRawConnWithSingleGroupListener(t *testing.T) {
  158. switch runtime.GOOS {
  159. case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
  160. t.Skipf("not supported on %s", runtime.GOOS)
  161. }
  162. if testing.Short() {
  163. t.Skip("to avoid external network")
  164. }
  165. if !nettest.SupportsRawSocket() {
  166. t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
  167. }
  168. c, err := net.ListenPacket("ip4:icmp", "0.0.0.0") // wildcard address
  169. if err != nil {
  170. t.Fatal(err)
  171. }
  172. defer c.Close()
  173. r, err := ipv4.NewRawConn(c)
  174. if err != nil {
  175. t.Fatal(err)
  176. }
  177. gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
  178. var mift []*net.Interface
  179. ift, err := net.Interfaces()
  180. if err != nil {
  181. t.Fatal(err)
  182. }
  183. for i, ifi := range ift {
  184. if _, err := nettest.MulticastSource("ip4", &ifi); err != nil {
  185. continue
  186. }
  187. if err := r.JoinGroup(&ifi, &gaddr); err != nil {
  188. t.Fatal(err)
  189. }
  190. mift = append(mift, &ift[i])
  191. }
  192. for _, ifi := range mift {
  193. if err := r.LeaveGroup(ifi, &gaddr); err != nil {
  194. t.Fatal(err)
  195. }
  196. }
  197. }
  198. func TestIPPerInterfaceSingleRawConnWithSingleGroupListener(t *testing.T) {
  199. switch runtime.GOOS {
  200. case "fuchsia", "hurd", "js", "nacl", "plan9", "windows":
  201. t.Skipf("not supported on %s", runtime.GOOS)
  202. }
  203. if testing.Short() {
  204. t.Skip("to avoid external network")
  205. }
  206. if !nettest.SupportsRawSocket() {
  207. t.Skipf("not supported on %s/%s", runtime.GOOS, runtime.GOARCH)
  208. }
  209. gaddr := net.IPAddr{IP: net.IPv4(224, 0, 0, 254)} // see RFC 4727
  210. type ml struct {
  211. c *ipv4.RawConn
  212. ifi *net.Interface
  213. }
  214. var mlt []*ml
  215. ift, err := net.Interfaces()
  216. if err != nil {
  217. t.Fatal(err)
  218. }
  219. for i, ifi := range ift {
  220. ip, err := nettest.MulticastSource("ip4", &ifi)
  221. if err != nil {
  222. continue
  223. }
  224. c, err := net.ListenPacket("ip4:253", ip.String()) // unicast address
  225. if err != nil {
  226. t.Fatal(err)
  227. }
  228. defer c.Close()
  229. r, err := ipv4.NewRawConn(c)
  230. if err != nil {
  231. t.Fatal(err)
  232. }
  233. if err := r.JoinGroup(&ifi, &gaddr); err != nil {
  234. t.Fatal(err)
  235. }
  236. mlt = append(mlt, &ml{r, &ift[i]})
  237. }
  238. for _, m := range mlt {
  239. if err := m.c.LeaveGroup(m.ifi, &gaddr); err != nil {
  240. t.Fatal(err)
  241. }
  242. }
  243. }