Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: x/sys/unix: add AppendSocketControlMessage #65775

Open
neild opened this issue Feb 17, 2024 · 0 comments
Open

proposal: x/sys/unix: add AppendSocketControlMessage #65775

neild opened this issue Feb 17, 2024 · 0 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Proposal
Milestone

Comments

@neild
Copy link
Contributor

neild commented Feb 17, 2024

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
}
@neild neild added the Proposal label Feb 17, 2024
@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Feb 17, 2024
@gopherbot gopherbot added this to the Unreleased milestone Feb 17, 2024
@neild neild changed the title x/sys/unix: add AppendSocketControlMessage proposal: x/sys/unix: add AppendSocketControlMessage Feb 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. Proposal
Projects
Status: Incoming
Development

No branches or pull requests

2 participants