[Feature Request] Add SEQPACKET socket type for vsock
Feature Request
https://docs.oasis-open.org/virtio/virtio/v1.2/csd01/virtio-v1.2-csd01.html
VIRTIO_VSOCK_F_SEQPACKET has been introduced as an option for virtio vsock. It would enable the use-case of VMs that are relaying datagrams over a vsock and need to keep the boundaries without a SOCK_STREAM combining them together.
Right now you can connect from the VM opening a vsock with SOCK_STREAM type, but not with SOCK_SEQPACKET. This would also mean that on the host side the created UDS needs to match the socket type of the vsock.
Describe the desired solution
This should work:
socketFd, err := unix.Socket(unix.AF_VSOCK, unix.SOCK_SEQPACKET, 0)
if err != nil {
return nil, 0, err
}
sockaddr := &unix.SockaddrVM{
CID: 2,
Port: 500,
}
if err := unix.Connect(socketFd, sockaddr); err != nil {
return nil, 0, err
}
And if the opened UDS on the host side doesn't match the sock type it should not go ahead with the connection.
Describe possible alternatives
I worked around this by implementing packet boundaries within the stream socket, but it's clearly a not very efficient solution and slow.
Checks
- [x] Have you searched the Firecracker Issues database for similar requests?
- [x] Have you read all the existing relevant Firecracker documentation?
- [x] Have you read and understood Firecracker's core tenets?
I am curious if this is something the Firecracker team is interested in implementing for their vsock virtio component.
Hi gabivlj, Thank you very much for your interest into Firecracker and this feature request. While at the moment we are not actively working to implement this feature, we are more than happy to receive contribution from the community to implement it. We will make sure to review any implementation of it. Thanks, Jack
I can pick this up, though I'm new to the project so may need some pointers
Thanks @evanrittenhouse, our getting started guide here is probably the best place to get going. Any other pointers/questions feel free to reach out
@evanrittenhouse CC: @JackThomson2
I see if you were still interested in working on this issue. If not, would I be able to take it on? Thank you!
I was looking at what it would take to add this over the past week and came up with some ideas:
- When the vsock device is started, the vmm opens a UDS at the configured
uds_pathon the host. Any host-initiated connections happen via this socket. Based on that, it seems like the socket type should be stated in the vsock device configuration alongsideguest_cidanduds_path. This would mean the entire vsock device "has" a socket type, which is implicitly the behavior at the moment. (This isn't the only option: on vsock device start the vmm could open 2 UDSs on the host, one at${uds_path}_streamand another at${uds_path}_seqpacketand leave it up to the socket on the host-side which one it wants toconnect()to. I'm not sure this is the way to go since probably only one socket would be used, leaving the other one sitting (a bit wasteful), and it adds the complexity of having to manage two different stream types at once within the vsock backend, which at the moment benefits from assuming onlyTYPE_STREAM). How does this sound from a design standpoint? - stdlib doesn't have support for UDS of type
SOCK_SEQPACKET(see here). AUnixSeqpacketListeneror similar would have to be implemented from unsafe libc calls (or an existing implementation pulled in from somewhere). I assume this could live within the vsock module, since it doesn't seem like it would be used elsewhere. - There is a slight incongruity between virtio vsock's seqpacket and UDS seqpacket. Virtio allows two boundary markers - end of message (
VIRTIO_VSOCK_SEQ_EOMpacket flag) and end of record (VIRTIO_VSOCK_SEQ_EORpacket flag) - while UDS only has the end of record flag. To me this means that multiple RW packets from the guest side, ending with a packet with the EOM flag set, must be sent to the host socket in one message. Going the other way, a single message from a host socket to the guest socket can be sent as a single message or multiple messages but the EOM flag must be set on the last message. An additional requirement of AF_UNIX SOCK_SEQPACKET is that each input system call (read(),recv(), etc) must consume an entire packet or the part that was not consumed will be dropped. These considerations would have to be mediated by VSockConnection.
Please let me know if I'm mistaken about anything!
@gjkeller we don't have any progress on this. Feel free to work on it.
Just a minor draft, very heavily a work in progress done in part with @gjkeller.