readwrite_test.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. // Copyright 2013 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 ipv6_test
  5. import (
  6. "bytes"
  7. "net"
  8. "runtime"
  9. "sync"
  10. "testing"
  11. "golang.org/x/net/internal/iana"
  12. "golang.org/x/net/internal/nettest"
  13. "golang.org/x/net/ipv6"
  14. )
  15. func benchmarkUDPListener() (net.PacketConn, net.Addr, error) {
  16. c, err := net.ListenPacket("udp6", "[::1]:0")
  17. if err != nil {
  18. return nil, nil, err
  19. }
  20. dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
  21. if err != nil {
  22. c.Close()
  23. return nil, nil, err
  24. }
  25. return c, dst, nil
  26. }
  27. func BenchmarkReadWriteNetUDP(b *testing.B) {
  28. if !supportsIPv6 {
  29. b.Skip("ipv6 is not supported")
  30. }
  31. c, dst, err := benchmarkUDPListener()
  32. if err != nil {
  33. b.Fatal(err)
  34. }
  35. defer c.Close()
  36. wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
  37. b.ResetTimer()
  38. for i := 0; i < b.N; i++ {
  39. benchmarkReadWriteNetUDP(b, c, wb, rb, dst)
  40. }
  41. }
  42. func benchmarkReadWriteNetUDP(b *testing.B, c net.PacketConn, wb, rb []byte, dst net.Addr) {
  43. if _, err := c.WriteTo(wb, dst); err != nil {
  44. b.Fatal(err)
  45. }
  46. if _, _, err := c.ReadFrom(rb); err != nil {
  47. b.Fatal(err)
  48. }
  49. }
  50. func BenchmarkReadWriteIPv6UDP(b *testing.B) {
  51. if !supportsIPv6 {
  52. b.Skip("ipv6 is not supported")
  53. }
  54. c, dst, err := benchmarkUDPListener()
  55. if err != nil {
  56. b.Fatal(err)
  57. }
  58. defer c.Close()
  59. p := ipv6.NewPacketConn(c)
  60. cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
  61. if err := p.SetControlMessage(cf, true); err != nil {
  62. b.Fatal(err)
  63. }
  64. ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
  65. wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
  66. b.ResetTimer()
  67. for i := 0; i < b.N; i++ {
  68. benchmarkReadWriteIPv6UDP(b, p, wb, rb, dst, ifi)
  69. }
  70. }
  71. func benchmarkReadWriteIPv6UDP(b *testing.B, p *ipv6.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) {
  72. cm := ipv6.ControlMessage{
  73. TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
  74. HopLimit: 1,
  75. }
  76. if ifi != nil {
  77. cm.IfIndex = ifi.Index
  78. }
  79. if n, err := p.WriteTo(wb, &cm, dst); err != nil {
  80. b.Fatal(err)
  81. } else if n != len(wb) {
  82. b.Fatalf("got %v; want %v", n, len(wb))
  83. }
  84. if _, _, _, err := p.ReadFrom(rb); err != nil {
  85. b.Fatal(err)
  86. }
  87. }
  88. func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
  89. switch runtime.GOOS {
  90. case "nacl", "plan9", "solaris", "windows":
  91. t.Skipf("not supported on %s", runtime.GOOS)
  92. }
  93. if !supportsIPv6 {
  94. t.Skip("ipv6 is not supported")
  95. }
  96. c, err := net.ListenPacket("udp6", "[::1]:0")
  97. if err != nil {
  98. t.Fatal(err)
  99. }
  100. defer c.Close()
  101. p := ipv6.NewPacketConn(c)
  102. defer p.Close()
  103. dst, err := net.ResolveUDPAddr("udp6", c.LocalAddr().String())
  104. if err != nil {
  105. t.Fatal(err)
  106. }
  107. ifi := nettest.RoutedInterface("ip6", net.FlagUp|net.FlagLoopback)
  108. cf := ipv6.FlagTrafficClass | ipv6.FlagHopLimit | ipv6.FlagSrc | ipv6.FlagDst | ipv6.FlagInterface | ipv6.FlagPathMTU
  109. wb := []byte("HELLO-R-U-THERE")
  110. if err := p.SetControlMessage(cf, true); err != nil { // probe before test
  111. if nettest.ProtocolNotSupported(err) {
  112. t.Skipf("not supported on %s", runtime.GOOS)
  113. }
  114. t.Fatal(err)
  115. }
  116. var wg sync.WaitGroup
  117. reader := func() {
  118. defer wg.Done()
  119. rb := make([]byte, 128)
  120. if n, cm, _, err := p.ReadFrom(rb); err != nil {
  121. t.Error(err)
  122. return
  123. } else if !bytes.Equal(rb[:n], wb) {
  124. t.Errorf("got %v; want %v", rb[:n], wb)
  125. return
  126. } else {
  127. t.Logf("rcvd cmsg: %v", cm)
  128. }
  129. }
  130. writer := func(toggle bool) {
  131. defer wg.Done()
  132. cm := ipv6.ControlMessage{
  133. TrafficClass: iana.DiffServAF11 | iana.CongestionExperienced,
  134. Src: net.IPv6loopback,
  135. }
  136. if ifi != nil {
  137. cm.IfIndex = ifi.Index
  138. }
  139. if err := p.SetControlMessage(cf, toggle); err != nil {
  140. t.Error(err)
  141. return
  142. }
  143. if n, err := p.WriteTo(wb, &cm, dst); err != nil {
  144. t.Error(err)
  145. return
  146. } else if n != len(wb) {
  147. t.Errorf("got %v; want %v", n, len(wb))
  148. return
  149. }
  150. }
  151. const N = 10
  152. wg.Add(N)
  153. for i := 0; i < N; i++ {
  154. go reader()
  155. }
  156. wg.Add(2 * N)
  157. for i := 0; i < 2*N; i++ {
  158. go writer(i%2 != 0)
  159. }
  160. wg.Add(N)
  161. for i := 0; i < N; i++ {
  162. go reader()
  163. }
  164. wg.Wait()
  165. }