Open amoldeshpande opened 5 years ago
I almost posted this one myself sometime last year after having burned an evening trying to use abstract names. [The announcement blog doesn't say they aren't supported, although no socketpair()
makes for a unsubtle hint.] I ended up not posting after I came to the uncomfortable conclusion the ask isn't strictly speaking WSL actionable (it is a win32 feature). Happy to hear I'm not the only one who tried tho.
Heads up we lost named AF_UNIX Windows interop in WSL2 (for now anyway). But even if we get that back 🙏, the fact that WSL2 is not in the same network namespace (nvm mount namespace) as win32 speaks to why abstract names is hard.
For time being, the way in and out of WSL (notwithstanding extreme unsupported measures) is through interop stdin/stdout/stderr and AF_INET.
Thanks @therealkenc , but the blog post does explicitly state "The second category is the ‘abstract’ socket address where the first character in ‘sun_path’ is a null byte. Windows implementation of AF_UNIX socket can also accept abstract addresses".
I am not really interested in interop with WSL, and while I don't see why they direct support for Winsock here, I hope it reaches someone who cares.
There's some real strangeness going on in this "feature" because I can run the code from https://gist.github.com/mattn/6b6bd66ff15e95ab0b241a578023e1ed and it will succeed outside a debugger but not within windbg. But that's an issue for another day.
I guess AF_INET on loopback is always an option for me in my specific use-case.
but the blog post does explicitly state
Indeed, it does; thanks. I knew there must have been a reason I spent so long trying to make it work.
I am not really interested in interop with WSL, and while I don't see why they direct support for Winsock here, I hope it reaches someone who cares.
I actually don't know the right place to reach someone who might care. I do hope someone does. Windows SDK forum maybe? [Noting that I didn't post there at the time either, and punted AF_INET pretty quick.]
My scenario at the time was interop with WSL though. If you are pure-play win32, I guess SOP would be win32 pipes.
Closing with tag question, since WSL is not the use case. Appreciate the post though, since it's a pretty good question regardless.
Well, the blog post explicitly points to this issue tracker as a place to provide feedback for AF_UNIX on Windows, and the forums have always been beyond useless. So, I'd like it left open for a real answer if that's possible. thanks.
Let's leave this open, it was our team that did the AF_UNIX work.
Heads up we lost named AF_UNIX Windows interop in WSL2 (for now anyway). But even if we get that back 🙏, the fact that WSL2 is not in the same network namespace (nvm mount namespace) as win32 speaks to why abstract names is hard.
@therealkenc what do you mean by that?
Also, how is WSL connecting to the 9P server to share the Linux filesystem now? I thought it was using a Unix socket in /run/WSL/
what do you mean by that?
I mean, we lost named AF_UNIX
Windows interop in WSL2 (for now anyway). [edit, correction: that's assuming we ever had AF_UNIX
Windows interop. It looks like not; I incorrectly assumed otherwise. The OP ask is abstract sockets in Windows.]
Also, how is WSL connecting to the 9P server to share the Linux filesystem now?
Wouldn't know. Probably a hyper-v socket, but that's only a guess.
I thought it was using a Unix socket in /run/WSL/_interop.
That path is not on 9p
. Quick look shows /run/WSL/*_interop
is accessed by /init
not a Windows process.
can we please not bring WSL into this ? I know this is a WSL issue tracker, but I specifically filed a Windows bug. If you have similar WSL issues, please separate them. thanks.
I also encountered this problem, AF_UNIX abstract on Windows, but connect always returns EINVAL, Is there any solution at the moment?
I also have problems with named AF_UNIX sockets, bind & listen & select work, but when I call accept in a response to a successful read select, I mysteriously get a WSAENOTSOCK error. I was not able to find any example code for AF_UNIX sockets on Windows. Do you have some working examples (named and/or abstract)?
This doesn't look like the right place to report this, since it is unrelated to WSL, but I am also missing a better feedback channel.
I have this problem as well: non-abstract AF_UNIX
sockets work fine, but connect
fails with WSAEINVAL
with abstract AF_UNIX
sockets.
The entire reason I am doing this is so that I can implement my own socketpair
so I can interrupt a select
/WSAPoll
loop. So if you implement socketpair
in WinSock, that'd work, too.
By the way, if you do implement socketpair
in Win32, please add something equivalent to Linux's SOCK_CLOEXEC
to it, which would atomically set the socket as non-inheritable. (Compare WSASocket
's WSA_FLAG_NO_HANDLE_INHERIT
.)
This feature is simply not implemented. The AfUnixTlConnect
function of afunix.sys
checks whether the address is abstract, and if it is, does a trace log of [0x%08x] connect to abstract address
then returns STATUS_INVALID_PARAMETER
, which becomes WSAEINVAL
in WinSock.
Why does this blog post from Microsoft claim that "Windows implementation of AF_UNIX socket can also accept abstract addresses" then? And why is @microsoft deleting comments?
well, that comment was just me ranting, so it definitely deserved to be deleted :) Nothing useful was lost in that deletion.
Will this ever be worked on?
Oh and maybe someone can correct the original blog post at https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/? I've lost a day's work due to this (know) limitation :-(
Windows implementation of AF_UNIX does not support abstract sockets (as already established here so far) and we have very less desire to implement it since it lacks the Windows security model (abstract unix sockets cannot be secured).
The blog post is incorrect and we take responsibility for that (we will correct it). And, we do apologize for the confusion caused here.
Thanks @sunilmut !
@sunilmut The entire reason I tried to use abstract sockets was so that I could interrupt select
. The only decent way to interrupt select
is to send a byte to one of the sockets it's using. But this requires a loopback socket, which without a socketpair
API can only be created by binding a socket to a localhost port and connecting to it. I didn't want to create an actual TCP port, so I used AF_UNIX instead. I wanted to use abstract sockets so that there wasn't an object in the filesystem sticking around.
As for the security issue, the way I got around the problem of other processes connecting to my socket in the timing window was to use SIO_AF_UNIX_GETPEERPID
to verify that I am talking to myself. So even without the ability to set ACLs on abstract sockets, it would've been secure.
All this could be avoided with a socketpair
API in WinSock.
(Yes, you can queue a user-mode APC to a select
thread, but there's no well-defined method to cause the select
to abort and return from that APC.)
@sunilmut So there are no abstract sockets in Windows and I wasted a couple of days and there are also no docs about AF_SOCKET here: https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-start-page-2
Very nice! Maybe the doc issues could be rectified too?
If anyone needs an AF_UNIX
-based implementation of socketpair()
for Windows, we needed it in OpenConnect and I figured out how to make it work: https://gitlab.com/openconnect/openconnect/-/merge_requests/320/diffs
The caveat, of course, is that you need a real filesystem path for the socket. :face_with_head_bandage:
Hey @microsoft!
Do you respect developers who are willing/able/required to write software for Windows?
If so, you should stop wasting everyone's time by correcting the blog post to reflect the fact that abstract sockets are not actually supported… at all… which is completely the opposite of what it explicitly states. It appears I'm just one of many developers who've wasted hours trying to make them work on Windows before discovering this thread. :cursing_face:
@sunilmut, you wrote more than a year and a half ago that it would get updated https://github.com/microsoft/WSL/issues/4240#issuecomment-620805115
Also, pretty much everyone who wants AF_UNIX
sockets on Win32 wants them for the same reason: to implement socketpair
without needing either to use either…
route /f
, which will nuke the 127.0.0.0/8
route, and make it very hard to restore; see openconnect issue #228 for examples of this)… so why not just implement socketpair
properly and give everyone what they actually want?
Adding support for AF_UNIX
was a huge step forward, as it allows to interrupt a WSAPoll()
call without the need to create TCP/IP sockets (reserving a port and leaving it exposed).
However, in order to achieve a proper socketpair()
implementation, abstract sockets are required.
However, in order to achieve a proper
socketpair()
implementation, abstract sockets are required.
@davidebeatrici, agreed, but do check out the "just about good enough" version that I've implemented for OpenConnect: https://gitlab.com/openconnect/openconnect/-/merge_requests/320/diffs
It works around the issue of missing abstract sockets by trying, in order…
{64-bit CPU ticks in hex}-{Process ID}.$$$
in %TMP%
%WINDIR%\Temp
C:\Temp
About as robust as I think we can do given the (frankly infuriating) limitations of Windows’ incomplete AF_UNIX implementation.
Your solution is indeed excellent and probably the best right now.
The only thing I would do differently is use GetTempFileName()
to generate the filename. The function should guarantee a unique string, the only limitation is the lack of a custom prefix (it's always .TMP
).
The only thing I would do differently is use
GetTempFileNameA()
to generate the filename. The function should guarantee a unique string, the only limitation is the lack of a custom prefix (it's always.TMP
).
Thanks! That's a great addition. Will include that when I try to contribute it back upstream to https://github.com/ncm/selectable-socketpair/blob/master/socketpair.c
Sure, no problem!
Is the socket file not deleted when closesocket()
is called?
Is the socket file not deleted when closesocket() is called?
It is not, in the Windows 10 implementation. My temp directory is littered with size-0 files that were Unix domain sockets.
Solution: call DeleteFile()
right after connect()
.
Oh and maybe someone can correct the original blog post at https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/? I've lost a day's work due to this (know) limitation :-(
That misleading blogpost! Lost 2 days.
Please implement correct support for socketpair
. The documentation and lack of support is truely frustrating and time consuming.
btw The unnamed AF_UNIX socket does not work as well.
Windows implementation of AF_UNIX does not support abstract sockets since it lacks the Windows security model (abstract unix sockets cannot be secured).
it would be nice of the unnamed AF_UNIX socket may be changed to a working state. I dont see an security problem, because the used internal name (handle) can be calculated by the members of microsoft themself. no one can do it better and more secure than a microsoft member.
To get more secured sockets for internal communication it would be great to get the unnamed AF_UNIX sockets working. The other way to open two sockets on a arbritayr ports is always less secure. So to "not implement" abstract or unnamed sockets to avoid security problems is not a solution, because there is no documented known secure solution available on windows, isnt it?
Source: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/?nsl_bypass_cache=1691bb3186187e54c37d7a6cd3e209af#comments "Lastly, ‘unnamed’ sockets, where the socket is bound to a pathname with no name. This is also supported on Windows unix socket implementation."
But unnamed sockets with length "2" (just sun_family=AF_UNIX not path) lead into the same not available error message.
As we've hit 2024, the blog post was not yet rectified There's a comment beneath it from someone whose name I don't see in this entire thread. Can someone please pick up the work of either fixing the blog post, or getting abstract sockets to work upstream rather than with robust workarounds?
where to put this afunix.h file.
The file afunix.h is part of visual studio / windows kits / wsdk. If not beside winsock2.h or stdio.h on your disk, you may need sdk (Software development kit) / visual studio updates.
The file afunix.h is an include file to get header definitions in your code. You should not deliver this file.
@keith-horton @CatalinFetoiu @OneBlue folks are you able to address this issue and the incorrect blog post? This is causing a lot of confusion, and it's been ~5 years since the issue was reported.
ver
at a Windows Command Prompt) 18362.175