1
0

socket.go 7.5 KB

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