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.
 
 
 

289 lines
7.6 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 socket provides a portable interface for socket system
  5. // calls.
  6. package socket // import "golang.org/x/net/internal/socket"
  7. import (
  8. "errors"
  9. "net"
  10. "runtime"
  11. "unsafe"
  12. )
  13. var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
  14. // An Option represents a sticky socket option.
  15. type Option struct {
  16. Level int // level
  17. Name int // name; must be equal or greater than 1
  18. Len int // length of value in bytes; must be equal or greater than 1
  19. }
  20. // Get reads a value for the option from the kernel.
  21. // It returns the number of bytes written into b.
  22. func (o *Option) Get(c *Conn, b []byte) (int, error) {
  23. if o.Name < 1 || o.Len < 1 {
  24. return 0, errors.New("invalid option")
  25. }
  26. if len(b) < o.Len {
  27. return 0, errors.New("short buffer")
  28. }
  29. return o.get(c, b)
  30. }
  31. // GetInt returns an integer value for the option.
  32. //
  33. // The Len field of Option must be either 1 or 4.
  34. func (o *Option) GetInt(c *Conn) (int, error) {
  35. if o.Len != 1 && o.Len != 4 {
  36. return 0, errors.New("invalid option")
  37. }
  38. var b []byte
  39. var bb [4]byte
  40. if o.Len == 1 {
  41. b = bb[:1]
  42. } else {
  43. b = bb[:4]
  44. }
  45. n, err := o.get(c, b)
  46. if err != nil {
  47. return 0, err
  48. }
  49. if n != o.Len {
  50. return 0, errors.New("invalid option length")
  51. }
  52. if o.Len == 1 {
  53. return int(b[0]), nil
  54. }
  55. return int(NativeEndian.Uint32(b[:4])), nil
  56. }
  57. // Set writes the option and value to the kernel.
  58. func (o *Option) Set(c *Conn, b []byte) error {
  59. if o.Name < 1 || o.Len < 1 {
  60. return errors.New("invalid option")
  61. }
  62. if len(b) < o.Len {
  63. return errors.New("short buffer")
  64. }
  65. return o.set(c, b)
  66. }
  67. // SetInt writes the option and value to the kernel.
  68. //
  69. // The Len field of Option must be either 1 or 4.
  70. func (o *Option) SetInt(c *Conn, v int) error {
  71. if o.Len != 1 && o.Len != 4 {
  72. return errors.New("invalid option")
  73. }
  74. var b []byte
  75. if o.Len == 1 {
  76. b = []byte{byte(v)}
  77. } else {
  78. var bb [4]byte
  79. NativeEndian.PutUint32(bb[:o.Len], uint32(v))
  80. b = bb[:4]
  81. }
  82. return o.set(c, b)
  83. }
  84. func controlHeaderLen() int {
  85. return roundup(sizeofCmsghdr)
  86. }
  87. func controlMessageLen(dataLen int) int {
  88. return roundup(sizeofCmsghdr) + dataLen
  89. }
  90. // ControlMessageSpace returns the whole length of control message.
  91. func ControlMessageSpace(dataLen int) int {
  92. return roundup(sizeofCmsghdr) + roundup(dataLen)
  93. }
  94. // A ControlMessage represents the head message in a stream of control
  95. // messages.
  96. //
  97. // A control message comprises of a header, data and a few padding
  98. // fields to conform to the interface to the kernel.
  99. //
  100. // See RFC 3542 for further information.
  101. type ControlMessage []byte
  102. // Data returns the data field of the control message at the head on
  103. // m.
  104. func (m ControlMessage) Data(dataLen int) []byte {
  105. l := controlHeaderLen()
  106. if len(m) < l || len(m) < l+dataLen {
  107. return nil
  108. }
  109. return m[l : l+dataLen]
  110. }
  111. // Next returns the control message at the next on m.
  112. //
  113. // Next works only for standard control messages.
  114. func (m ControlMessage) Next(dataLen int) ControlMessage {
  115. l := ControlMessageSpace(dataLen)
  116. if len(m) < l {
  117. return nil
  118. }
  119. return m[l:]
  120. }
  121. // MarshalHeader marshals the header fields of the control message at
  122. // the head on m.
  123. func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
  124. if len(m) < controlHeaderLen() {
  125. return errors.New("short message")
  126. }
  127. h := (*cmsghdr)(unsafe.Pointer(&m[0]))
  128. h.set(controlMessageLen(dataLen), lvl, typ)
  129. return nil
  130. }
  131. // ParseHeader parses and returns the header fields of the control
  132. // message at the head on m.
  133. func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
  134. l := controlHeaderLen()
  135. if len(m) < l {
  136. return 0, 0, 0, errors.New("short message")
  137. }
  138. h := (*cmsghdr)(unsafe.Pointer(&m[0]))
  139. return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
  140. }
  141. // Marshal marshals the control message at the head on m, and returns
  142. // the next control message.
  143. func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
  144. l := len(data)
  145. if len(m) < ControlMessageSpace(l) {
  146. return nil, errors.New("short message")
  147. }
  148. h := (*cmsghdr)(unsafe.Pointer(&m[0]))
  149. h.set(controlMessageLen(l), lvl, typ)
  150. if l > 0 {
  151. copy(m.Data(l), data)
  152. }
  153. return m.Next(l), nil
  154. }
  155. // Parse parses m as a single or multiple control messages.
  156. //
  157. // Parse works for both standard and compatible messages.
  158. func (m ControlMessage) Parse() ([]ControlMessage, error) {
  159. var ms []ControlMessage
  160. for len(m) >= controlHeaderLen() {
  161. h := (*cmsghdr)(unsafe.Pointer(&m[0]))
  162. l := h.len()
  163. if l <= 0 {
  164. return nil, errors.New("invalid header length")
  165. }
  166. if uint64(l) < uint64(controlHeaderLen()) {
  167. return nil, errors.New("invalid message length")
  168. }
  169. if uint64(l) > uint64(len(m)) {
  170. return nil, errors.New("short buffer")
  171. }
  172. // On message reception:
  173. //
  174. // |<- ControlMessageSpace --------------->|
  175. // |<- controlMessageLen ---------->| |
  176. // |<- controlHeaderLen ->| | |
  177. // +---------------+------+---------+------+
  178. // | Header | PadH | Data | PadD |
  179. // +---------------+------+---------+------+
  180. //
  181. // On compatible message reception:
  182. //
  183. // | ... |<- controlMessageLen ----------->|
  184. // | ... |<- controlHeaderLen ->| |
  185. // +-----+---------------+------+----------+
  186. // | ... | Header | PadH | Data |
  187. // +-----+---------------+------+----------+
  188. ms = append(ms, ControlMessage(m[:l]))
  189. ll := l - controlHeaderLen()
  190. if len(m) >= ControlMessageSpace(ll) {
  191. m = m[ControlMessageSpace(ll):]
  192. } else {
  193. m = m[controlMessageLen(ll):]
  194. }
  195. }
  196. return ms, nil
  197. }
  198. // NewControlMessage returns a new stream of control messages.
  199. func NewControlMessage(dataLen []int) ControlMessage {
  200. var l int
  201. for i := range dataLen {
  202. l += ControlMessageSpace(dataLen[i])
  203. }
  204. return make([]byte, l)
  205. }
  206. // A Message represents an IO message.
  207. type Message struct {
  208. // When writing, the Buffers field must contain at least one
  209. // byte to write.
  210. // When reading, the Buffers field will always contain a byte
  211. // to read.
  212. Buffers [][]byte
  213. // OOB contains protocol-specific control or miscellaneous
  214. // ancillary data known as out-of-band data.
  215. OOB []byte
  216. // Addr specifies a destination address when writing.
  217. // It can be nil when the underlying protocol of the raw
  218. // connection uses connection-oriented communication.
  219. // After a successful read, it may contain the source address
  220. // on the received packet.
  221. Addr net.Addr
  222. N int // # of bytes read or written from/to Buffers
  223. NN int // # of bytes read or written from/to OOB
  224. Flags int // protocol-specific information on the received message
  225. }
  226. // RecvMsg wraps recvmsg system call.
  227. //
  228. // The provided flags is a set of platform-dependent flags, such as
  229. // syscall.MSG_PEEK.
  230. func (c *Conn) RecvMsg(m *Message, flags int) error {
  231. return c.recvMsg(m, flags)
  232. }
  233. // SendMsg wraps sendmsg system call.
  234. //
  235. // The provided flags is a set of platform-dependent flags, such as
  236. // syscall.MSG_DONTROUTE.
  237. func (c *Conn) SendMsg(m *Message, flags int) error {
  238. return c.sendMsg(m, flags)
  239. }
  240. // RecvMsgs wraps recvmmsg system call.
  241. //
  242. // It returns the number of processed messages.
  243. //
  244. // The provided flags is a set of platform-dependent flags, such as
  245. // syscall.MSG_PEEK.
  246. //
  247. // Only Linux supports this.
  248. func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
  249. return c.recvMsgs(ms, flags)
  250. }
  251. // SendMsgs wraps sendmmsg system call.
  252. //
  253. // It returns the number of processed messages.
  254. //
  255. // The provided flags is a set of platform-dependent flags, such as
  256. // syscall.MSG_DONTROUTE.
  257. //
  258. // Only Linux supports this.
  259. func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
  260. return c.sendMsgs(ms, flags)
  261. }