endpoint.go raw

   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  
   5  package ipv6
   6  
   7  import (
   8  	"net"
   9  	"time"
  10  
  11  	"golang.org/x/net/internal/socket"
  12  )
  13  
  14  // BUG(mikio): On Windows, the JoinSourceSpecificGroup,
  15  // LeaveSourceSpecificGroup, ExcludeSourceSpecificGroup and
  16  // IncludeSourceSpecificGroup methods of PacketConn are not
  17  // implemented.
  18  
  19  // A Conn represents a network endpoint that uses IPv6 transport.
  20  // It allows to set basic IP-level socket options such as traffic
  21  // class and hop limit.
  22  type Conn struct {
  23  	genericOpt
  24  }
  25  
  26  type genericOpt struct {
  27  	*socket.Conn
  28  }
  29  
  30  func (c *genericOpt) ok() bool { return c != nil && c.Conn != nil }
  31  
  32  // PathMTU returns a path MTU value for the destination associated
  33  // with the endpoint.
  34  func (c *Conn) PathMTU() (int, error) {
  35  	if !c.ok() {
  36  		return 0, errInvalidConn
  37  	}
  38  	so, ok := sockOpts[ssoPathMTU]
  39  	if !ok {
  40  		return 0, errNotImplemented
  41  	}
  42  	_, mtu, err := so.getMTUInfo(c.Conn)
  43  	if err != nil {
  44  		return 0, err
  45  	}
  46  	return mtu, nil
  47  }
  48  
  49  // NewConn returns a new Conn.
  50  func NewConn(c net.Conn) *Conn {
  51  	cc, _ := socket.NewConn(c)
  52  	return &Conn{
  53  		genericOpt: genericOpt{Conn: cc},
  54  	}
  55  }
  56  
  57  // A PacketConn represents a packet network endpoint that uses IPv6
  58  // transport. It is used to control several IP-level socket options
  59  // including IPv6 header manipulation. It also provides datagram
  60  // based network I/O methods specific to the IPv6 and higher layer
  61  // protocols such as OSPF, GRE, and UDP.
  62  type PacketConn struct {
  63  	genericOpt
  64  	dgramOpt
  65  	payloadHandler
  66  }
  67  
  68  type dgramOpt struct {
  69  	*socket.Conn
  70  }
  71  
  72  func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
  73  
  74  // SetControlMessage allows to receive the per packet basis IP-level
  75  // socket options.
  76  func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
  77  	if !c.payloadHandler.ok() {
  78  		return errInvalidConn
  79  	}
  80  	return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
  81  }
  82  
  83  // SetDeadline sets the read and write deadlines associated with the
  84  // endpoint.
  85  func (c *PacketConn) SetDeadline(t time.Time) error {
  86  	if !c.payloadHandler.ok() {
  87  		return errInvalidConn
  88  	}
  89  	return c.payloadHandler.SetDeadline(t)
  90  }
  91  
  92  // SetReadDeadline sets the read deadline associated with the
  93  // endpoint.
  94  func (c *PacketConn) SetReadDeadline(t time.Time) error {
  95  	if !c.payloadHandler.ok() {
  96  		return errInvalidConn
  97  	}
  98  	return c.payloadHandler.SetReadDeadline(t)
  99  }
 100  
 101  // SetWriteDeadline sets the write deadline associated with the
 102  // endpoint.
 103  func (c *PacketConn) SetWriteDeadline(t time.Time) error {
 104  	if !c.payloadHandler.ok() {
 105  		return errInvalidConn
 106  	}
 107  	return c.payloadHandler.SetWriteDeadline(t)
 108  }
 109  
 110  // Close closes the endpoint.
 111  func (c *PacketConn) Close() error {
 112  	if !c.payloadHandler.ok() {
 113  		return errInvalidConn
 114  	}
 115  	return c.payloadHandler.Close()
 116  }
 117  
 118  // NewPacketConn returns a new PacketConn using c as its underlying
 119  // transport.
 120  func NewPacketConn(c net.PacketConn) *PacketConn {
 121  	cc, _ := socket.NewConn(c.(net.Conn))
 122  	return &PacketConn{
 123  		genericOpt:     genericOpt{Conn: cc},
 124  		dgramOpt:       dgramOpt{Conn: cc},
 125  		payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
 126  	}
 127  }
 128