-
Notifications
You must be signed in to change notification settings - Fork 4.5k
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
Consider exposing Socket.Handle / Socket.SafeHandle #16666
Comments
We could add a new extension method (with a different name other than |
cc: @CIPop |
Please add the scenarios that you have in mind for this API. Would those scenarios require a new constructor |
The ones I had in mind, no. On Unix, a file descriptor underlies the Socket, and there are some functions that can take this file descriptor and do things with it not exposed in the Socket object model, for example getting details on who's at the other end of a Unix domain socket (http://linux.die.net/man/3/getpeereid). |
@stephentoub Feel free to drive this API enhancement into API review and implementation/testing including .NET Framework partial façade changes. Overall, I think it is probably an ok thing to add. But I don't think our team has cycles to work this now given the other work we're stabilizing for RTM. |
Just found this issue while I was trying to figure out how to call sendmsg on a Unix Socket. |
Thinking about this further, even if the Socket would expose a handle it isn't clear how I'd call the system function. |
You'd need to special-case based on platform, either compiling different assemblies based on the target, or with runtime checking, e.g. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
// call Win32 functions via P/Invoke
}
else
{
// call POSIX functions via P/Invoke
} |
If I DllImport libc to call a POSIX function, will that work on all non-Windows platforms? Or are there (non-Windows) platforms that need a value other than libc? |
It depends on the function. Most POSIX functions will be exported from libc, but it's possible some won't. This is where https://github.com/dotnet/coreclr/issues/930 and https://github.com/dotnet/coreclr/issues/444 come into play. |
Specifically for sendmsg, which has a signature:
is this the proper way to do the DllImport?
|
Is there a reason you can't use Socket.Send? Some option it's not providing that you need?
That looks right (though I think it's possible, though unlikely, that ssize_t could be 64-bit on a 32-bit platform, in which case IntPtr would end up being the wrong size). |
I want to pass credentials using SCM_CREDS in msghdr.msg_control. |
@SidharthNabar Do you have an idea when you will look at this? |
@stephentoub It looks like this can be implemented as |
While that can be implemented in CoreFx, it will not work for .NET Framework (Desktop). We can't use the "m_Handle" field since it is a private field to the Socket class. The revised package for System.Net.Sockets needs to work on both CoreFx and Desktop. We need to implement this functionality as an extension method most likely so that we can use PUBLIC Socket APIs to implement it. |
@davidsh why not implement it as a property on the Socket class (like it is on the desktop framework)? |
Because it is an existing class in the .NET Framework and we can't add properties to it without moving it out of the current contract generation it is in. Otherwise, the package will not be portable anymore to Desktop. I know this is a complicated topic and I can't really fully explain it here. But reving the contract surface for classes that already exist in the .NET Framework is a complex process. @ericstj can explain more fully. |
The way I look at it, the property already exists in the desktop framework so there is no need to change the contract (https://msdn.microsoft.com/en-us/library/system.net.sockets.socket.handle(v=vs.110).aspx). |
The concern with exposing the existing |
If the SafeHandle is exposed, doesn't that expose the IntPtr as well (by calling DangerousGetHandle)? |
Yes, but that's why it's prefixed with "Dangerous", and it also exposes the DangerousAddRef and DangerousRelease methods that enable you to do the right thing if you do need the raw IntPtr. Most of the time you don't, though, in that you can write your P/Invokes to take a SafeHandle and the runtime calls AddRef/GetHandle/Release appropriately rather than you doing it manually. SafeHandle isn't about making it impossible to shoot yourself in the foot, but rather about making the default behavior as reliable as possible. |
Yes, but we don't want to encourage bad practices. So, new APIs expose SafeHandle even though a developer can drill into it to get an IntPtr. |
What needs to happen to add SafeHandle to the System.Net.Sockets contract? |
@davidsh Perhaps it is also an option to extend the current implementation with IntPtr Handle and create a new contract which deprecates the IntPtr in favor of a SafeHandle? What is the rationale for choosing between an extension method or a property when updating the contract? |
We want to ensure that System.Net.Sockets is compatible between .Net Desktop. |
@CIPop Is there an advantage to using an extension method when the new feature cannot be implemented on top of the existing public API? |
@CIPop Let me paraphrase my question: In the first post on this issue @davidsh said:
I understand that adding a new feature requires a new version of the contract. But I don't get why it needs to be an extension method. Can't the contract specify whatever it wants (as long as it is backwards compatible)? |
@stephentoub @CIPop @davidsh can we decide something on the API? |
bump |
I've settled on using @stephentoub's reflection hack. It limits portability, but in my specific case that's fine. If the Handle issue isn't considered for the System.Net.Socket 4.1.0 contract used for netstandard 1.3-5, does that mean that when it gets added in 4.1.1 for netstandard 1.6, access to this feature in a platform generic way will be limited to 1.6+ platforms? |
To clarify about contract revisions, System.Net.Sockets 4.1.* is the pending contract which will RTM. When we add new APIs to a contract, we increase the minor version number, so the new contract would be 4.2.* and not 4.1.1. At this point, it is hard to say whether System.Net.Sockets 4.2.* will have to move to netstandard1.6 or not. That will get investigated post RTM. |
dotnet/corefx#11800 added Socket.Handle |
In the full framework, Socket provides an
IntPtr Handle { get; }
property that returns a representation of the underlying OS' socket. This enables using functionality not exposed via the Socket object model. In corefx, this property isn't available, and there's no IntPtr-based or SafeHandle-based replacement for it, preventing such use.The text was updated successfully, but these errors were encountered: