Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Support UnixDomainSocketEndPoint on Windows #27631

Merged
merged 2 commits into from
Mar 2, 2018

Conversation

stephentoub
Copy link
Member

@stephentoub stephentoub commented Mar 1, 2018

Windows is adding support for Unix domain sockets, and it's easy to enable that support via our new UnixDomainSocketEndPoint type.

Fixes https://github.com/dotnet/corefx/issues/27542
cc: @eerhardt, @danmosemsft, @geoffkizer, @sunilmut, @tmds

@@ -28,108 +22,5 @@ static UnixDomainSocketEndPoint()
Debug.Assert(s_nativePathOffset + s_nativePathLength <= s_nativeAddressSize, "Expected address size to include all of the path length");
Debug.Assert(s_nativePathLength >= 92, "Expected max path length to be at least 92"); // per http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_un.h.html
}

public UnixDomainSocketEndPoint(string path)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of this code just moved to the other partial class, with very few changes. I'll point them out individually.

if (!s_udsSupported.Value)
{
throw new PlatformNotSupportedException();
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is obviously new.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to do this at the beginning of the constructor?


In reply to: 171722160 [](ancestors = 171722160)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinning was that we want to make sure all the arguments are valid regardless of whether support is currently there. I could go either way, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I can understand that reasoning. Just wanted to make sure.


public override SocketAddress Serialize()
{
var result = new SocketAddress(AddressFamily.Unix, s_nativeAddressSize);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The length changed from s_nativePathOffset + _encodedPath.Length to s_nativeAddressSize.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the change?


In reply to: 171722363 [](ancestors = 171722363)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it needs to match the native type in size/layout; otherwise if the native implementation dereferences, it can AV and other such things, and the native implementation may also do a size check. Basically it's dangerous to use anything smaller than the corresponding native definition.

{
bytesRead = await client.ReceiveAsync(new ArraySegment<byte>(buffer), SocketFlags.None);
Assert.InRange(bytesRead, 1, writeBuffer.Length - readData.Length);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed this because in my build there are some issues with shutdown, and the test would sometimes hang.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stephentoub - For the hang, as discussed offline, couple of similar bugs were fixed in the release branch. If you can give it a try on a recent build.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can give it a try on a recent build.

I will, thanks.

@geoffkizer
Copy link

Did you punt on the SAEA issue?

@geoffkizer
Copy link

Should we add a static OSSupportsUnixDomainSockets, like OSSupportsIPv4/6?

@stephentoub
Copy link
Member Author

@dotnet/dnceng, can you help me to understand what failed in https://ci3.dot.net/job/dotnet_corefx/job/master/job/linux-TGroup_netcoreapp+CGroup_Release+AGroup_x64+TestOuter_false_prtest/9488/consoleText? Some kind of infrastructure issue?

@stephentoub
Copy link
Member Author

Did you punt on the SAEA issue?

Yes. There's an easy workaround if you think it's worthwhile, which is to essentially just do the same thing that's done in the other asynchronous connects and fall back to a synchronous connect for things other than DnsEndPoint and IPEndPoint.

Should we add a static OSSupportsUnixDomainSockets, like OSSupportsIPv4/6?

I think that'd be reasonable. We can open an issue.

@stephentoub stephentoub closed this Mar 2, 2018
@stephentoub stephentoub reopened this Mar 2, 2018
@@ -8,18 +8,12 @@
namespace System.Net.Sockets
{
/// <summary>Represents a Unix Domain Socket endpoint as a path.</summary>
public sealed class UnixDomainSocketEndPoint : EndPoint
public sealed partial class UnixDomainSocketEndPoint : EndPoint
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had no idea we made this public


// Pathname socket addresses should be null-terminated.
// Linux abstract socket addresses start with a zero byte, they must not be null-terminated.
bool isAbstract = IsAbstract(path);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does Windows support abstract socket addresses? Will it fail later if one is passed in?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I see the test now. Nice!

Copy link

@sunilmut sunilmut Mar 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, Windows unix sockets supports abstract addresses, but, it does not support the autobind feature available in linux (see man7 unix).

// Some Windows will.
try
{
new Socket(AddressFamily.Unix, SocketType.Stream, ProtocolType.Unspecified).Dispose();
Copy link
Member

@eerhardt eerhardt Mar 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assumes that our product code is doing the right thing. Would it be better to P/Invoke into Windows directly to see if it is supported?

Or is their some other way to ask Windows if it is supported?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To check whether a given socket domain, type or protocol combo is supported, the best thing is to call the socket routine and check the return value.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To check whether a given socket domain, type or protocol combo is supported, the best thing is to call the socket routine and check the return value.

That's essentially what this code is doing, just via the .NET Socket type.

But to Eric's point, sure, I can just P/Invoke directly.

@@ -443,5 +442,29 @@ private static string GetRandomNonExistingFilePath()

return result;
}

private static bool PlatformDoesntSupportUnixDomainSockets => s_platformSupportsUnixDomainSockets.Value;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should there be a ! here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's why the Windows CI failed. :)

@MattGal
Copy link
Member

MattGal commented Mar 2, 2018

@stephentoub we had a total outage of telemetry processing, which is resolved now but was causing the Helix API to not reflect recently started jobs. Once the Jenkins plugin waited 15 minutes, it failed with the java.lang.NullPointerException as you noted (generally the wait between sending work and showing up in the API is < 5 seconds). This was dotnet/core-eng#2805.

Windows is adding support for Unix domain sockets, and it's easy to enable that support via our new UnixDomainSocketEndPoint type.
@stephentoub stephentoub force-pushed the udswindows branch 2 times, most recently from 903f3cf to afeb431 Compare March 2, 2018 19:52
@stephentoub stephentoub merged commit 421ce7b into dotnet:master Mar 2, 2018
@stephentoub stephentoub deleted the udswindows branch March 2, 2018 23:28
@karelz karelz added this to the 2.1.0 milestone Mar 10, 2018
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
* Support UnixDomainSocketEndPoint on Windows

Windows is adding support for Unix domain sockets, and it's easy to enable that support via our new UnixDomainSocketEndPoint type.

* Address PR feedback


Commit migrated from dotnet/corefx@421ce7b
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
8 participants