dumb_socketpair(): try to use AF_UNIX socketpair on Windows 10 and newer
As a workaround for the lack of socketpair() on Windows, we use dumb_socketpair() from https://github.com/ncm/selectable-socketpair/blob/master/socketpair.c, which uses a pair of IPv4 local sockets (listening on 127.0.0.1).
Unfortunately, and maddeningly, it's possible for the local IPv4 routes (127.0.0.0/8) to be deleted on Windows; this will prevent dumb_socketpair() from working in its current form.
See #228 (closed) and
#361 (closed) for examples of how
to trigger this condition. The simplest way to do it is with route /f
.
Fortunately, Windows 10+ supports AF_UNIX sockets, which we should be able to use to sidestep this issue.
This feature was announced in December 2017 in https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows. It is evidently incomplete, and also buggy:
- "Abstract" sockets don't actually seem to work, and this is probably why the socketpair() function still isn't implemented, even though AF_UNIX support would naturally enable it: https://github.com/microsoft/WSL/issues/4240#issuecomment-506437851
- Actual MSDN documentation for this feature is seemingly nonexistent.
- MinGW lacks the expected <afunix.h> header, but other FLOSS projects show
how to embed the needed
struct sockaddr_un
definition:
Nevertheless, it works well enough that we can use it in OpenConnect. The modified version of dumb_socketpair() in this patch tries to create an AF_UNIX socketpair, and only uses IPv4 local sockets as a fallback. With this modified version, I confirm that I can do the following on Windows 10:
- Nuke routes with
route /f
. - Reconnect network adapter via GUI.
- Confirm that IPv4 local route (127.0.0.0/8) still hasn't been recreated.
- Run OpenConnect and successfully create the cmd pipe.
So this appears to fix #228 (closed) and #361 (closed), at least on Windows 10 and newer.