Skip to content

supporting AF_UNIX on Windows #549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 10, 2023

Conversation

kazu-yamamoto
Copy link
Collaborator

Sending PR just for CI.

@kazu-yamamoto kazu-yamamoto requested a review from Mistuke April 26, 2023 07:05
@kazu-yamamoto
Copy link
Collaborator Author

kazu-yamamoto commented Apr 26, 2023

@Mistuke This enables AF_UNIX on Windows. I have some concerns:

  1. This can be built at least on Windows 11. But I don't know which versions of Windows provide afunix.h exactly.
  2. I'm not sure why GHC 9.2 or earlier cannot find afunix.h. See the results of CI.
  3. I'm not sure why you did not implement instance ControlMessage Fd.

Any suggestions?

@Mistuke
Copy link
Collaborator

Mistuke commented Apr 26, 2023

@Mistuke This enables AF_UNIX on Windows. I have some concerns:

Hi, Awesome!

  1. This can be built at least on Windows 11. But I don't know which versions of Windows provide afunix.h exactly.

It was enabled in Windows 10 build 1803, so the version of Windows released on 30 April 2018. Due to the current support cycle of Windows, this means any supported version of Windows has it. See https://learn.microsoft.com/en-us/windows/release-health/supported-versions-windows-client

Typically for features we do runtime checks instead of compile time checks. But there doesn't seem to be a way to detect the availability of this at runtime since it exposes new functionality as only a struct. So I think it makes sense to just use it unconditionally. Anyone on a non-supported version of Windows would also not be supported by newer GHC and so can use older versions.

  1. I'm not sure why GHC 9.2 or earlier cannot find afunix.h. See the results of CI.

Distribution of headers on Windows happen by bundling the dev headers inside the compiler package itself. So on releases of GHC when the compiler version is increased, the headers and crt are also updated. So GHC 9.4 works because of the switch to clang and having the headers updated.

Typically, we work around this by having a "compat" header file which bundles a copy of the header for older GHC, like this https://github.com/haskell/win32/blob/master/include/wincon_compat.h you can find the header definition here https://github.com/mingw-w64/mingw-w64/blob/master/mingw-w64-headers/include/afunix.h

  1. I'm not sure why you did not implement instance ControlMessage Fd.

because conceptually the operation doesn't line up with the expectations. On Unix it does

pattern CmsgIdFd :: CmsgId
pattern CmsgIdFd = CmsgId (#const SOL_SOCKET) (#const SCM_RIGHTS)

and if you look at the posibilities for SOL_SOCKET https://learn.microsoft.com/en-us/windows/win32/winsock/sol-socket-socket-options there's no SCM_RIGHTS.

As far as I can tell, SCM_RIGHTS is described as:

       SCM_RIGHTS
              Send or receive a set of open file descriptors from
              another process.  The data portion contains an integer
              array of the file descriptors.

But this in itself is a problem. On Windows Fd are process local. As in they're not first class, the C runtime has a per-process list (or rather there's a pool of memory allocated in each process) that maps Fd to the underlying Windows Handle.

As a consequence, the behavior of Fd are quite limited:

  1. They only exist in the current process. You cannot pass them to a child. Basically Fd=12 in a parent is not the same thing as in the child, if it exists. On Windows only the native type HANDLE can be inherited.
  2. In Network, On Windows we don't actually have an Fd, it's a truncated HANDLE Socket type is incorrect on Windows #426 but because of how permissions on HANDLE work, in order for you to pass it to a child process, you need to use WSADuplicateSocket to ensure it can be passed to another process. Long story short, the operation isn't really compatible with SOL_SOCKET and if you look at the blog post announcing support for af_unix it explicitly states this as a non supported operation https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/

Which is because I don't think the Windows socket/security model allows it the same way as the Unix one.

@kazu-yamamoto
Copy link
Collaborator Author

@Mistuke Thank you for explaining!
May I pass the button of this PR to you?

P.S.
Now I have Windows 11 Arm on Parallels Desktop.
So, I can test your final code.

@Mistuke
Copy link
Collaborator

Mistuke commented Apr 28, 2023

Sure, I'll take a look in the weekend :)

@kazu-yamamoto kazu-yamamoto force-pushed the unix-domain-for-win branch from cd5fbb6 to bafc223 Compare May 1, 2023 13:56
@Mistuke
Copy link
Collaborator

Mistuke commented May 5, 2023

Have not forgotten, just didn't get a change last weekend, got stuck in train delays. it's a long weekend this one so will do it tonight or tomorrow morning!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants