System or closed process keeping a socket open on Windows

30 Oct 2019 / ERap320

While developing and debugging a C# program for a customer I noticed some very strange behaviour: when the program crashed or was terminated from the debugger (without having time to properly close a listening socket), the TCP port would stay open indefinitely. This was very annoying because after the crash I obviously couldn't restart the program without getting errors about the port being already open. Trying to close the socket from a handy program like cports didn't work at all: the process listening on the port was already dead, so it didn't know how to kill it! Not having much time to debug this I logged off and on my Windows account to force the socket to die every time the issue happened.

After implementation and testing of the most important features of the program I decided to look into the problem once more. At first I found some comments about how it's impossible to make Windows close listening sockets of a crashed application or that it closes itself after some minutes, but this sounded like complete nonsense to me. This is not the first network-involving program I write and I never stumbled in this problem before. The fact that it seemed to only happen "sometimes" made me skeptical this was a Windows problem. Didn't really know what to do with this information, so I went on googoling.

I started looking into socket settings or flags, trying to set linger options and timeouts, but that did nothing. I also went so far as to set ReuseAddr to make the errors go away. This option makes the program always connect to the port even if it's occupied, but this didn't solve the problem because now I couldn't detect if there was a REAL other program already listening. Moreover, my users could open the program many times and only one instance would actually receive packets. This was unacceptable at best.

In the end, some post I found and some tries lead me to the right idea: child processes. Since the program had to work with an Oculus Quest (an Android based VR headset), some functions interfaced with it by opening adb and parsing its console output. I quickly figured out the problem appeared only when I used some feature involving adb, and closing its process also freed the TCP port!

When I programmatically launched adb, it became a child process. This would be fine if adb.exe ended after giving me its output but, as any Android developer knows, it stays open in the background waiting for other requests. By default, the child process which outlives its parent inherits almost all of its handles, including sockets. To obtain the desired behaviour, I "just" had to disable the inheritance on the process or on the handle. Too bad there is no way to do it in C# when calling the child process. The introduction of some way to set inheritance flags with pure C# was proposed but as far as I can tell everything stopped there.

I decided to just call kernel32.dll and use Windows APIs to do this. Luckily, the C# Socket class includes a Handle parameter exposing the handle we need.

//Evil windows kernel magic to avoid adb keeping inherited sockets alive when the program crashes

[Flags]
public enum HANDLE_FLAGS : uint
{
     NONE = 0,
     INHERIT = 1,
     PROTECT_FROM_CLOSE = 2
}

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool SetHandleInformation(IntPtr hObject, HANDLE_FLAGS dwMask, HANDLE_FLAGS dwFlags);

//End of evil windows kernel magic

And when declaring the socket:

Socket socket = new Socket(IPAddress.Any.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
SetHandleInformation(socket.Handle, HANDLE_FLAGS.INHERIT, 0);

How to run graphical applications with the Windows Subsystem for Linux

17 Jul 2017 / ERap320

First of all you have to activate the Windows Subsystem for Linux from Turn Windows features on and off, which you can find with a simple search from the start menu.

Download, install and start Xming, our substitute for the X server usually found on linux. This component will render the windows of the GUI program we'll throw at it.

At this point you have to install a program with a graphic interface. For this article I'll use a text editor named gedit, but you can use pretty much everything that comes to your mind. I was even able to succesfully run xfce4 straight from the default repository.

sudo apt-get install gedit

After the installation is completed, we "link" the shell to Xming by executing

export DISPLAY=:0

If you want to avoid having to write the same command every time you restart bash, you can just append it to .bashrc, found in your home directory.

Now you just jave to run the program by writing its name, like this:

gedit

Making shortcuts for Linux programs

You can make shortcuts to start GUI Linux programs straight from your desktop, using the "bash -c" command.

The command of the shortcut is:

bash -c "export DISPLAY=:0; [[[PROGRAM NAME]]]"

Since bash -c doesn't run the content of the user's .bashrc it needs the first line to specify the display before every other command is executed. Of course you have to make sure Xming is running every time you try to open these shortcuts.



1