socket.go raw

   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  
   5  // Package socket provides a portable interface for socket system
   6  // calls.
   7  package socket // import "golang.org/x/net/internal/socket"
   8  
   9  import (
  10  	"errors"
  11  	"net"
  12  	"runtime"
  13  	"unsafe"
  14  )
  15  
  16  var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)
  17  
  18  // An Option represents a sticky socket option.
  19  type Option struct {
  20  	Level int // level
  21  	Name  int // name; must be equal or greater than 1
  22  	Len   int // length of value in bytes; must be equal or greater than 1
  23  }
  24  
  25  // Get reads a value for the option from the kernel.
  26  // It returns the number of bytes written into b.
  27  func (o *Option) Get(c *Conn, b []byte) (int, error) {
  28  	if o.Name < 1 || o.Len < 1 {
  29  		return 0, errors.New("invalid option")
  30  	}
  31  	if len(b) < o.Len {
  32  		return 0, errors.New("short buffer")
  33  	}
  34  	return o.get(c, b)
  35  }
  36  
  37  // GetInt returns an integer value for the option.
  38  //
  39  // The Len field of Option must be either 1 or 4.
  40  func (o *Option) GetInt(c *Conn) (int, error) {
  41  	if o.Len != 1 && o.Len != 4 {
  42  		return 0, errors.New("invalid option")
  43  	}
  44  	var b []byte
  45  	var bb [4]byte
  46  	if o.Len == 1 {
  47  		b = bb[:1]
  48  	} else {
  49  		b = bb[:4]
  50  	}
  51  	n, err := o.get(c, b)
  52  	if err != nil {
  53  		return 0, err
  54  	}
  55  	if n != o.Len {
  56  		return 0, errors.New("invalid option length")
  57  	}
  58  	if o.Len == 1 {
  59  		return int(b[0]), nil
  60  	}
  61  	return int(NativeEndian.Uint32(b[:4])), nil
  62  }
  63  
  64  // Set writes the option and value to the kernel.
  65  func (o *Option) Set(c *Conn, b []byte) error {
  66  	if o.Name < 1 || o.Len < 1 {
  67  		return errors.New("invalid option")
  68  	}
  69  	if len(b) < o.Len {
  70  		return errors.New("short buffer")
  71  	}
  72  	return o.set(c, b)
  73  }
  74  
  75  // SetInt writes the option and value to the kernel.
  76  //
  77  // The Len field of Option must be either 1 or 4.
  78  func (o *Option) SetInt(c *Conn, v int) error {
  79  	if o.Len != 1 && o.Len != 4 {
  80  		return errors.New("invalid option")
  81  	}
  82  	var b []byte
  83  	if o.Len == 1 {
  84  		b = []byte{byte(v)}
  85  	} else {
  86  		var bb [4]byte
  87  		NativeEndian.PutUint32(bb[:o.Len], uint32(v))
  88  		b = bb[:4]
  89  	}
  90  	return o.set(c, b)
  91  }
  92  
  93  // ControlMessageSpace returns the whole length of control message.
  94  func ControlMessageSpace(dataLen int) int {
  95  	return controlMessageSpace(dataLen)
  96  }
  97  
  98  // A ControlMessage represents the head message in a stream of control
  99  // messages.
 100  //
 101  // A control message comprises of a header, data and a few padding
 102  // fields to conform to the interface to the kernel.
 103  //
 104  // See RFC 3542 for further information.
 105  type ControlMessage []byte
 106  
 107  // Data returns the data field of the control message at the head on
 108  // m.
 109  func (m ControlMessage) Data(dataLen int) []byte {
 110  	l := controlHeaderLen()
 111  	if len(m) < l || len(m) < l+dataLen {
 112  		return nil
 113  	}
 114  	return m[l : l+dataLen]
 115  }
 116  
 117  // Next returns the control message at the next on m.
 118  //
 119  // Next works only for standard control messages.
 120  func (m ControlMessage) Next(dataLen int) ControlMessage {
 121  	l := ControlMessageSpace(dataLen)
 122  	if len(m) < l {
 123  		return nil
 124  	}
 125  	return m[l:]
 126  }
 127  
 128  // MarshalHeader marshals the header fields of the control message at
 129  // the head on m.
 130  func (m ControlMessage) MarshalHeader(lvl, typ, dataLen int) error {
 131  	if len(m) < controlHeaderLen() {
 132  		return errors.New("short message")
 133  	}
 134  	h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 135  	h.set(controlMessageLen(dataLen), lvl, typ)
 136  	return nil
 137  }
 138  
 139  // ParseHeader parses and returns the header fields of the control
 140  // message at the head on m.
 141  func (m ControlMessage) ParseHeader() (lvl, typ, dataLen int, err error) {
 142  	l := controlHeaderLen()
 143  	if len(m) < l {
 144  		return 0, 0, 0, errors.New("short message")
 145  	}
 146  	h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 147  	return h.lvl(), h.typ(), int(uint64(h.len()) - uint64(l)), nil
 148  }
 149  
 150  // Marshal marshals the control message at the head on m, and returns
 151  // the next control message.
 152  func (m ControlMessage) Marshal(lvl, typ int, data []byte) (ControlMessage, error) {
 153  	l := len(data)
 154  	if len(m) < ControlMessageSpace(l) {
 155  		return nil, errors.New("short message")
 156  	}
 157  	h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 158  	h.set(controlMessageLen(l), lvl, typ)
 159  	if l > 0 {
 160  		copy(m.Data(l), data)
 161  	}
 162  	return m.Next(l), nil
 163  }
 164  
 165  // Parse parses m as a single or multiple control messages.
 166  //
 167  // Parse works for both standard and compatible messages.
 168  func (m ControlMessage) Parse() ([]ControlMessage, error) {
 169  	var ms []ControlMessage
 170  	for len(m) >= controlHeaderLen() {
 171  		h := (*cmsghdr)(unsafe.Pointer(&m[0]))
 172  		l := h.len()
 173  		if l <= 0 {
 174  			return nil, errors.New("invalid header length")
 175  		}
 176  		if uint64(l) < uint64(controlHeaderLen()) {
 177  			return nil, errors.New("invalid message length")
 178  		}
 179  		if uint64(l) > uint64(len(m)) {
 180  			return nil, errors.New("short buffer")
 181  		}
 182  		// On message reception:
 183  		//
 184  		// |<- ControlMessageSpace --------------->|
 185  		// |<- controlMessageLen ---------->|      |
 186  		// |<- controlHeaderLen ->|         |      |
 187  		// +---------------+------+---------+------+
 188  		// |    Header     | PadH |  Data   | PadD |
 189  		// +---------------+------+---------+------+
 190  		//
 191  		// On compatible message reception:
 192  		//
 193  		// | ... |<- controlMessageLen ----------->|
 194  		// | ... |<- controlHeaderLen ->|          |
 195  		// +-----+---------------+------+----------+
 196  		// | ... |    Header     | PadH |   Data   |
 197  		// +-----+---------------+------+----------+
 198  		ms = append(ms, ControlMessage(m[:l]))
 199  		ll := l - controlHeaderLen()
 200  		if len(m) >= ControlMessageSpace(ll) {
 201  			m = m[ControlMessageSpace(ll):]
 202  		} else {
 203  			m = m[controlMessageLen(ll):]
 204  		}
 205  	}
 206  	return ms, nil
 207  }
 208  
 209  // NewControlMessage returns a new stream of control messages.
 210  func NewControlMessage(dataLen []int) ControlMessage {
 211  	var l int
 212  	for i := range dataLen {
 213  		l += ControlMessageSpace(dataLen[i])
 214  	}
 215  	return make([]byte, l)
 216  }
 217  
 218  // A Message represents an IO message.
 219  type Message struct {
 220  	// When writing, the Buffers field must contain at least one
 221  	// byte to write.
 222  	// When reading, the Buffers field will always contain a byte
 223  	// to read.
 224  	Buffers [][]byte
 225  
 226  	// OOB contains protocol-specific control or miscellaneous
 227  	// ancillary data known as out-of-band data.
 228  	OOB []byte
 229  
 230  	// Addr specifies a destination address when writing.
 231  	// It can be nil when the underlying protocol of the raw
 232  	// connection uses connection-oriented communication.
 233  	// After a successful read, it may contain the source address
 234  	// on the received packet.
 235  	Addr net.Addr
 236  
 237  	N     int // # of bytes read or written from/to Buffers
 238  	NN    int // # of bytes read or written from/to OOB
 239  	Flags int // protocol-specific information on the received message
 240  }
 241  
 242  // RecvMsg wraps recvmsg system call.
 243  //
 244  // The provided flags is a set of platform-dependent flags, such as
 245  // syscall.MSG_PEEK.
 246  func (c *Conn) RecvMsg(m *Message, flags int) error {
 247  	return c.recvMsg(m, flags)
 248  }
 249  
 250  // SendMsg wraps sendmsg system call.
 251  //
 252  // The provided flags is a set of platform-dependent flags, such as
 253  // syscall.MSG_DONTROUTE.
 254  func (c *Conn) SendMsg(m *Message, flags int) error {
 255  	return c.sendMsg(m, flags)
 256  }
 257  
 258  // RecvMsgs wraps recvmmsg system call.
 259  //
 260  // It returns the number of processed messages.
 261  //
 262  // The provided flags is a set of platform-dependent flags, such as
 263  // syscall.MSG_PEEK.
 264  //
 265  // Only Linux supports this.
 266  func (c *Conn) RecvMsgs(ms []Message, flags int) (int, error) {
 267  	return c.recvMsgs(ms, flags)
 268  }
 269  
 270  // SendMsgs wraps sendmmsg system call.
 271  //
 272  // It returns the number of processed messages.
 273  //
 274  // The provided flags is a set of platform-dependent flags, such as
 275  // syscall.MSG_DONTROUTE.
 276  //
 277  // Only Linux supports this.
 278  func (c *Conn) SendMsgs(ms []Message, flags int) (int, error) {
 279  	return c.sendMsgs(ms, flags)
 280  }
 281