// Copyright 2017 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.
// Package socket provides a portable interface for socket system// calls.
package socket // import "golang.org/x/net/internal/socket"import ()var errNotImplemented = errors.New("not implemented on " + runtime.GOOS + "/" + runtime.GOARCH)// An Option represents a sticky socket option.typeOptionstruct { Level int// level Name int// name; must be equal or greater than 1 Len int// length of value in bytes; must be equal or greater than 1}// Get reads a value for the option from the kernel.// It returns the number of bytes written into b.func ( *Option) ( *Conn, []byte) (int, error) {if .Name < 1 || .Len < 1 {return0, errors.New("invalid option") }iflen() < .Len {return0, errors.New("short buffer") }return .get(, )}// GetInt returns an integer value for the option.//// The Len field of Option must be either 1 or 4.func ( *Option) ( *Conn) (int, error) {if .Len != 1 && .Len != 4 {return0, errors.New("invalid option") }var []bytevar [4]byteif .Len == 1 { = [:1] } else { = [:4] } , := .get(, )if != nil {return0, }if != .Len {return0, errors.New("invalid option length") }if .Len == 1 {returnint([0]), nil }returnint(NativeEndian.Uint32([:4])), nil}// Set writes the option and value to the kernel.func ( *Option) ( *Conn, []byte) error {if .Name < 1 || .Len < 1 {returnerrors.New("invalid option") }iflen() < .Len {returnerrors.New("short buffer") }return .set(, )}// SetInt writes the option and value to the kernel.//// The Len field of Option must be either 1 or 4.func ( *Option) ( *Conn, int) error {if .Len != 1 && .Len != 4 {returnerrors.New("invalid option") }var []byteif .Len == 1 { = []byte{byte()} } else {var [4]byteNativeEndian.PutUint32([:.Len], uint32()) = [:4] }return .set(, )}// ControlMessageSpace returns the whole length of control message.func ( int) int {returncontrolMessageSpace()}// A ControlMessage represents the head message in a stream of control// messages.//// A control message comprises of a header, data and a few padding// fields to conform to the interface to the kernel.//// See RFC 3542 for further information.typeControlMessage []byte// Data returns the data field of the control message at the head on// m.func ( ControlMessage) ( int) []byte { := controlHeaderLen()iflen() < || len() < + {returnnil }return [ : +]}// Next returns the control message at the next on m.//// Next works only for standard control messages.func ( ControlMessage) ( int) ControlMessage { := ControlMessageSpace()iflen() < {returnnil }return [:]}// MarshalHeader marshals the header fields of the control message at// the head on m.func ( ControlMessage) (, , int) error {iflen() < controlHeaderLen() {returnerrors.New("short message") } := (*cmsghdr)(unsafe.Pointer(&[0])) .set(controlMessageLen(), , )returnnil}// ParseHeader parses and returns the header fields of the control// message at the head on m.func ( ControlMessage) () (, , int, error) { := controlHeaderLen()iflen() < {return0, 0, 0, errors.New("short message") } := (*cmsghdr)(unsafe.Pointer(&[0]))return .lvl(), .typ(), int(uint64(.len()) - uint64()), nil}// Marshal marshals the control message at the head on m, and returns// the next control message.func ( ControlMessage) (, int, []byte) (ControlMessage, error) { := len()iflen() < ControlMessageSpace() {returnnil, errors.New("short message") } := (*cmsghdr)(unsafe.Pointer(&[0])) .set(controlMessageLen(), , )if > 0 {copy(.Data(), ) }return .Next(), nil}// Parse parses m as a single or multiple control messages.//// Parse works for both standard and compatible messages.func ( ControlMessage) () ([]ControlMessage, error) {var []ControlMessageforlen() >= controlHeaderLen() { := (*cmsghdr)(unsafe.Pointer(&[0])) := .len()if <= 0 {returnnil, errors.New("invalid header length") }ifuint64() < uint64(controlHeaderLen()) {returnnil, errors.New("invalid message length") }ifuint64() > uint64(len()) {returnnil, errors.New("short buffer") }// On message reception: // // |<- ControlMessageSpace --------------->| // |<- controlMessageLen ---------->| | // |<- controlHeaderLen ->| | | // +---------------+------+---------+------+ // | Header | PadH | Data | PadD | // +---------------+------+---------+------+ // // On compatible message reception: // // | ... |<- controlMessageLen ----------->| // | ... |<- controlHeaderLen ->| | // +-----+---------------+------+----------+ // | ... | Header | PadH | Data | // +-----+---------------+------+----------+ = append(, ControlMessage([:])) := - controlHeaderLen()iflen() >= ControlMessageSpace() { = [ControlMessageSpace():] } else { = [controlMessageLen():] } }return , nil}// NewControlMessage returns a new stream of control messages.func ( []int) ControlMessage {varintfor := range { += ControlMessageSpace([]) }returnmake([]byte, )}// A Message represents an IO message.typeMessagestruct {// When writing, the Buffers field must contain at least one // byte to write. // When reading, the Buffers field will always contain a byte // to read. Buffers [][]byte// OOB contains protocol-specific control or miscellaneous // ancillary data known as out-of-band data. OOB []byte// Addr specifies a destination address when writing. // It can be nil when the underlying protocol of the raw // connection uses connection-oriented communication. // After a successful read, it may contain the source address // on the received packet. Addr net.Addr N int// # of bytes read or written from/to Buffers NN int// # of bytes read or written from/to OOB Flags int// protocol-specific information on the received message}// RecvMsg wraps recvmsg system call.//// The provided flags is a set of platform-dependent flags, such as// syscall.MSG_PEEK.func ( *Conn) ( *Message, int) error {return .recvMsg(, )}// SendMsg wraps sendmsg system call.//// The provided flags is a set of platform-dependent flags, such as// syscall.MSG_DONTROUTE.func ( *Conn) ( *Message, int) error {return .sendMsg(, )}// RecvMsgs wraps recvmmsg system call.//// It returns the number of processed messages.//// The provided flags is a set of platform-dependent flags, such as// syscall.MSG_PEEK.//// Only Linux supports this.func ( *Conn) ( []Message, int) (int, error) {return .recvMsgs(, )}// SendMsgs wraps sendmmsg system call.//// It returns the number of processed messages.//// The provided flags is a set of platform-dependent flags, such as// syscall.MSG_DONTROUTE.//// Only Linux supports this.func ( *Conn) ( []Message, int) (int, error) {return .sendMsgs(, )}
The pages are generated with Goldsv0.8.2. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds.