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.
 
 
 

189 rivejä
5.5 KiB

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