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.

128 lines
3.1 KiB

  1. // Copyright 2013 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 ipv6
  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 are not
  14. // implemented.
  15. // A Conn represents a network endpoint that uses IPv6 transport.
  16. // It allows to set basic IP-level socket options such as traffic
  17. // class and hop limit.
  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. // PathMTU returns a path MTU value for the destination associated
  26. // with the endpoint.
  27. func (c *Conn) PathMTU() (int, error) {
  28. if !c.ok() {
  29. return 0, syscall.EINVAL
  30. }
  31. so, ok := sockOpts[ssoPathMTU]
  32. if !ok {
  33. return 0, errOpNoSupport
  34. }
  35. _, mtu, err := so.getMTUInfo(c.Conn)
  36. if err != nil {
  37. return 0, err
  38. }
  39. return mtu, nil
  40. }
  41. // NewConn returns a new Conn.
  42. func NewConn(c net.Conn) *Conn {
  43. cc, _ := socket.NewConn(c)
  44. return &Conn{
  45. genericOpt: genericOpt{Conn: cc},
  46. }
  47. }
  48. // A PacketConn represents a packet network endpoint that uses IPv6
  49. // transport. It is used to control several IP-level socket options
  50. // including IPv6 header manipulation. It also provides datagram
  51. // based network I/O methods specific to the IPv6 and higher layer
  52. // protocols such as OSPF, GRE, and UDP.
  53. type PacketConn struct {
  54. genericOpt
  55. dgramOpt
  56. payloadHandler
  57. }
  58. type dgramOpt struct {
  59. *socket.Conn
  60. }
  61. func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
  62. // SetControlMessage allows to receive the per packet basis IP-level
  63. // socket options.
  64. func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
  65. if !c.payloadHandler.ok() {
  66. return syscall.EINVAL
  67. }
  68. return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
  69. }
  70. // SetDeadline sets the read and write deadlines associated with the
  71. // endpoint.
  72. func (c *PacketConn) SetDeadline(t time.Time) error {
  73. if !c.payloadHandler.ok() {
  74. return syscall.EINVAL
  75. }
  76. return c.payloadHandler.SetDeadline(t)
  77. }
  78. // SetReadDeadline sets the read deadline associated with the
  79. // endpoint.
  80. func (c *PacketConn) SetReadDeadline(t time.Time) error {
  81. if !c.payloadHandler.ok() {
  82. return syscall.EINVAL
  83. }
  84. return c.payloadHandler.SetReadDeadline(t)
  85. }
  86. // SetWriteDeadline sets the write deadline associated with the
  87. // endpoint.
  88. func (c *PacketConn) SetWriteDeadline(t time.Time) error {
  89. if !c.payloadHandler.ok() {
  90. return syscall.EINVAL
  91. }
  92. return c.payloadHandler.SetWriteDeadline(t)
  93. }
  94. // Close closes the endpoint.
  95. func (c *PacketConn) Close() error {
  96. if !c.payloadHandler.ok() {
  97. return syscall.EINVAL
  98. }
  99. return c.payloadHandler.Close()
  100. }
  101. // NewPacketConn returns a new PacketConn using c as its underlying
  102. // transport.
  103. func NewPacketConn(c net.PacketConn) *PacketConn {
  104. cc, _ := socket.NewConn(c.(net.Conn))
  105. return &PacketConn{
  106. genericOpt: genericOpt{Conn: cc},
  107. dgramOpt: dgramOpt{Conn: cc},
  108. payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
  109. }
  110. }