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.

187 lines
4.9 KiB

  1. // Copyright 2012 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. "syscall"
  8. "time"
  9. "golang.org/x/net/internal/socket"
  10. )
  11. // BUG(mikio): On Windows, the JoinSourceSpecificGroup,
  12. // LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
  13. // IncludeSourceSpecificGroup methods of PacketConn and RawConn are
  14. // not implemented.
  15. // A Conn represents a network endpoint that uses the IPv4 transport.
  16. // It is used to control basic IP-level socket options such as TOS and
  17. // TTL.
  18. type Conn struct {
  19. genericOpt
  20. }
  21. type genericOpt struct {
  22. *socket.Conn
  23. }
  24. func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
  25. // NewConn returns a new Conn.
  26. func NewConn(c net.Conn) *Conn {
  27. cc, _ := socket.NewConn(c)
  28. return &Conn{
  29. genericOpt: genericOpt{Conn: cc},
  30. }
  31. }
  32. // A PacketConn represents a packet network endpoint that uses the
  33. // IPv4 transport. It is used to control several IP-level socket
  34. // options including multicasting. It also provides datagram based
  35. // network I/O methods specific to the IPv4 and higher layer protocols
  36. // such as UDP.
  37. type PacketConn struct {
  38. genericOpt
  39. dgramOpt
  40. payloadHandler
  41. }
  42. type dgramOpt struct {
  43. *socket.Conn
  44. }
  45. func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
  46. // SetControlMessage sets the per packet IP-level socket options.
  47. func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
  48. if !c.payloadHandler.ok() {
  49. return syscall.EINVAL
  50. }
  51. return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
  52. }
  53. // SetDeadline sets the read and write deadlines associated with the
  54. // endpoint.
  55. func (c *PacketConn) SetDeadline(t time.Time) error {
  56. if !c.payloadHandler.ok() {
  57. return syscall.EINVAL
  58. }
  59. return c.payloadHandler.PacketConn.SetDeadline(t)
  60. }
  61. // SetReadDeadline sets the read deadline associated with the
  62. // endpoint.
  63. func (c *PacketConn) SetReadDeadline(t time.Time) error {
  64. if !c.payloadHandler.ok() {
  65. return syscall.EINVAL
  66. }
  67. return c.payloadHandler.PacketConn.SetReadDeadline(t)
  68. }
  69. // SetWriteDeadline sets the write deadline associated with the
  70. // endpoint.
  71. func (c *PacketConn) SetWriteDeadline(t time.Time) error {
  72. if !c.payloadHandler.ok() {
  73. return syscall.EINVAL
  74. }
  75. return c.payloadHandler.PacketConn.SetWriteDeadline(t)
  76. }
  77. // Close closes the endpoint.
  78. func (c *PacketConn) Close() error {
  79. if !c.payloadHandler.ok() {
  80. return syscall.EINVAL
  81. }
  82. return c.payloadHandler.PacketConn.Close()
  83. }
  84. // NewPacketConn returns a new PacketConn using c as its underlying
  85. // transport.
  86. func NewPacketConn(c net.PacketConn) *PacketConn {
  87. cc, _ := socket.NewConn(c.(net.Conn))
  88. p := &PacketConn{
  89. genericOpt: genericOpt{Conn: cc},
  90. dgramOpt: dgramOpt{Conn: cc},
  91. payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
  92. }
  93. return p
  94. }
  95. // A RawConn represents a packet network endpoint that uses the IPv4
  96. // transport. It is used to control several IP-level socket options
  97. // including IPv4 header manipulation. It also provides datagram
  98. // based network I/O methods specific to the IPv4 and higher layer
  99. // protocols that handle IPv4 datagram directly such as OSPF, GRE.
  100. type RawConn struct {
  101. genericOpt
  102. dgramOpt
  103. packetHandler
  104. }
  105. // SetControlMessage sets the per packet IP-level socket options.
  106. func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
  107. if !c.packetHandler.ok() {
  108. return syscall.EINVAL
  109. }
  110. return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
  111. }
  112. // SetDeadline sets the read and write deadlines associated with the
  113. // endpoint.
  114. func (c *RawConn) SetDeadline(t time.Time) error {
  115. if !c.packetHandler.ok() {
  116. return syscall.EINVAL
  117. }
  118. return c.packetHandler.IPConn.SetDeadline(t)
  119. }
  120. // SetReadDeadline sets the read deadline associated with the
  121. // endpoint.
  122. func (c *RawConn) SetReadDeadline(t time.Time) error {
  123. if !c.packetHandler.ok() {
  124. return syscall.EINVAL
  125. }
  126. return c.packetHandler.IPConn.SetReadDeadline(t)
  127. }
  128. // SetWriteDeadline sets the write deadline associated with the
  129. // endpoint.
  130. func (c *RawConn) SetWriteDeadline(t time.Time) error {
  131. if !c.packetHandler.ok() {
  132. return syscall.EINVAL
  133. }
  134. return c.packetHandler.IPConn.SetWriteDeadline(t)
  135. }
  136. // Close closes the endpoint.
  137. func (c *RawConn) Close() error {
  138. if !c.packetHandler.ok() {
  139. return syscall.EINVAL
  140. }
  141. return c.packetHandler.IPConn.Close()
  142. }
  143. // NewRawConn returns a new RawConn using c as its underlying
  144. // transport.
  145. func NewRawConn(c net.PacketConn) (*RawConn, error) {
  146. cc, err := socket.NewConn(c.(net.Conn))
  147. if err != nil {
  148. return nil, err
  149. }
  150. r := &RawConn{
  151. genericOpt: genericOpt{Conn: cc},
  152. dgramOpt: dgramOpt{Conn: cc},
  153. packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},
  154. }
  155. so, ok := sockOpts[ssoHeaderPrepend]
  156. if !ok {
  157. return nil, errOpNoSupport
  158. }
  159. if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
  160. return nil, err
  161. }
  162. return r, nil
  163. }