Networking
The built-in user network gives the guest DHCP, DNS and outgoing TCP. In Node it uses real sockets; in a browser, a relay.
The guest gets a virtio network card and, behind it, a small router built into Warm64: QEMU's user network. It hands out an address by DHCP, answers DNS, and carries the guest's outgoing TCP connections.
wemu-system-aarch64 ... -netdev user,id=n0 -device virtio-net-pci,netdev=n0
# or, in one option
wemu-system-aarch64 ... -nic userThe user network
| Address | What |
|---|---|
10.0.2.15 | The guest (by DHCP) |
10.0.2.2 | The gateway. TCP to it reaches the host's 127.0.0.1. |
10.0.2.3 | DNS |
What it carries:
- DHCP, ARP, and ping to the gateway and DNS addresses.
- DNS
Alookups, answered by the host. - Outgoing TCP, to any address, opened by the host.
What it doesn't: connections into the guest (hostfwd is refused), UDP other than DHCP and DNS, and IPv6.
In the guest
On Alpine's netboot initramfs:
modprobe virtio_net
udhcpc -i eth0
echo nameserver 10.0.2.3 > /etc/resolv.conf
wget -O - http://example.com/Most installed systems configure the network by DHCP on their own.
In Node
nodeWEMUHost(), and so wemu-system-aarch64, opens the guest's TCP connections as real sockets and answers DNS with the system's resolver. The guest reaches the internet, and your machine's local services at 10.0.2.2.
In a browser
A web page can't open raw TCP connections, so the guest's connections travel over a WebSocket to a relay, a small Node program that opens them for it. webSocketConnector() is the browser end:
import { WEMU, browserWEMUHost, webSocketConnector } from "warm64";
const host = {
...browserWEMUHost(),
connector: webSocketConnector("wss://relay.example.com/"),
resolve: async (name) => lookUp(name), // your DNS, returning an IPv4 address or null
};The Warm64 repository includes one, examples/net/tcp-relay.mjs, which takes a port and an allow-list of the hosts and networks the guest may reach:
ALLOW="example.com:443,10.0.0.0/8" node examples/net/tcp-relay.mjs 7682Warning A relay opens connections on the guest's behalf. Run it with an allow-list, or anyone who can reach it can use it as a proxy.
Without a connector, the guest still gets DHCP, ARP and ping, but its TCP connections are refused. Without resolve, every name lookup fails.
Guests on one network
-netdev socket,connect= joins the guest to an Ethernet hub over a WebSocket, so several machines, in different pages or processes, share a network. The repository's examples/net/relay-hub.mjs is such a hub:
node examples/net/relay-hub.mjs 7681
wemu-system-aarch64 ... -netdev socket,id=n0,connect=ws://localhost:7681 -device virtio-net-pci,netdev=n0There's no DHCP on the hub: give each guest its own address on the same subnet.
Link state
set_link (in QMP and the monitor) takes a network card's link down and up again:
await vm.qmp("set_link", { name: "net0", up: false });