socket_go1_9_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. // Copyright 2017 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. // +build go1.9
  5. // +build darwin dragonfly freebsd linux netbsd openbsd solaris
  6. package socket_test
  7. import (
  8. "bytes"
  9. "fmt"
  10. "net"
  11. "runtime"
  12. "testing"
  13. "golang.org/x/net/internal/nettest"
  14. "golang.org/x/net/internal/socket"
  15. )
  16. type mockControl struct {
  17. Level int
  18. Type int
  19. Data []byte
  20. }
  21. func TestControlMessage(t *testing.T) {
  22. for _, tt := range []struct {
  23. cs []mockControl
  24. }{
  25. {
  26. []mockControl{
  27. {Level: 1, Type: 1},
  28. },
  29. },
  30. {
  31. []mockControl{
  32. {Level: 2, Type: 2, Data: []byte{0xfe}},
  33. },
  34. },
  35. {
  36. []mockControl{
  37. {Level: 3, Type: 3, Data: []byte{0xfe, 0xff, 0xff, 0xfe}},
  38. },
  39. },
  40. {
  41. []mockControl{
  42. {Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
  43. },
  44. },
  45. {
  46. []mockControl{
  47. {Level: 4, Type: 4, Data: []byte{0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe}},
  48. {Level: 2, Type: 2, Data: []byte{0xfe}},
  49. },
  50. },
  51. } {
  52. var w []byte
  53. var tailPadLen int
  54. mm := socket.NewControlMessage([]int{0})
  55. for i, c := range tt.cs {
  56. m := socket.NewControlMessage([]int{len(c.Data)})
  57. l := len(m) - len(mm)
  58. if i == len(tt.cs)-1 && l > len(c.Data) {
  59. tailPadLen = l - len(c.Data)
  60. }
  61. w = append(w, m...)
  62. }
  63. var err error
  64. ww := make([]byte, len(w))
  65. copy(ww, w)
  66. m := socket.ControlMessage(ww)
  67. for _, c := range tt.cs {
  68. if err = m.MarshalHeader(c.Level, c.Type, len(c.Data)); err != nil {
  69. t.Fatalf("(%v).MarshalHeader() = %v", tt.cs, err)
  70. }
  71. copy(m.Data(len(c.Data)), c.Data)
  72. m = m.Next(len(c.Data))
  73. }
  74. m = socket.ControlMessage(w)
  75. for _, c := range tt.cs {
  76. m, err = m.Marshal(c.Level, c.Type, c.Data)
  77. if err != nil {
  78. t.Fatalf("(%v).Marshal() = %v", tt.cs, err)
  79. }
  80. }
  81. if !bytes.Equal(ww, w) {
  82. t.Fatalf("got %#v; want %#v", ww, w)
  83. }
  84. ws := [][]byte{w}
  85. if tailPadLen > 0 {
  86. // Test a message with no tail padding.
  87. nopad := w[:len(w)-tailPadLen]
  88. ws = append(ws, [][]byte{nopad}...)
  89. }
  90. for _, w := range ws {
  91. ms, err := socket.ControlMessage(w).Parse()
  92. if err != nil {
  93. t.Fatalf("(%v).Parse() = %v", tt.cs, err)
  94. }
  95. for i, m := range ms {
  96. lvl, typ, dataLen, err := m.ParseHeader()
  97. if err != nil {
  98. t.Fatalf("(%v).ParseHeader() = %v", tt.cs, err)
  99. }
  100. if lvl != tt.cs[i].Level || typ != tt.cs[i].Type || dataLen != len(tt.cs[i].Data) {
  101. t.Fatalf("%v: got %d, %d, %d; want %d, %d, %d", tt.cs[i], lvl, typ, dataLen, tt.cs[i].Level, tt.cs[i].Type, len(tt.cs[i].Data))
  102. }
  103. }
  104. }
  105. }
  106. }
  107. func TestUDP(t *testing.T) {
  108. c, err := nettest.NewLocalPacketListener("udp")
  109. if err != nil {
  110. t.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
  111. }
  112. defer c.Close()
  113. cc, err := socket.NewConn(c.(net.Conn))
  114. if err != nil {
  115. t.Fatal(err)
  116. }
  117. t.Run("Message", func(t *testing.T) {
  118. data := []byte("HELLO-R-U-THERE")
  119. wm := socket.Message{
  120. Buffers: bytes.SplitAfter(data, []byte("-")),
  121. Addr: c.LocalAddr(),
  122. }
  123. if err := cc.SendMsg(&wm, 0); err != nil {
  124. t.Fatal(err)
  125. }
  126. b := make([]byte, 32)
  127. rm := socket.Message{
  128. Buffers: [][]byte{b[:1], b[1:3], b[3:7], b[7:11], b[11:]},
  129. }
  130. if err := cc.RecvMsg(&rm, 0); err != nil {
  131. t.Fatal(err)
  132. }
  133. if !bytes.Equal(b[:rm.N], data) {
  134. t.Fatalf("got %#v; want %#v", b[:rm.N], data)
  135. }
  136. })
  137. switch runtime.GOOS {
  138. case "android", "linux":
  139. t.Run("Messages", func(t *testing.T) {
  140. data := []byte("HELLO-R-U-THERE")
  141. wmbs := bytes.SplitAfter(data, []byte("-"))
  142. wms := []socket.Message{
  143. {Buffers: wmbs[:1], Addr: c.LocalAddr()},
  144. {Buffers: wmbs[1:], Addr: c.LocalAddr()},
  145. }
  146. n, err := cc.SendMsgs(wms, 0)
  147. if err != nil {
  148. t.Fatal(err)
  149. }
  150. if n != len(wms) {
  151. t.Fatalf("got %d; want %d", n, len(wms))
  152. }
  153. b := make([]byte, 32)
  154. rmbs := [][][]byte{{b[:len(wmbs[0])]}, {b[len(wmbs[0]):]}}
  155. rms := []socket.Message{
  156. {Buffers: rmbs[0]},
  157. {Buffers: rmbs[1]},
  158. }
  159. n, err = cc.RecvMsgs(rms, 0)
  160. if err != nil {
  161. t.Fatal(err)
  162. }
  163. if n != len(rms) {
  164. t.Fatalf("got %d; want %d", n, len(rms))
  165. }
  166. nn := 0
  167. for i := 0; i < n; i++ {
  168. nn += rms[i].N
  169. }
  170. if !bytes.Equal(b[:nn], data) {
  171. t.Fatalf("got %#v; want %#v", b[:nn], data)
  172. }
  173. })
  174. }
  175. // The behavior of transmission for zero byte paylaod depends
  176. // on each platform implementation. Some may transmit only
  177. // protocol header and options, other may transmit nothing.
  178. // We test only that SendMsg and SendMsgs will not crash with
  179. // empty buffers.
  180. wm := socket.Message{
  181. Buffers: [][]byte{{}},
  182. Addr: c.LocalAddr(),
  183. }
  184. cc.SendMsg(&wm, 0)
  185. wms := []socket.Message{
  186. {Buffers: [][]byte{{}}, Addr: c.LocalAddr()},
  187. }
  188. cc.SendMsgs(wms, 0)
  189. }
  190. func BenchmarkUDP(b *testing.B) {
  191. c, err := nettest.NewLocalPacketListener("udp")
  192. if err != nil {
  193. b.Skipf("not supported on %s/%s: %v", runtime.GOOS, runtime.GOARCH, err)
  194. }
  195. defer c.Close()
  196. cc, err := socket.NewConn(c.(net.Conn))
  197. if err != nil {
  198. b.Fatal(err)
  199. }
  200. data := []byte("HELLO-R-U-THERE")
  201. wm := socket.Message{
  202. Buffers: [][]byte{data},
  203. Addr: c.LocalAddr(),
  204. }
  205. rm := socket.Message{
  206. Buffers: [][]byte{make([]byte, 128)},
  207. OOB: make([]byte, 128),
  208. }
  209. for M := 1; M <= 1<<9; M = M << 1 {
  210. b.Run(fmt.Sprintf("Iter-%d", M), func(b *testing.B) {
  211. for i := 0; i < b.N; i++ {
  212. for j := 0; j < M; j++ {
  213. if err := cc.SendMsg(&wm, 0); err != nil {
  214. b.Fatal(err)
  215. }
  216. if err := cc.RecvMsg(&rm, 0); err != nil {
  217. b.Fatal(err)
  218. }
  219. }
  220. }
  221. })
  222. switch runtime.GOOS {
  223. case "android", "linux":
  224. wms := make([]socket.Message, M)
  225. for i := range wms {
  226. wms[i].Buffers = [][]byte{data}
  227. wms[i].Addr = c.LocalAddr()
  228. }
  229. rms := make([]socket.Message, M)
  230. for i := range rms {
  231. rms[i].Buffers = [][]byte{make([]byte, 128)}
  232. rms[i].OOB = make([]byte, 128)
  233. }
  234. b.Run(fmt.Sprintf("Batch-%d", M), func(b *testing.B) {
  235. for i := 0; i < b.N; i++ {
  236. if _, err := cc.SendMsgs(wms, 0); err != nil {
  237. b.Fatal(err)
  238. }
  239. if _, err := cc.RecvMsgs(rms, 0); err != nil {
  240. b.Fatal(err)
  241. }
  242. }
  243. })
  244. }
  245. }
  246. }