moonlight-stream / moonlight-qt

GameStream client for PCs (Windows, Mac, Linux, and Steam Link)
GNU General Public License v3.0
10.75k stars 629 forks source link

Moonlight does not properly obtain the right MTU for Nebula VPN connections #1233

Closed socram8888 closed 7 months ago

socram8888 commented 7 months ago

Describe the bug

I am currently using Slack's Nebula VPN, as I prefer its licensing terms over ZeroTier's BSL, for connecting to the server from my client at home.

The Windows client seems to be unable to properly obtain the network MTU, falls back to 65535, and causes heavy IP packet fragmentation, which ultimately results in the video failing to render and the application stopping with a network error.

00:00:09 - Qt Info: Found matching interface: "orcanet" "" QFlags<QNetworkInterface::InterfaceFlag>(IsUp|IsRunning|CanBroadcast|CanMulticast)
00:00:09 - Qt Info: Interface Type: QNetworkInterface::Unknown
00:00:09 - Qt Info: Interface MTU: 65535

The device's MTU is correctly reported by netsh, so this should not be an issue with Nebula, but rather how the MTU is being obtained by Moonlight:

PS C:\windows\system32> netsh interface ipv4 show subinterfaces interface=orcanet

   MTU  MediaSenseState  Bytes ent. Bytes sal. Interfaz
------  ---------------  ---------  ---------  -------------
  1300                1    9572119    2657337  orcanet

The application works perfectly fine if I manually tune the packetsize setting and set it to ie 1200.

Steps to reproduce

1- Install Nebula VPN on both server and client. 2- Pair Moonlight successfully with the server. 3- Attempt to start playing.

Affected games All games, including launching Steam Big Picture.

Other Moonlight clients Moonlight on Android does not check the device's MTU, so this is irrelevant. I have not tried this on Linux.

Moonlight settings (please complete the following information) Forced H264 (to use hardware decoding), and bandwidth limited to 10Mbps for 1080p. Changing to defaults do not make any difference.

Client PC details (please complete the following information)

Server PC details (please complete the following information)

Moonlight Logs (please attach)

Attached are two logs, one with the packetsize set to autodetect (zero), and another with the packet manually set to 1200. log-packetsize-0.log log-packetsize-1200.log

cgutman commented 7 months ago

We're getting the MTU from Qt, which gets it from GetAdapterAddresses(). We don't want to just blindly treat 64K as invalid becasue it could possibly be a valid MTU for some obscure cases.

I'd be quite surprised though if Windows was really reporting two different values. I wonder if we're not really matching the correct interface somehow.

Can you post the full output of the following:

netsh interface ipv4 show interfaces
netsh interface ipv4 show subinterfaces
socram8888 commented 7 months ago

Here's the output:

C:\Windows\system32>netsh interface ipv4 show interfaces

Índ     Mét         MTU         Estado              Nombre
---  ----------  ----------  ------------  ---------------------------
  1          75  4294967295  connected     Loopback Pseudo-Interface 1
 13           5        1300  connected     orcanet
 14          25        1500  connected     Ethernet
  3          20        1500  disconnected  Ethernet 2
 18          20        1500  disconnected  Ethernet 3
  5          20        1500  disconnected  Ethernet 4

C:\Windows\system32>netsh interface ipv4 show subinterfaces

   MTU  MediaSenseState  Bytes ent. Bytes sal. Interfaz
------  ---------------  ---------  ---------  -------------
4294967295                1          0      29449  Loopback Pseudo-Interface 1
  1300                1          0      15805  orcanet
  1500                1    1949016     811651  Ethernet
  1500                5          0          0  Ethernet 2
  1500                5          0          0  Ethernet 3
  1500                5          0          0  Ethernet 4

(This is on another machine, as I've upgraded, but the issue still remains)

Also, the thing is, it seems Windows is indeed reporting different MTU sizes depending on how you query it. Querying for MTU size using Powershell returns:

PS C:\Windows\system32> $adapter = get-netadapter orcanet
PS C:\Windows\system32> $adapter.MtuSize
65535
PS C:\Windows\system32> $adapter.MacAddress

PS C:\Windows\system32> $adapter.DriverVersion
0.14.0.0
PS C:\Windows\system32> $adapter.DriverDescription
Wintun Userspace Tunnel
PS C:\Windows\system32> $adapter.DriverName
\SystemRoot\System32\drivers\wintun.sys

Unsure where this issue could be coming from. The driver this uses is not homebrewn by Slack, but it is actually Wireguard's: imagen

socram8888 commented 7 months ago

I've downloaded the Qt IDE to see all available properties in the QNetworkInterface. Here is the result:

Human name:  "orcanet"
Name:  "iftype53_32768"
Addr:  ""
Type:  QNetworkInterface::Unknown
MTU:  65535
===
Human name:  "SBTeamVPN"
Name:  "iftype53_32769"
Addr:  ""
Type:  QNetworkInterface::Unknown
MTU:  1420
===
Human name:  "Ethernet 2"
Name:  "ethernet_32773"
Addr:  "A8:B8:E0:01:C4:7A"
Type:  QNetworkInterface::Ethernet
MTU:  1500
===
Human name:  "Ethernet 3"
Name:  "ethernet_32774"
Addr:  "A8:B8:E0:01:C4:7B"
Type:  QNetworkInterface::Ethernet
MTU:  1500
===
Human name:  "Ethernet 4"
Name:  "ethernet_32775"
Addr:  "A8:B8:E0:01:C4:7C"
Type:  QNetworkInterface::Ethernet
MTU:  1500
===
Human name:  "Ethernet"
Name:  "ethernet_32772"
Addr:  "A8:B8:E0:01:C4:79"
Type:  QNetworkInterface::Ethernet
MTU:  1500
===
Human name:  "Loopback Pseudo-Interface 1"
Name:  "loopback_0"
Addr:  ""
Type:  QNetworkInterface::Loopback
MTU:  2147483647

orcanet is the Nebula VPN, and SBTeamVPN is another WireGuard interface for my workplace.

Unrelated to the issue, but I think it might make sense to add intf.name().startsWith("iftype53_") to the heuristics currently applied to check if the connection is via a VPN or not, as NDIS interface type 53 is virtual or proprietary.