multicastsockopt_test.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  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. "os"
  8. "runtime"
  9. "testing"
  10. "code.google.com/p/go.net/ipv4"
  11. )
  12. var packetConnMulticastSocketOptionTests = []struct {
  13. net, proto, addr string
  14. gaddr net.Addr
  15. }{
  16. {"udp4", "", "224.0.0.0:0", &net.UDPAddr{IP: net.IPv4(224, 0, 0, 249)}}, // see RFC 4727
  17. {"ip4", ":icmp", "0.0.0.0", &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}}, // see RFC 4727
  18. }
  19. func TestPacketConnMulticastSocketOptions(t *testing.T) {
  20. switch runtime.GOOS {
  21. case "plan9":
  22. t.Skipf("not supported on %q", runtime.GOOS)
  23. }
  24. ifi := loopbackInterface()
  25. if ifi == nil {
  26. t.Skipf("not available on %q", runtime.GOOS)
  27. }
  28. for _, tt := range packetConnMulticastSocketOptionTests {
  29. if tt.net == "ip4" && os.Getuid() != 0 {
  30. t.Skip("must be root")
  31. }
  32. c, err := net.ListenPacket(tt.net+tt.proto, tt.addr)
  33. if err != nil {
  34. t.Fatalf("net.ListenPacket failed: %v", err)
  35. }
  36. defer c.Close()
  37. testMulticastSocketOptions(t, ipv4.NewPacketConn(c), ifi, tt.gaddr)
  38. }
  39. }
  40. func TestRawConnMulticastSocketOptions(t *testing.T) {
  41. switch runtime.GOOS {
  42. case "plan9":
  43. t.Skipf("not supported on %q", runtime.GOOS)
  44. }
  45. if os.Getuid() != 0 {
  46. t.Skip("must be root")
  47. }
  48. ifi := loopbackInterface()
  49. if ifi == nil {
  50. t.Skipf("not available on %q", runtime.GOOS)
  51. }
  52. c, err := net.ListenPacket("ip4:icmp", "0.0.0.0")
  53. if err != nil {
  54. t.Fatalf("net.ListenPacket failed: %v", err)
  55. }
  56. defer c.Close()
  57. r, err := ipv4.NewRawConn(c)
  58. if err != nil {
  59. t.Fatalf("ipv4.NewRawConn failed: %v", err)
  60. }
  61. testMulticastSocketOptions(t, r, ifi, &net.IPAddr{IP: net.IPv4(224, 0, 0, 250)}) /// see RFC 4727
  62. }
  63. type testIPv4MulticastConn interface {
  64. MulticastTTL() (int, error)
  65. SetMulticastTTL(ttl int) error
  66. MulticastLoopback() (bool, error)
  67. SetMulticastLoopback(bool) error
  68. JoinGroup(*net.Interface, net.Addr) error
  69. LeaveGroup(*net.Interface, net.Addr) error
  70. }
  71. func testMulticastSocketOptions(t *testing.T, c testIPv4MulticastConn, ifi *net.Interface, gaddr net.Addr) {
  72. const ttl = 255
  73. if err := c.SetMulticastTTL(ttl); err != nil {
  74. t.Fatalf("ipv4.PacketConn.SetMulticastTTL failed: %v", err)
  75. }
  76. if v, err := c.MulticastTTL(); err != nil {
  77. t.Fatalf("ipv4.PacketConn.MulticastTTL failed: %v", err)
  78. } else if v != ttl {
  79. t.Fatalf("got unexpected multicast TTL value %v; expected %v", v, ttl)
  80. }
  81. for _, toggle := range []bool{true, false} {
  82. if err := c.SetMulticastLoopback(toggle); err != nil {
  83. t.Fatalf("ipv4.PacketConn.SetMulticastLoopback failed: %v", err)
  84. }
  85. if v, err := c.MulticastLoopback(); err != nil {
  86. t.Fatalf("ipv4.PacketConn.MulticastLoopback failed: %v", err)
  87. } else if v != toggle {
  88. t.Fatalf("got unexpected multicast loopback %v; expected %v", v, toggle)
  89. }
  90. }
  91. if err := c.JoinGroup(ifi, gaddr); err != nil {
  92. t.Fatalf("ipv4.PacketConn.JoinGroup(%v, %v) failed: %v", ifi, gaddr, err)
  93. }
  94. if err := c.LeaveGroup(ifi, gaddr); err != nil {
  95. t.Fatalf("ipv4.PacketConn.LeaveGroup(%v, %v) failed: %v", ifi, gaddr, err)
  96. }
  97. }