batch.go 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  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. package ipv4
  6. import (
  7. "net"
  8. "runtime"
  9. "golang.org/x/net/internal/socket"
  10. )
  11. // BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
  12. // PacketConn are not implemented.
  13. // BUG(mikio): On Windows, the ReadBatch and WriteBatch methods of
  14. // RawConn are not implemented.
  15. // A Message represents an IO message.
  16. //
  17. // type Message struct {
  18. // Buffers [][]byte
  19. // OOB []byte
  20. // Addr net.Addr
  21. // N int
  22. // NN int
  23. // Flags int
  24. // }
  25. //
  26. // The Buffers fields represents a list of contiguous buffers, which
  27. // can be used for vectored IO, for example, putting a header and a
  28. // payload in each slice.
  29. // When writing, the Buffers field must contain at least one byte to
  30. // write.
  31. // When reading, the Buffers field will always contain a byte to read.
  32. //
  33. // The OOB field contains protocol-specific control or miscellaneous
  34. // ancillary data known as out-of-band data.
  35. // It can be nil when not required.
  36. //
  37. // The Addr field specifies a destination address when writing.
  38. // It can be nil when the underlying protocol of the endpoint uses
  39. // connection-oriented communication.
  40. // After a successful read, it may contain the source address on the
  41. // received packet.
  42. //
  43. // The N field indicates the number of bytes read or written from/to
  44. // Buffers.
  45. //
  46. // The NN field indicates the number of bytes read or written from/to
  47. // OOB.
  48. //
  49. // The Flags field contains protocol-specific information on the
  50. // received message.
  51. type Message = socket.Message
  52. // ReadBatch reads a batch of messages.
  53. //
  54. // The provided flags is a set of platform-dependent flags, such as
  55. // syscall.MSG_PEEK.
  56. //
  57. // On a successful read it returns the number of messages received, up
  58. // to len(ms).
  59. //
  60. // On Linux, a batch read will be optimized.
  61. // On other platforms, this method will read only a single message.
  62. //
  63. // Unlike the ReadFrom method, it doesn't strip the IPv4 header
  64. // followed by option headers from the received IPv4 datagram when the
  65. // underlying transport is net.IPConn. Each Buffers field of Message
  66. // must be large enough to accommodate an IPv4 header and option
  67. // headers.
  68. func (c *payloadHandler) ReadBatch(ms []Message, flags int) (int, error) {
  69. if !c.ok() {
  70. return 0, errInvalidConn
  71. }
  72. switch runtime.GOOS {
  73. case "linux":
  74. n, err := c.RecvMsgs([]socket.Message(ms), flags)
  75. if err != nil {
  76. err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  77. }
  78. return n, err
  79. default:
  80. n := 1
  81. err := c.RecvMsg(&ms[0], flags)
  82. if err != nil {
  83. n = 0
  84. err = &net.OpError{Op: "read", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  85. }
  86. return n, err
  87. }
  88. }
  89. // WriteBatch writes a batch of messages.
  90. //
  91. // The provided flags is a set of platform-dependent flags, such as
  92. // syscall.MSG_DONTROUTE.
  93. //
  94. // It returns the number of messages written on a successful write.
  95. //
  96. // On Linux, a batch write will be optimized.
  97. // On other platforms, this method will write only a single message.
  98. func (c *payloadHandler) WriteBatch(ms []Message, flags int) (int, error) {
  99. if !c.ok() {
  100. return 0, errInvalidConn
  101. }
  102. switch runtime.GOOS {
  103. case "linux":
  104. n, err := c.SendMsgs([]socket.Message(ms), flags)
  105. if err != nil {
  106. err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  107. }
  108. return n, err
  109. default:
  110. n := 1
  111. err := c.SendMsg(&ms[0], flags)
  112. if err != nil {
  113. n = 0
  114. err = &net.OpError{Op: "write", Net: c.PacketConn.LocalAddr().Network(), Source: c.PacketConn.LocalAddr(), Err: err}
  115. }
  116. return n, err
  117. }
  118. }
  119. // ReadBatch reads a batch of messages.
  120. //
  121. // The provided flags is a set of platform-dependent flags, such as
  122. // syscall.MSG_PEEK.
  123. //
  124. // On a successful read it returns the number of messages received, up
  125. // to len(ms).
  126. //
  127. // On Linux, a batch read will be optimized.
  128. // On other platforms, this method will read only a single message.
  129. func (c *packetHandler) ReadBatch(ms []Message, flags int) (int, error) {
  130. if !c.ok() {
  131. return 0, errInvalidConn
  132. }
  133. switch runtime.GOOS {
  134. case "linux":
  135. n, err := c.RecvMsgs([]socket.Message(ms), flags)
  136. if err != nil {
  137. err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  138. }
  139. return n, err
  140. default:
  141. n := 1
  142. err := c.RecvMsg(&ms[0], flags)
  143. if err != nil {
  144. n = 0
  145. err = &net.OpError{Op: "read", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  146. }
  147. return n, err
  148. }
  149. }
  150. // WriteBatch writes a batch of messages.
  151. //
  152. // The provided flags is a set of platform-dependent flags, such as
  153. // syscall.MSG_DONTROUTE.
  154. //
  155. // It returns the number of messages written on a successful write.
  156. //
  157. // On Linux, a batch write will be optimized.
  158. // On other platforms, this method will write only a single message.
  159. func (c *packetHandler) WriteBatch(ms []Message, flags int) (int, error) {
  160. if !c.ok() {
  161. return 0, errInvalidConn
  162. }
  163. switch runtime.GOOS {
  164. case "linux":
  165. n, err := c.SendMsgs([]socket.Message(ms), flags)
  166. if err != nil {
  167. err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  168. }
  169. return n, err
  170. default:
  171. n := 1
  172. err := c.SendMsg(&ms[0], flags)
  173. if err != nil {
  174. n = 0
  175. err = &net.OpError{Op: "write", Net: c.IPConn.LocalAddr().Network(), Source: c.IPConn.LocalAddr(), Err: err}
  176. }
  177. return n, err
  178. }
  179. }