I’ve recently made LAN Party VPN. It makes playing LAN games with friends on Discord effortless. LPVPN is written in C++, mostly because Discord SDK is only available in C, C++ and C#. So I didn’t have much of an option here.
The idea of LPVPN is rather simple, get IP packets from WinTun (the Windows implementation of TUN by WireGuard), and send those using the Discord SDK, and of course the other way around. There were still a few things left on the table: IP assignment and package routing. Both of these were implemented in the most straight-forward way possible. A minimal GUI is slapped on to LPVPN to make everything a little bit more user friendly.
I did ran into a few problems though:
Problem 1: Windows Firewall
Windows by default sets a network as “Public” with no easy way to reconfigure. A network interface being set to the “Public” profile gives Windows PCs a little bit more safety when connected to public networks. But in this case it totally destroys the intended use-case: LAN gaming. When a network is set to “Public”, other parties cannot connect to services on that interface, even if it listens to
0.0.0.0. This means that if you will not be able to find and connect to games other people are hosting. I’m able to work around this using this API, which is able to set a network as “Private”.
Problem 2: Packing everything into a single binary
I want users to download a standalone exe file, double click it, and have the VPN running. This proved to be a little bit hard since I need to bundle 2 dlls with the main binary: one for WinTun, and one for Discord. I want to package everything into a single binary since I don’t want users to download a ZIP file and manually unzip. For this I used NSIS, which is usually used for creating software installer. In this case I used it as a way to automatically unpack the dlls and exe and then execute in a temporary directory. This works on paper until I run into problem 3.
Problem 3: Windows Defender False Positives
Unfortunately, as soon as I have the NSIS executable packaged. Windows Defender promptly deleted it from my computer and gave me a stern warning that it is a Trojan. (It’s kind of funny to see Windows do that.) This would not fly if I plan on distributing the software.
Problem 4: Problem 2, Electric Boogaloo
Since there’s really no easy way to fix problem 3. I have think of another way to solve problem 2. Fortunately I found MemoryModule, which is a reimplementation of
LoadLibrary and its friends in Windows. This means I can load dlls from memory, instead of from files. I ended up packing the dlls as resources using cmrc, and then loading them using MemoryModule. This fixed the false positives from Windows Defender.