You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
3.0 KiB

  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. "bytes"
  7. "net"
  8. "runtime"
  9. "strings"
  10. "sync"
  11. "testing"
  12. "golang.org/x/net/internal/nettest"
  13. "golang.org/x/net/ipv4"
  14. )
  15. func BenchmarkReadWriteUnicast(b *testing.B) {
  16. c, err := nettest.NewLocalPacketListener("udp4")
  17. if err != nil {
  18. b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
  19. }
  20. defer c.Close()
  21. dst := c.LocalAddr()
  22. wb, rb := []byte("HELLO-R-U-THERE"), make([]byte, 128)
  23. b.Run("NetUDP", func(b *testing.B) {
  24. for i := 0; i < b.N; i++ {
  25. if _, err := c.WriteTo(wb, dst); err != nil {
  26. b.Fatal(err)
  27. }
  28. if _, _, err := c.ReadFrom(rb); err != nil {
  29. b.Fatal(err)
  30. }
  31. }
  32. })
  33. b.Run("IPv4UDP", func(b *testing.B) {
  34. p := ipv4.NewPacketConn(c)
  35. cf := ipv4.FlagTTL | ipv4.FlagInterface
  36. if err := p.SetControlMessage(cf, true); err != nil {
  37. b.Fatal(err)
  38. }
  39. cm := ipv4.ControlMessage{TTL: 1}
  40. ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
  41. if ifi != nil {
  42. cm.IfIndex = ifi.Index
  43. }
  44. for i := 0; i < b.N; i++ {
  45. if _, err := p.WriteTo(wb, &cm, dst); err != nil {
  46. b.Fatal(err)
  47. }
  48. if _, _, _, err := p.ReadFrom(rb); err != nil {
  49. b.Fatal(err)
  50. }
  51. }
  52. })
  53. }
  54. func TestPacketConnConcurrentReadWriteUnicastUDP(t *testing.T) {
  55. switch runtime.GOOS {
  56. case "nacl", "plan9", "windows":
  57. t.Skipf("not supported on %s", runtime.GOOS)
  58. }
  59. c, err := nettest.NewLocalPacketListener("udp4")
  60. if err != nil {
  61. t.Fatal(err)
  62. }
  63. defer c.Close()
  64. p := ipv4.NewPacketConn(c)
  65. defer p.Close()
  66. dst := c.LocalAddr()
  67. ifi := nettest.RoutedInterface("ip4", net.FlagUp|net.FlagLoopback)
  68. cf := ipv4.FlagTTL | ipv4.FlagSrc | ipv4.FlagDst | ipv4.FlagInterface
  69. wb := []byte("HELLO-R-U-THERE")
  70. if err := p.SetControlMessage(cf, true); err != nil { // probe before test
  71. if nettest.ProtocolNotSupported(err) {
  72. t.Skipf("not supported on %s", runtime.GOOS)
  73. }
  74. t.Fatal(err)
  75. }
  76. var wg sync.WaitGroup
  77. reader := func() {
  78. defer wg.Done()
  79. rb := make([]byte, 128)
  80. if n, cm, _, err := p.ReadFrom(rb); err != nil {
  81. t.Error(err)
  82. return
  83. } else if !bytes.Equal(rb[:n], wb) {
  84. t.Errorf("got %v; want %v", rb[:n], wb)
  85. return
  86. } else {
  87. s := cm.String()
  88. if strings.Contains(s, ",") {
  89. t.Errorf("should be space-separated values: %s", s)
  90. }
  91. }
  92. }
  93. writer := func(toggle bool) {
  94. defer wg.Done()
  95. cm := ipv4.ControlMessage{
  96. Src: net.IPv4(127, 0, 0, 1),
  97. }
  98. if ifi != nil {
  99. cm.IfIndex = ifi.Index
  100. }
  101. if err := p.SetControlMessage(cf, toggle); err != nil {
  102. t.Error(err)
  103. return
  104. }
  105. if n, err := p.WriteTo(wb, &cm, dst); err != nil {
  106. t.Error(err)
  107. return
  108. } else if n != len(wb) {
  109. t.Errorf("got %d; want %d", n, len(wb))
  110. return
  111. }
  112. }
  113. const N = 10
  114. wg.Add(N)
  115. for i := 0; i < N; i++ {
  116. go reader()
  117. }
  118. wg.Add(2 * N)
  119. for i := 0; i < 2*N; i++ {
  120. go writer(i%2 != 0)
  121. }
  122. wg.Add(N)
  123. for i := 0; i < N; i++ {
  124. go reader()
  125. }
  126. wg.Wait()
  127. }