readwrite_test.go 4.3 KB

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