-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
Proposal Details
I propose adding this function to golang.org/x/net/sys/unix:
// AppendSocketControlMessage appends a single socket control message to b,
// returning a new slice and the subslice of the message data.
func AppendSocketControlMessage(b []byte, level, typ int32, size int) (_, data []byte) {
off := len(b)
b = append(b, make([]byte, unix.CmsgSpace(size))...)
h := (*unix.Cmsghdr)(unsafe.Pointer(&b[off]))
h.Level = level
h.Type = typ
h.SetLen(unix.CmsgLen(size))
return b, b[off+unix.CmsgSpace(0):][:size]
}
Sample usage:
var control []byte
control, data = AppendSocketControlMessage(control, unix.IPPROTO_IP, unix.IP_TOS)
data[0] = 0b000000_01 // set ECN field to ECT1
conn.WriteMessageUDPAddrPort(datagram, control, address)
Background and motivation:
The golang.org/x/net/sys/unix.ParseOneSocketControlMessage function parses a socket control message.
The unix package contains functions that can be used to create specific control messages, such as unix.PktInfo4. There are also functions which can be used to construct a control message, but they are ill-documented and cumbersome to use. For example, the implementation of PktInfo4 is:
func PktInfo4(info *Inet4Pktinfo) []byte {
b := make([]byte, CmsgSpace(SizeofInet4Pktinfo))
h := (*Cmsghdr)(unsafe.Pointer(&b[0]))
h.Level = SOL_IP
h.Type = IP_PKTINFO
h.SetLen(CmsgLen(SizeofInet4Pktinfo))
*(*Inet4Pktinfo)(h.data(0)) = *info
return b
}
Note that this uses the unexported function Cmsghdr.data. One can achieve the same effect with exported functions (unix.CmsgSpace(0) will give the offset to the data section), but there is still no convenient inverse to ParseOneSocketControlMessage.
AppendSocketControlMessage provides that inverse, giving a simple way to construct control messages for use with sendmsg.
As another example of usage, PktInfo4 rewritten in terms of AppendSocketControlMessage:
func PktInfo4(info *Inet4Pktinfo) []byte {
b, data := AppendSocketControlMessage(nil, SOL_IP, IP_PKTINFO, SizeofInet4Pktinfo)
*(*Inet4Pktinfo)(unsafe.Pointer(&data[0])) = *info
return b
}
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Status