Skip to content

Instantly share code, notes, and snippets.

@nrdmn
Last active October 14, 2024 15:48
Show Gist options
  • Save nrdmn/7971be650919b112343b1cb2757a3fe6 to your computer and use it in GitHub Desktop.
Save nrdmn/7971be650919b112343b1cb2757a3fe6 to your computer and use it in GitHub Desktop.
vsock notes

vsock notes

about vsocks

Vsocks are a means of providing socket communication (either stream or datagram) directly between VMs and their host operating system. The host and each VM have a 32 bit CID (Context IDentifier) and may connect or bind to a 32 bit port number. Ports < 1024 are privileged ports.

special values

name value description
VMADDR_PORT_ANY -1 Bind to a random available port.
VMADDR_CID_ANY -1 Bind to any CID. This seems to work inside VMs only.
VMADDR_CID_HYPERVISOR 0 The hypervisor's CID.
VMADDR_CID_RESERVED 1 Reserved; this must not be used.
VMADDR_CID_HOST 2 The host's CID.

how to launch a vm with a vsock device

This creates a VM with a vsock device with CID 123.

qemu-system-x86_64 -device vhost-vsock-pci,guest-cid=123

vsock server on host

c

#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <string.h>
#include <stdio.h>

int main()
{
	int s = socket(AF_VSOCK, SOCK_STREAM, 0);

	struct sockaddr_vm addr;
	memset(&addr, 0, sizeof(struct sockaddr_vm));
	addr.svm_family = AF_VSOCK;
	addr.svm_port = 9999;
	addr.svm_cid = VMADDR_CID_HOST;

	bind(s, &addr, sizeof(struct sockaddr_vm));

	listen(s, 0);

	struct sockaddr_vm peer_addr;
	socklen_t peer_addr_size = sizeof(struct sockaddr_vm);
	int peer_fd = accept(s, &peer_addr, &peer_addr_size);

	char buf[64];
	size_t msg_len;
	while ((msg_len = recv(peer_fd, &buf, 64, 0)) > 0) {
		printf("Received %lu bytes: %.*s\n", msg_len, msg_len, buf);
	}

	return 0;
}

python

#!/usr/bin/env python3

import socket

CID = socket.VMADDR_CID_HOST
PORT = 9999

s = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM)
s.bind((CID, PORT))
s.listen()
(conn, (remote_cid, remote_port)) = s.accept()

print(f"Connection opened by cid={remote_cid} port={remote_port}")

while True:
    buf = conn.recv(64)
    if not buf:
        break

    print(f"Received bytes: {buf}")

vsock client in vm

c

#include <sys/socket.h>
#include <linux/vm_sockets.h>
#include <string.h>

int main()
{
	int s = socket(AF_VSOCK, SOCK_STREAM, 0);

	struct sockaddr_vm addr;
	memset(&addr, 0, sizeof(struct sockaddr_vm));
	addr.svm_family = AF_VSOCK;
	addr.svm_port = 9999;
	addr.svm_cid = VMADDR_CID_HOST;

	connect(s, &addr, sizeof(struct sockaddr_vm));

	send(s, "Hello, world!", 13, 0);

	close(s);

	return 0;
}

python

#!/usr/bin/env python3

import socket

CID = socket.VMADDR_CID_HOST
PORT = 9999

s = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM)
s.connect((CID, PORT))
s.sendall(b"Hello, world!")
s.close()

wireshark

ip link add type vsockmon
ip link set vsockmon0 up
wireshark -k -i vsockmon0
ip link set vsockmon0 down
ip link del vsockmon0

see also

@kanpov
Copy link

kanpov commented Sep 29, 2024

Maybe also mention seqpacket vsock?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment