# Low-Latency Sunshine Streaming to a Quest 3 over USB on Linux
Table of Contents
I wanted to use my Huion graphics tablet for math exercises while viewing my desktop inside the Quest 3. I first tried streaming the desktop over Wi-Fi, but the delay between moving the pen and seeing the result in the headset was large enough to make writing annoying.
The obvious next step was to remove Wi-Fi from the equation and connect the Quest directly to my Linux laptop over USB. This was the only approach I found on Linux that gave me a desktop connection with very little latency. With Sunshine running on the laptop and Nightfall on the Quest, the delay was no longer noticeable in normal use.
The Quest supports USB NCM, which makes the USB cable behave like a small Ethernet link. Neither side configures that link automatically, though. The laptop needs an address, and the Quest needs a DHCP lease. This is how I set that up on Arch Linux and got Sunshine streaming over the cable.
Switch the Quest to USB NCM mode
With the Quest connected and the USB debugging prompt accepted, switch its USB gadget mode to NCM:
adb shell svc usb setFunctions ncmThe USB connection may briefly disappear while the mode changes. Once it comes back, list the network interfaces on both devices:
ip -br linkadb shell ip -br linkOn my machine, the new Linux interface was enp60s0u1i3, while the Quest called its side usb0. Your Linux interface will probably have a different name, so substitute it in the rest of the commands.
Check that Linux loaded the NCM driver
Before changing any addresses, I checked that Linux had actually bound the interface to the cdc_ncm driver:
ethtool -i enp60s0u1i3journalctl -k -b | grep -iE 'cdc.ncm|ncm|enp60s0u1i3'ethtool should report cdc_ncm, or the kernel log should show the CDC-NCM device being attached. If neither command finds it, there is no point debugging DHCP yet. The USB link itself is not ready.
Give the Linux side an address
I used 10.77.0.0/24 for the USB network and assigned 10.77.0.1 to the Linux side. Any unused private subnet will do, as long as it does not overlap with one of your existing networks.
sudo ip addr flush dev enp60s0u1i3sudo ip addr add 10.77.0.1/24 dev enp60s0u1i3sudo ip link set enp60s0u1i3 upip -4 addr show dev enp60s0u1i3The final command should show 10.77.0.1/24 on the interface.
Hand out an address with dnsmasq
Android expects DHCP on this kind of Ethernet connection, so I ran a temporary dnsmasq instance in a separate terminal. This command only serves DHCP on the USB interface. --port=0 disables dnsmasq’s DNS server, which I did not need for a direct local connection.
sudo dnsmasq --no-daemon --log-dhcp --port=0 \ --interface=enp60s0u1i3 \ --bind-interfaces \ --dhcp-authoritative \ --dhcp-range=10.77.0.2,10.77.0.10,255.255.255.0,1hLeave that running and tell the Quest to request an address for usb0:
adb shell cmd ethernet set-ip-configuration usb0 dhcpIf everything is working, the dnsmasq terminal will show the usual DHCP exchange: discover, offer, request, and acknowledgement. Mine looked like this:
DHCPDISCOVER(enp60s0u1i3) 16:82:19:1d:90:3bDHCPOFFER(enp60s0u1i3) 10.77.0.4 16:82:19:1d:90:3bDHCPREQUEST(enp60s0u1i3) 10.77.0.4 16:82:19:1d:90:3bDHCPACK(enp60s0u1i3) 10.77.0.4 16:82:19:1d:90:3bThe assigned address can change between runs. In this case the Quest got 10.77.0.4, but any address from the configured 10.77.0.2 to 10.77.0.10 pool is fine.
I confirmed the address and route from the Quest side with:
adb shell ip -4 addr show dev usb0adb shell ip -4 route show dev usb0Test the USB connection
At this point, the Quest should be able to reach the Linux address directly over the cable:
adb shell ping -c 3 -I usb0 10.77.0.1I got replies from 10.77.0.1. That confirms the local IPv4 path across the cable, but nothing more. This setup does not provide DNS, Internet access, or forwarding through the Linux machine.
Check that Sunshine’s ports are listening
Before trying the client, I also checked whether the host had TCP listeners on the ports I expected Sunshine to use:
ss -lntup | grep -E ':(47984|47989|47990|48010)\b'My output included:
0.0.0.0:479840.0.0.0:479890.0.0.0:479900.0.0.0:48010This is only a quick sanity check. The filtered output shows that something is listening on those ports, not which process owns them. Use sudo ss -lntup without the filter if you also want to verify the process.
Connect from Nightfall
Once the USB network was up, Nightfall automatically found the laptop running Sunshine. I did not need to enter 10.77.0.1 manually or change anything in Nightfall.
To make sure the stream was really using the cable rather than Wi-Fi, I disabled Wi-Fi on the Quest before connecting:
adb shell svc wifi disable# Start the Nightfall stream hereadb shell svc wifi enableThe stream continued to work with Wi-Fi disabled, confirming that Nightfall was reaching Sunshine over the USB network. More importantly for my use case, writing on the Huion no longer had any latency I could notice. I would still keep an ADB terminal open during the test, since it is easy to forget that Wi-Fi is disabled after taking off the headset.
Clean up afterward
When finished, stop dnsmasq with Ctrl-C, remove the temporary address, and make sure the Quest’s Wi-Fi is back on.
sudo ip addr flush dev enp60s0u1i3adb shell svc wifi enableThat leaves the host interface without the temporary address and restores the Quest’s normal Wi-Fi connection. If you changed how NetworkManager or another network service manages the interface, restore that separately.
This gave me exactly what I was after: Nightfall discovered Sunshine automatically, the desktop streamed over the USB cable, and writing with the Huion felt immediate instead of laggy. It is not a formal latency benchmark, but in actual use I could no longer perceive the delay that made the Wi-Fi setup so frustrating.