endpoint.go raw

   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  
   5  package ipv4
   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 and RawConn are
  17  // not implemented.
  18  
  19  // A Conn represents a network endpoint that uses the IPv4 transport.
  20  // It is used to control basic IP-level socket options such as TOS and
  21  // TTL.
  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  // NewConn returns a new Conn.
  33  func NewConn(c net.Conn) *Conn {
  34  	cc, _ := socket.NewConn(c)
  35  	return &Conn{
  36  		genericOpt: genericOpt{Conn: cc},
  37  	}
  38  }
  39  
  40  // A PacketConn represents a packet network endpoint that uses the
  41  // IPv4 transport. It is used to control several IP-level socket
  42  // options including multicasting. It also provides datagram based
  43  // network I/O methods specific to the IPv4 and higher layer protocols
  44  // such as UDP.
  45  type PacketConn struct {
  46  	genericOpt
  47  	dgramOpt
  48  	payloadHandler
  49  }
  50  
  51  type dgramOpt struct {
  52  	*socket.Conn
  53  }
  54  
  55  func (c *dgramOpt) ok() bool { return c != nil && c.Conn != nil }
  56  
  57  // SetControlMessage sets the per packet IP-level socket options.
  58  func (c *PacketConn) SetControlMessage(cf ControlFlags, on bool) error {
  59  	if !c.payloadHandler.ok() {
  60  		return errInvalidConn
  61  	}
  62  	return setControlMessage(c.dgramOpt.Conn, &c.payloadHandler.rawOpt, cf, on)
  63  }
  64  
  65  // SetDeadline sets the read and write deadlines associated with the
  66  // endpoint.
  67  func (c *PacketConn) SetDeadline(t time.Time) error {
  68  	if !c.payloadHandler.ok() {
  69  		return errInvalidConn
  70  	}
  71  	return c.payloadHandler.PacketConn.SetDeadline(t)
  72  }
  73  
  74  // SetReadDeadline sets the read deadline associated with the
  75  // endpoint.
  76  func (c *PacketConn) SetReadDeadline(t time.Time) error {
  77  	if !c.payloadHandler.ok() {
  78  		return errInvalidConn
  79  	}
  80  	return c.payloadHandler.PacketConn.SetReadDeadline(t)
  81  }
  82  
  83  // SetWriteDeadline sets the write deadline associated with the
  84  // endpoint.
  85  func (c *PacketConn) SetWriteDeadline(t time.Time) error {
  86  	if !c.payloadHandler.ok() {
  87  		return errInvalidConn
  88  	}
  89  	return c.payloadHandler.PacketConn.SetWriteDeadline(t)
  90  }
  91  
  92  // Close closes the endpoint.
  93  func (c *PacketConn) Close() error {
  94  	if !c.payloadHandler.ok() {
  95  		return errInvalidConn
  96  	}
  97  	return c.payloadHandler.PacketConn.Close()
  98  }
  99  
 100  // NewPacketConn returns a new PacketConn using c as its underlying
 101  // transport.
 102  func NewPacketConn(c net.PacketConn) *PacketConn {
 103  	cc, _ := socket.NewConn(c.(net.Conn))
 104  	p := &PacketConn{
 105  		genericOpt:     genericOpt{Conn: cc},
 106  		dgramOpt:       dgramOpt{Conn: cc},
 107  		payloadHandler: payloadHandler{PacketConn: c, Conn: cc},
 108  	}
 109  	return p
 110  }
 111  
 112  // A RawConn represents a packet network endpoint that uses the IPv4
 113  // transport. It is used to control several IP-level socket options
 114  // including IPv4 header manipulation. It also provides datagram
 115  // based network I/O methods specific to the IPv4 and higher layer
 116  // protocols that handle IPv4 datagram directly such as OSPF, GRE.
 117  type RawConn struct {
 118  	genericOpt
 119  	dgramOpt
 120  	packetHandler
 121  }
 122  
 123  // SetControlMessage sets the per packet IP-level socket options.
 124  func (c *RawConn) SetControlMessage(cf ControlFlags, on bool) error {
 125  	if !c.packetHandler.ok() {
 126  		return errInvalidConn
 127  	}
 128  	return setControlMessage(c.dgramOpt.Conn, &c.packetHandler.rawOpt, cf, on)
 129  }
 130  
 131  // SetDeadline sets the read and write deadlines associated with the
 132  // endpoint.
 133  func (c *RawConn) SetDeadline(t time.Time) error {
 134  	if !c.packetHandler.ok() {
 135  		return errInvalidConn
 136  	}
 137  	return c.packetHandler.IPConn.SetDeadline(t)
 138  }
 139  
 140  // SetReadDeadline sets the read deadline associated with the
 141  // endpoint.
 142  func (c *RawConn) SetReadDeadline(t time.Time) error {
 143  	if !c.packetHandler.ok() {
 144  		return errInvalidConn
 145  	}
 146  	return c.packetHandler.IPConn.SetReadDeadline(t)
 147  }
 148  
 149  // SetWriteDeadline sets the write deadline associated with the
 150  // endpoint.
 151  func (c *RawConn) SetWriteDeadline(t time.Time) error {
 152  	if !c.packetHandler.ok() {
 153  		return errInvalidConn
 154  	}
 155  	return c.packetHandler.IPConn.SetWriteDeadline(t)
 156  }
 157  
 158  // Close closes the endpoint.
 159  func (c *RawConn) Close() error {
 160  	if !c.packetHandler.ok() {
 161  		return errInvalidConn
 162  	}
 163  	return c.packetHandler.IPConn.Close()
 164  }
 165  
 166  // NewRawConn returns a new RawConn using c as its underlying
 167  // transport.
 168  func NewRawConn(c net.PacketConn) (*RawConn, error) {
 169  	cc, err := socket.NewConn(c.(net.Conn))
 170  	if err != nil {
 171  		return nil, err
 172  	}
 173  	r := &RawConn{
 174  		genericOpt:    genericOpt{Conn: cc},
 175  		dgramOpt:      dgramOpt{Conn: cc},
 176  		packetHandler: packetHandler{IPConn: c.(*net.IPConn), Conn: cc},
 177  	}
 178  	so, ok := sockOpts[ssoHeaderPrepend]
 179  	if !ok {
 180  		return nil, errNotImplemented
 181  	}
 182  	if err := so.SetInt(r.dgramOpt.Conn, boolint(true)); err != nil {
 183  		return nil, err
 184  	}
 185  	return r, nil
 186  }
 187