socket.go 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. // m.
  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 m.
  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 m.
  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 m.
  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 m, 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 m 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 l <= 0 {
  162. return nil, errors.New("invalid header length")
  163. }
  164. if uint64(l) < uint64(controlHeaderLen()) {
  165. return nil, errors.New("invalid message length")
  166. }
  167. if uint64(l) > uint64(len(m)) {
  168. return nil, errors.New("short buffer")
  169. }
  170. // On message reception:
  171. //
  172. // |<- ControlMessageSpace --------------->|
  173. // |<- controlMessageLen ---------->| |
  174. // |<- controlHeaderLen ->| | |
  175. // +---------------+------+---------+------+
  176. // | Header | PadH | Data | PadD |
  177. // +---------------+------+---------+------+
  178. //
  179. // On compatible message reception:
  180. //
  181. // | ... |<- controlMessageLen ----------->|
  182. // | ... |<- controlHeaderLen ->| |
  183. // +-----+---------------+------+----------+
  184. // | ... | Header | PadH | Data |
  185. // +-----+---------------+------+----------+
  186. ms = append(ms, ControlMessage(m[:l]))
  187. ll := l - controlHeaderLen()
  188. if len(m) >= ControlMessageSpace(ll) {
  189. m = m[ControlMessageSpace(ll):]
  190. } else {
  191. m = m[controlMessageLen(ll):]
  192. }
  193. }
  194. return ms, nil
  195. }
  196. // NewControlMessage returns a new stream of control messages.
  197. func NewControlMessage(dataLen []int) ControlMessage {
  198. var l int
  199. for i := range dataLen {
  200. l += ControlMessageSpace(dataLen[i])
  201. }
  202. return make([]byte, l)
  203. }
  204. // A Message represents an IO message.
  205. type Message struct {
  206. // When writing, the Buffers field must contain at least one
  207. // byte to write.
  208. // When reading, the Buffers field will always contain a byte
  209. // to read.
  210. Buffers [][]byte
  211. // OOB contains protocol-specific control or miscellaneous
  212. // ancillary data known as out-of-band data.
  213. OOB []byte
  214. // Addr specifies a destination address when writing.
  215. // It can be nil when the underlying protocol of the raw
  216. // connection uses connection-oriented communication.
  217. // After a successful read, it may contain the source address
  218. // on the received packet.
  219. Addr net.Addr
  220. N int // # of bytes read or written from/to Buffers
  221. NN int // # of bytes read or written from/to OOB
  222. Flags int // protocol-specific information on the received message
  223. }
  224. // RecvMsg wraps recvmsg system call.
  225. //
  226. // The provided flags is a set of platform-dependent flags, such as
  227. // syscall.MSG_PEEK.
  228. func (c *Conn) RecvMsg(m *Message, flags int) error {
  229. return c.recvMsg(m, flags)
  230. }
  231. // SendMsg wraps sendmsg system call.
  232. //
  233. // The provided flags is a set of platform-dependent flags, such as
  234. // syscall.MSG_DONTROUTE.
  235. func (c *Conn) SendMsg(m *Message, flags int) error {
  236. return c.sendMsg(m, flags)
  237. }
  238. // RecvMsgs wraps recvmmsg system call.
  239. //
  240. // It returns the number of processed messages.
  241. //
  242. // The provided flags is a set of platform-dependent flags, such as
  243. // syscall.MSG_PEEK.
  244. //
  245. // Only Linux supports this.
  246. func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
  247. return c.recvMsgs(ms, flags)
  248. }
  249. // SendMsgs wraps sendmmsg system call.
  250. //
  251. // It returns the number of processed messages.
  252. //
  253. // The provided flags is a set of platform-dependent flags, such as
  254. // syscall.MSG_DONTROUTE.
  255. //
  256. // Only Linux supports this.
  257. func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
  258. return c.sendMsgs(ms, flags)
  259. }