readwrite_test.go 4.2 KB

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