Imported Upstream version 5.10.0.69

Former-commit-id: fc39669a0b707dd3c063977486506b6793da2890
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-01-29 19:03:06 +00:00
parent d8f8abd549
commit e2950ec768
6283 changed files with 453847 additions and 91879 deletions

View File

@@ -7,7 +7,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Sockets.Tests",
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B} = {43311AFB-D7C4-4E5A-B1DE-855407F90D1B}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Sockets.Async.Performance.Tests", "tests\PerformanceTests\System.Net.Sockets.Async.Performance.Tests.csproj", "{BB5C85AD-C51A-4903-80E9-6F6E1AC1AD34}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Sockets.Async.Performance.Tests", "tests\ManualPerformanceTests\System.Net.Sockets.Async.Performance.Tests.csproj", "{BB5C85AD-C51A-4903-80E9-6F6E1AC1AD34}"
ProjectSection(ProjectDependencies) = postProject
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B} = {43311AFB-D7C4-4E5A-B1DE-855407F90D1B}
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.Sockets.Performance.Tests", "tests\Performance\System.Net.Sockets.Performance.Tests.csproj", "{981FC867-9071-444D-9388-BC5826609F76}"
ProjectSection(ProjectDependencies) = postProject
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B} = {43311AFB-D7C4-4E5A-B1DE-855407F90D1B}
EndProjectSection
@@ -39,6 +44,10 @@ Global
{BB5C85AD-C51A-4903-80E9-6F6E1AC1AD34}.Debug|Any CPU.Build.0 = netstandard-Windows_NT-Debug|Any CPU
{BB5C85AD-C51A-4903-80E9-6F6E1AC1AD34}.Release|Any CPU.ActiveCfg = netstandard-Windows_NT-Release|Any CPU
{BB5C85AD-C51A-4903-80E9-6F6E1AC1AD34}.Release|Any CPU.Build.0 = netstandard-Windows_NT-Release|Any CPU
{981FC867-9071-444D-9388-BC5826609F76}.Debug|Any CPU.ActiveCfg = netcoreapp-Debug|Any CPU
{981FC867-9071-444D-9388-BC5826609F76}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU
{981FC867-9071-444D-9388-BC5826609F76}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU
{981FC867-9071-444D-9388-BC5826609F76}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
@@ -54,6 +63,7 @@ Global
GlobalSection(NestedProjects) = preSolution
{8CBA022C-635F-4C8D-9D29-CD8AAC68C8E6} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
{BB5C85AD-C51A-4903-80E9-6F6E1AC1AD34} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
{981FC867-9071-444D-9388-BC5826609F76} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
{43311AFB-D7C4-4E5A-B1DE-855407F90D1B} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD}
{834E3534-6A11-4A8D-923F-35C1E71CCEC3} = {2E666815-2EDB-464B-9DF6-380BF4789AD4}
EndGlobalSection

View File

@@ -45,9 +45,9 @@ namespace System.Net.Sockets
TranslateHandle = (long)3355443213,
UnicastInterface = (long)2550136838,
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct IPPacketInformation
{
private object _dummy;
public System.Net.IPAddress Address { get { throw null; } }
public int Interface { get { throw null; } }
public override bool Equals(object comparand) { throw null; }
@@ -389,10 +389,10 @@ namespace System.Net.Sockets
Peek = 2,
Truncated = 256,
}
 [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct SocketInformation
public partial struct SocketInformation
{
public SocketInformationOptions Options { get { throw null; } set { } }
private object _dummy;
public System.Net.Sockets.SocketInformationOptions Options { get { throw null; } set { } }
public byte[] ProtocolInformation { get { throw null; } set { } }
}
[Flags]
@@ -638,9 +638,9 @@ namespace System.Net.Sockets
public System.Threading.Tasks.Task<int> SendAsync(byte[] datagram, int bytes, string hostname, int port) { throw null; }
public void AllowNatTraversal(bool allowed) { throw null; }
}
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct UdpReceiveResult : System.IEquatable<System.Net.Sockets.UdpReceiveResult>
{
private object _dummy;
public UdpReceiveResult(byte[] buffer, System.Net.IPEndPoint remoteEndPoint) { throw null; }
public byte[] Buffer { get { throw null; } }
public System.Net.IPEndPoint RemoteEndPoint { get { throw null; } }

View File

@@ -18,7 +18,7 @@ namespace System.Net.Sockets
public int Send(ReadOnlySpan<byte> buffer, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) { throw null; }
}
public partial static class SocketTaskExtensions
public static partial class SocketTaskExtensions
{
public static System.Threading.Tasks.ValueTask<int> ReceiveAsync(this System.Net.Sockets.Socket socket, System.Memory<byte> buffer, System.Net.Sockets.SocketFlags socketFlags, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
public static System.Threading.Tasks.ValueTask<int> SendAsync(this System.Net.Sockets.Socket socket, System.ReadOnlyMemory<byte> buffer, System.Net.Sockets.SocketFlags socketFlags, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { throw null; }
@@ -26,7 +26,12 @@ namespace System.Net.Sockets
public partial class SocketAsyncEventArgs : System.EventArgs, System.IDisposable
{
public System.Memory<byte> GetBuffer() { throw null; }
public System.Memory<byte> MemoryBuffer { get { throw null; } }
public void SetBuffer(System.Memory<byte> buffer) { throw null; }
}
public sealed partial class UnixDomainSocketEndPoint : System.Net.EndPoint
{
public UnixDomainSocketEndPoint(string path) { }
}
}

View File

@@ -220,6 +220,9 @@
<data name="ArgumentOutOfRange_NeedPosNum" xml:space="preserve">
<value>Positive number required.</value>
</data>
<data name="ArgumentOutOfRange_PathLengthInvalid" xml:space="preserve">
<value>The path '{0}' is of an invalid length for use with domain sockets on this platform. The length must be between 1 and {1} characters, inclusive.</value>
</data>
<data name="net_io_readwritefailure" xml:space="preserve">
<value>Unable to transfer data on the transport connection: {0}.</value>
</data>
@@ -232,4 +235,7 @@
<data name="PlatformNotSupported_IPProtectionLevel" xml:space="preserve">
<value>IP protection level cannot be controlled on this platform.</value>
</data>
<data name="InvalidOperation_BufferNotExplicitArray" xml:space="preserve">
<value>This operation may only be performed when the buffer was set using the SetBuffer overload that accepts an array.</value>
</data>
</root>

View File

@@ -30,7 +30,6 @@
<ItemGroup Condition="'$(TargetGroup)' != 'netfx'">
<!-- CoreCLR (All Operating Systems), .NET Native -->
<Compile Include="System\Net\Sockets\SocketTaskExtensions.cs" />
<Compile Include="System\Net\SocketPerfCounters.cs" />
<Compile Include="System\Net\Sockets\IOControlCode.cs" />
<Compile Include="System\Net\Sockets\IPPacketInformation.cs" />
<Compile Include="System\Net\Sockets\IPProtectionLevel.cs" />
@@ -144,6 +143,7 @@
<Compile Include="System\Net\Sockets\SocketAsyncEventArgs.Windows.cs" />
<Compile Include="System\Net\Sockets\SocketPal.Windows.cs" />
<Compile Include="System\Net\Sockets\TransmitFileAsyncResult.Windows.cs" />
<Compile Include="System\Net\Sockets\UnixDomainSocketEndPoint.Windows.cs" />
<Compile Include="$(CommonPath)\System\Net\SafeCloseSocket.Windows.cs">
<Link>Common\System\Net\SafeCloseSocket.Windows.cs</Link>
</Compile>
@@ -267,6 +267,7 @@
<Compile Include="System\Net\Sockets\SocketAsyncEngine.Unix.cs" />
<Compile Include="System\Net\Sockets\SocketAsyncEventArgs.Unix.cs" />
<Compile Include="System\Net\Sockets\SocketPal.Unix.cs" />
<Compile Include="System\Net\Sockets\UnixDomainSocketEndPoint.Unix.cs" />
<Compile Include="$(CommonPath)\System\Net\ContextAwareResult.Unix.cs">
<Link>Common\System\Net\ContextAwareResult.Unix.cs</Link>
</Compile>
@@ -312,6 +313,9 @@
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.GetBytesAvailable.cs">
<Link>Interop\Unix\System.Native\Interop.GetBytesAvailable.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.GetDomainSocketSizes.cs">
<Link>Common\Interop\Unix\Interop.GetDomainSocketSizes.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.GetPeerName.cs">
<Link>Interop\Unix\System.Native\Interop.GetPeerName.cs</Link>
</Compile>
@@ -395,11 +399,11 @@
<Reference Include="System.Diagnostics.Debug" />
<Reference Include="System.Diagnostics.Tracing" />
<Reference Include="System.IO.FileSystem" />
<Reference Include="System.Memory" />
<Reference Include="System.Net.NameResolution" />
<Reference Include="System.Net.Primitives" />
<Reference Include="System.Resources.ResourceManager" />
<Reference Include="System.Runtime" />
<Reference Include="System.Runtime.CompilerServices.Unsafe" />
<Reference Include="System.Runtime.Extensions" />
<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.Security.Claims" />
@@ -416,4 +420,4 @@
<Reference Include="System" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
</Project>
</Project>

View File

@@ -1,33 +0,0 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Threading;
namespace System.Net
{
internal enum SocketPerfCounterName
{
SocketConnectionsEstablished = 0, // these enum values are used as index
SocketBytesReceived,
SocketBytesSent,
SocketDatagramsReceived,
SocketDatagramsSent,
}
internal sealed class SocketPerfCounter
{
private static SocketPerfCounter s_instance;
public static SocketPerfCounter Instance => LazyInitializer.EnsureInitialized(ref s_instance);
public bool Enabled => false; // TODO (#7833): Implement socket perf counters.
[Conditional("TODO7833")]
public void Increment(SocketPerfCounterName perfCounter, long amount = 1)
{
// TODO (#7833): Implement socket perf counters.
}
}
}

View File

@@ -15,7 +15,7 @@ namespace System.Net.Sockets
_endPoint = endPoint;
}
internal EndPoint RemoteEndPoint
internal override EndPoint RemoteEndPoint
{
get { return _endPoint; }
}

View File

@@ -33,8 +33,6 @@ namespace System.Net.Sockets
private object _lockObject = new object();
protected abstract Socket UserSocket { get; }
// Called by Socket to kick off the ConnectAsync process. We'll complete the user's SAEA
// when it's done. Returns true if the operation will be asynchronous, false if it has failed synchronously
public bool StartConnectAsync(SocketAsyncEventArgs args, DnsEndPoint endPoint)
@@ -129,7 +127,7 @@ namespace System.Net.Sockets
_internalArgs = new SocketAsyncEventArgs();
_internalArgs.Completed += InternalConnectCallback;
_internalArgs.SetBuffer(_userArgs.Buffer, _userArgs.Offset, _userArgs.Count);
_internalArgs.CopyBufferFrom(_userArgs);
exception = AttemptConnection();
@@ -163,7 +161,7 @@ namespace System.Net.Sockets
if (_state == State.Canceled)
{
// If Cancel was called before we got the lock, the Socket will be closed soon. We need to report
// OperationAborted (even though the connection actually completed), or the user will try to use a
// OperationAborted (even though the connection actually completed), or the user will try to use a
// closed Socket.
exception = new SocketException((int)SocketError.OperationAborted);
}
@@ -186,7 +184,7 @@ namespace System.Net.Sockets
}
else
{
// Keep track of this because it will be overwritten by AttemptConnection
SocketError currentFailure = args.SocketError;
Exception connectException = AttemptConnection();
@@ -254,7 +252,7 @@ namespace System.Net.Sockets
}
}
private static Exception AttemptConnection(Socket attemptSocket, SocketAsyncEventArgs args)
private Exception AttemptConnection(Socket attemptSocket, SocketAsyncEventArgs args)
{
try
{
@@ -263,14 +261,15 @@ namespace System.Net.Sockets
NetEventSource.Fail(null, "attemptSocket is null!");
}
if (!attemptSocket.ConnectAsync(args))
bool pending = attemptSocket.ConnectAsync(args);
if (!pending)
{
return new SocketException((int)args.SocketError);
InternalConnectCallback(null, args);
}
}
catch (ObjectDisposedException)
{
// This can happen if the user closes the socket, and is equivalent to a call
// This can happen if the user closes the socket, and is equivalent to a call
// to CancelConnectAsync
return new SocketException((int)SocketError.OperationAborted);
}
@@ -413,8 +412,6 @@ namespace System.Net.Sockets
private Socket _socket;
private bool _userSocket;
protected override Socket UserSocket => _socket;
public SingleSocketMultipleConnectAsync(Socket socket, bool userSocket)
{
_socket = socket;
@@ -445,7 +442,7 @@ namespace System.Net.Sockets
protected override void OnFail(bool abortive)
{
// Close the socket if this is an abortive failure (CancelConnectAsync)
// Close the socket if this is an abortive failure (CancelConnectAsync)
// or if we created it internally
if (abortive || !_userSocket)
{
@@ -464,8 +461,6 @@ namespace System.Net.Sockets
private Socket _socket4;
private Socket _socket6;
protected override Socket UserSocket => null;
public DualSocketMultipleConnectAsync(SocketType socketType, ProtocolType protocolType)
{
if (Socket.OSSupportsIPv4)

View File

@@ -4,6 +4,7 @@
using System.Diagnostics.Tracing;
using System.Net.Sockets;
using System.Runtime.CompilerServices;
namespace System.Net
{
@@ -76,5 +77,41 @@ namespace System.Net
{
WriteEvent(NotLoggedFileId, filePath, socketHash, (int)completedOperation);
}
/// <summary>Logs the contents of a buffer.</summary>
/// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
/// <param name="buffer">The buffer to be logged.</param>
/// <param name="memberName">The calling member.</param>
[NonEvent]
public static void DumpBuffer(object thisOrContextObject, Memory<byte> buffer, [CallerMemberName] string memberName = null)
{
DumpBuffer(thisOrContextObject, buffer, 0, buffer.Length, memberName);
}
/// <summary>Logs the contents of a buffer.</summary>
/// <param name="thisOrContextObject">`this`, or another object that serves to provide context for the operation.</param>
/// <param name="buffer">The buffer to be logged.</param>
/// <param name="offset">The starting offset from which to log.</param>
/// <param name="count">The number of bytes to log.</param>
/// <param name="memberName">The calling member.</param>
[NonEvent]
public static void DumpBuffer(object thisOrContextObject, Memory<byte> buffer, int offset, int count, [CallerMemberName] string memberName = null)
{
if (IsEnabled)
{
if (offset < 0 || offset > buffer.Length - count)
{
Fail(thisOrContextObject, $"Invalid {nameof(DumpBuffer)} Args. Length={buffer.Length}, Offset={offset}, Count={count}", memberName);
return;
}
buffer = buffer.Slice(offset, Math.Min(count, MaxDumpSize));
byte[] slice = buffer.TryGetArray(out ArraySegment<byte> arraySegment) && arraySegment.Offset == 0 && arraySegment.Count == buffer.Length ?
arraySegment.Array :
buffer.ToArray();
Log.DumpBuffer(IdOf(thisOrContextObject), memberName, slice);
}
}
}
}

View File

@@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@@ -374,7 +375,7 @@ namespace System.Net.Sockets
if (saea != null)
{
// We got a cached instance. Configure the buffer and initate the operation.
ConfigureBuffer(saea, Unsafe.As<ReadOnlyMemory<byte>,Memory<byte>>(ref buffer), socketFlags, wrapExceptionsInIOExceptions: fromNetworkStream);
ConfigureBuffer(saea, MemoryMarshal.AsMemory<byte>(buffer), socketFlags, wrapExceptionsInIOExceptions: fromNetworkStream);
return GetValueTaskForSendReceive(SendAsync(saea), saea, fromNetworkStream, isReceive: false);
}
else
@@ -388,7 +389,7 @@ namespace System.Net.Sockets
/// <summary>Implements Task-returning SendAsync on top of Begin/EndSend.</summary>
private Task<int> SendAsyncApm(ReadOnlyMemory<byte> buffer, SocketFlags socketFlags)
{
if (buffer.DangerousTryGetArray(out ArraySegment<byte> bufferArray))
if (MemoryMarshal.TryGetArray(buffer, out ArraySegment<byte> bufferArray))
{
var tcs = new TaskCompletionSource<int>(this);
BeginSend(bufferArray.Array, bufferArray.Offset, bufferArray.Count, socketFlags, iar =>
@@ -521,7 +522,7 @@ namespace System.Net.Sockets
// so as to minimize overhead if the same buffers are used for subsequent operations (which is likely).
// But SAEA doesn't support having both a buffer and a buffer list configured, so clear out a buffer
// if there is one before we set the desired buffer list.
if (saea.Buffer != null) saea.SetBuffer(null, 0, 0);
if (!saea.MemoryBuffer.Equals(default)) saea.SetBuffer(default);
saea.BufferList = buffers;
saea.SocketFlags = socketFlags;
}

View File

@@ -1 +1 @@
b7edd69b9b150d3c51ac0b5efb82a99dbf85290e
10bd970a50210617dd5f2e7f0b1355084b3ba7a2

View File

@@ -16,7 +16,7 @@ namespace System.Net.Sockets
//
// Encapsulates a particular SocketAsyncContext object's access to a SocketAsyncEngine.
//
public struct Token
public readonly struct Token
{
private readonly SocketAsyncEngine _engine;
private readonly IntPtr _handle;
@@ -39,10 +39,10 @@ namespace System.Net.Sockets
}
}
public bool TryRegister(SafeCloseSocket socket, Interop.Sys.SocketEvents current, Interop.Sys.SocketEvents events, out Interop.Error error)
public bool TryRegister(SafeCloseSocket socket, out Interop.Error error)
{
Debug.Assert(WasAllocated, "Expected WasAllocated to be true");
return _engine.TryRegister(socket, current, events, _handle, out error);
return _engine.TryRegister(socket, _handle, out error);
}
}
@@ -375,15 +375,10 @@ namespace System.Net.Sockets
}
}
private bool TryRegister(SafeCloseSocket socket, Interop.Sys.SocketEvents current, Interop.Sys.SocketEvents events, IntPtr handle, out Interop.Error error)
private bool TryRegister(SafeCloseSocket socket, IntPtr handle, out Interop.Error error)
{
if (current == events)
{
error = Interop.Error.SUCCESS;
return true;
}
error = Interop.Sys.TryChangeSocketEventRegistration(_port, socket, current, events, handle);
error = Interop.Sys.TryChangeSocketEventRegistration(_port, socket, Interop.Sys.SocketEvents.None,
Interop.Sys.SocketEvents.Read | Interop.Sys.SocketEvents.Write, handle);
return error == Interop.Error.SUCCESS;
}
}

View File

@@ -15,8 +15,6 @@ namespace System.Net.Sockets
private SocketFlags _receivedFlags;
private Action<int, byte[], int, SocketFlags, SocketError> _transferCompletionCallback;
internal int? SendPacketsDescriptorCount => _sendPacketsElements?.Length;
private void InitializeInternals()
{
// No-op for *nix.
@@ -37,10 +35,7 @@ namespace System.Net.Sockets
// No-op for *nix.
}
private void SetupSendPacketsElements()
{
// No-op for *nix.
}
private void CompleteCore() { }
private void FinishOperationSync(SocketError socketError, int bytesTransferred, SocketFlags flags)
{
@@ -56,11 +51,6 @@ namespace System.Net.Sockets
}
}
private void InnerStartOperationAccept(bool userSuppliedBuffer)
{
_acceptedFileDescriptor = (IntPtr)(-1);
}
private void AcceptCompletionCallback(IntPtr acceptedFileDescriptor, byte[] socketAddress, int socketAddressSize, SocketError socketError)
{
CompleteAcceptOperation(acceptedFileDescriptor, socketAddress, socketAddressSize, socketError);
@@ -77,11 +67,13 @@ namespace System.Net.Sockets
internal unsafe SocketError DoOperationAccept(Socket socket, SafeCloseSocket handle, SafeCloseSocket acceptHandle)
{
if (_buffer != null)
if (!_buffer.Equals(default))
{
throw new PlatformNotSupportedException(SR.net_sockets_accept_receive_notsupported);
}
_acceptedFileDescriptor = (IntPtr)(-1);
Debug.Assert(acceptHandle == null, $"Unexpected acceptHandle: {acceptHandle}");
IntPtr acceptedFd;
@@ -97,11 +89,6 @@ namespace System.Net.Sockets
return socketError;
}
private void InnerStartOperationConnect()
{
// No-op for *nix.
}
private void ConnectCompletionCallback(SocketError socketError)
{
CompletionCallback(0, SocketFlags.None, socketError);
@@ -124,10 +111,6 @@ namespace System.Net.Sockets
return socketError;
}
private void InnerStartOperationDisconnect()
{
}
private Action<int, byte[], int, SocketFlags, SocketError> TransferCompletionCallback =>
_transferCompletionCallback ?? (_transferCompletionCallback = TransferCompletionCallbackCore);
@@ -145,19 +128,17 @@ namespace System.Net.Sockets
_receivedFlags = receivedFlags;
}
private void InnerStartOperationReceive()
internal unsafe SocketError DoOperationReceive(SafeCloseSocket handle)
{
_receivedFlags = System.Net.Sockets.SocketFlags.None;
_socketAddressSize = 0;
}
internal unsafe SocketError DoOperationReceive(SafeCloseSocket handle, out SocketFlags flags)
{
SocketFlags flags;
int bytesReceived;
SocketError errorCode;
if (_buffer != null)
if (_bufferList == null)
{
errorCode = handle.AsyncContext.ReceiveAsync(_buffer, _offset, _count, _socketFlags, out bytesReceived, out flags, TransferCompletionCallback);
errorCode = handle.AsyncContext.ReceiveAsync(_buffer.Slice(_offset, _count), _socketFlags, out bytesReceived, out flags, TransferCompletionCallback);
}
else
{
@@ -173,20 +154,18 @@ namespace System.Net.Sockets
return errorCode;
}
private void InnerStartOperationReceiveFrom()
internal unsafe SocketError DoOperationReceiveFrom(SafeCloseSocket handle)
{
_receivedFlags = System.Net.Sockets.SocketFlags.None;
_socketAddressSize = 0;
}
internal unsafe SocketError DoOperationReceiveFrom(SafeCloseSocket handle, out SocketFlags flags)
{
SocketFlags flags;
SocketError errorCode;
int bytesReceived = 0;
int socketAddressLen = _socketAddress.Size;
if (_buffer != null)
if (_bufferList == null)
{
errorCode = handle.AsyncContext.ReceiveFromAsync(_buffer, _offset, _count, _socketFlags, _socketAddress.Buffer, ref socketAddressLen, out bytesReceived, out flags, TransferCompletionCallback);
errorCode = handle.AsyncContext.ReceiveFromAsync(_buffer.Slice(_offset, _count), _socketFlags, _socketAddress.Buffer, ref socketAddressLen, out bytesReceived, out flags, TransferCompletionCallback);
}
else
{
@@ -202,13 +181,6 @@ namespace System.Net.Sockets
return errorCode;
}
private void InnerStartOperationReceiveMessageFrom()
{
_receiveMessageFromPacketInfo = default(IPPacketInformation);
_receivedFlags = System.Net.Sockets.SocketFlags.None;
_socketAddressSize = 0;
}
private void ReceiveMessageFromCompletionCallback(int bytesTransferred, byte[] socketAddress, int socketAddressSize, SocketFlags receivedFlags, IPPacketInformation ipPacketInformation, SocketError errorCode)
{
CompleteReceiveMessageFromOperation(bytesTransferred, socketAddress, socketAddressSize, receivedFlags, ipPacketInformation, errorCode);
@@ -228,6 +200,10 @@ namespace System.Net.Sockets
internal unsafe SocketError DoOperationReceiveMessageFrom(Socket socket, SafeCloseSocket handle)
{
_receiveMessageFromPacketInfo = default(IPPacketInformation);
_receivedFlags = System.Net.Sockets.SocketFlags.None;
_socketAddressSize = 0;
bool isIPv4, isIPv6;
Socket.GetIPProtocolInformation(socket.AddressFamily, _socketAddress, out isIPv4, out isIPv6);
@@ -235,7 +211,7 @@ namespace System.Net.Sockets
int bytesReceived;
SocketFlags receivedFlags;
IPPacketInformation ipPacketInformation;
SocketError socketError = handle.AsyncContext.ReceiveMessageFromAsync(_buffer, _bufferListInternal, _offset, _count, _socketFlags, _socketAddress.Buffer, ref socketAddressSize, isIPv4, isIPv6, out bytesReceived, out receivedFlags, out ipPacketInformation, ReceiveMessageFromCompletionCallback);
SocketError socketError = handle.AsyncContext.ReceiveMessageFromAsync(_buffer.Slice(_offset, _count), _bufferListInternal, _socketFlags, _socketAddress.Buffer, ref socketAddressSize, isIPv4, isIPv6, out bytesReceived, out receivedFlags, out ipPacketInformation, ReceiveMessageFromCompletionCallback);
if (socketError != SocketError.IOPending)
{
CompleteReceiveMessageFromOperation(bytesReceived, _socketAddress.Buffer, socketAddressSize, receivedFlags, ipPacketInformation, socketError);
@@ -244,17 +220,14 @@ namespace System.Net.Sockets
return socketError;
}
private void InnerStartOperationSend()
internal unsafe SocketError DoOperationSend(SafeCloseSocket handle)
{
_receivedFlags = System.Net.Sockets.SocketFlags.None;
_socketAddressSize = 0;
}
internal unsafe SocketError DoOperationSend(SafeCloseSocket handle)
{
int bytesSent;
SocketError errorCode;
if (_buffer != null)
if (_bufferList == null)
{
errorCode = handle.AsyncContext.SendAsync(_buffer, _offset, _count, _socketFlags, out bytesSent, TransferCompletionCallback);
}
@@ -272,11 +245,6 @@ namespace System.Net.Sockets
return errorCode;
}
private void InnerStartOperationSendPackets()
{
// nop
}
internal SocketError DoOperationSendPackets(Socket socket, SafeCloseSocket handle)
{
Debug.Assert(_sendPacketsElements != null);
@@ -336,18 +304,15 @@ namespace System.Net.Sockets
return SocketError.IOPending;
}
private void InnerStartOperationSendTo()
internal SocketError DoOperationSendTo(SafeCloseSocket handle)
{
_receivedFlags = System.Net.Sockets.SocketFlags.None;
_socketAddressSize = 0;
}
internal SocketError DoOperationSendTo(SafeCloseSocket handle)
{
int bytesSent;
int socketAddressLen = _socketAddress.Size;
SocketError errorCode;
if (_buffer != null)
if (_bufferList == null)
{
errorCode = handle.AsyncContext.SendToAsync(_buffer, _offset, _count, _socketFlags, _socketAddress.Buffer, ref socketAddressLen, out bytesSent, TransferCompletionCallback);
}
@@ -372,7 +337,7 @@ namespace System.Net.Sockets
// may fire erroneously.
Debug.Assert(NetEventSource.IsEnabled);
if (_buffer != null)
if (_bufferList == null)
{
NetEventSource.DumpBuffer(this, _buffer, _offset, size);
}

View File

@@ -11,13 +11,14 @@ namespace System.Net.Sockets
public partial class SocketAsyncEventArgs : EventArgs, IDisposable
{
// AcceptSocket property variables.
internal Socket _acceptSocket;
private Socket _acceptSocket;
private Socket _connectSocket;
// Buffer,Offset,Count property variables.
internal byte[] _buffer;
internal int _count;
internal int _offset;
// Single buffer.
private Memory<byte> _buffer;
private int _offset;
private int _count;
private bool _bufferIsExplicitArray;
// BufferList property variables.
private IList<ArraySegment<byte>> _bufferList;
@@ -43,27 +44,27 @@ namespace System.Net.Sockets
private EndPoint _remoteEndPoint;
// SendPacketsSendSize property variable.
internal int _sendPacketsSendSize;
private int _sendPacketsSendSize;
// SendPacketsElements property variables.
internal SendPacketsElement[] _sendPacketsElements;
private SendPacketsElement[] _sendPacketsElements;
// SendPacketsFlags property variable.
internal TransmitFileOptions _sendPacketsFlags;
private TransmitFileOptions _sendPacketsFlags;
// SocketError property variables.
private SocketError _socketError;
private Exception _connectByNameError;
// SocketFlags property variables.
internal SocketFlags _socketFlags;
private SocketFlags _socketFlags;
// UserToken property variables.
private object _userToken;
// Internal buffer for AcceptEx when Buffer not supplied.
internal byte[] _acceptBuffer;
internal int _acceptAddressBufferCount;
private byte[] _acceptBuffer;
private int _acceptAddressBufferCount;
// Internal SocketAddress buffer.
internal Internals.SocketAddress _socketAddress;
@@ -101,27 +102,24 @@ namespace System.Net.Sockets
public byte[] Buffer
{
get { return _buffer; }
get
{
if (_bufferIsExplicitArray)
{
bool success = _buffer.TryGetArray(out ArraySegment<byte> arraySegment);
Debug.Assert(success);
return arraySegment.Array;
}
return null;
}
}
public Memory<byte> GetBuffer()
{
// TODO https://github.com/dotnet/corefx/issues/24429:
// Actually support Memory<byte> natively.
return _buffer != null ?
new Memory<byte>(_buffer, _offset, _count) :
Memory<byte>.Empty;
}
public Memory<byte> MemoryBuffer => _buffer;
public int Offset
{
get { return _offset; }
}
public int Offset => _offset;
public int Count
{
get { return _count; }
}
public int Count => _count;
// SendPacketsFlags property.
public TransmitFileOptions SendPacketsFlags
@@ -131,7 +129,7 @@ namespace System.Net.Sockets
}
// NOTE: this property is mutually exclusive with Buffer.
// Setting this property with an existing non-null Buffer will throw.
// Setting this property with an existing non-null Buffer will throw.
public IList<ArraySegment<byte>> BufferList
{
get { return _bufferList; }
@@ -142,7 +140,7 @@ namespace System.Net.Sockets
{
if (value != null)
{
if (_buffer != null)
if (!_buffer.Equals(default))
{
// Can't have both set
throw new ArgumentException(SR.Format(SR.net_ambiguousbuffers, nameof(Buffer)));
@@ -172,7 +170,7 @@ namespace System.Net.Sockets
{
_bufferListInternal?.Clear();
}
_bufferList = value;
SetupMultipleBuffers();
@@ -205,11 +203,7 @@ namespace System.Net.Sockets
protected virtual void OnCompleted(SocketAsyncEventArgs e)
{
EventHandler<SocketAsyncEventArgs> handler = _completed;
if (handler != null)
{
handler(e._currentSocket, e);
}
_completed?.Invoke(e._currentSocket, e);
}
// DisconnectResuseSocket property.
@@ -244,7 +238,6 @@ namespace System.Net.Sockets
try
{
_sendPacketsElements = value;
SetupSendPacketsElements();
}
finally
{
@@ -282,34 +275,53 @@ namespace System.Net.Sockets
set { _userToken = value; }
}
public void SetBuffer(byte[] buffer, int offset, int count)
{
SetBufferInternal(buffer, offset, count);
}
public void SetBuffer(int offset, int count)
{
SetBufferInternal(_buffer, offset, count);
}
public void SetBuffer(Memory<byte> buffer)
{
if (!buffer.TryGetArray(out ArraySegment<byte> array))
StartConfiguring();
try
{
// TODO https://github.com/dotnet/corefx/issues/24429:
// Actually support Memory<byte> natively.
throw new ArgumentException();
if (!_buffer.Equals(default))
{
if ((uint)offset > _buffer.Length)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
if ((uint)count > (_buffer.Length - offset))
{
throw new ArgumentOutOfRangeException(nameof(count));
}
if (!_bufferIsExplicitArray)
{
throw new InvalidOperationException(SR.InvalidOperation_BufferNotExplicitArray);
}
_offset = offset;
_count = count;
}
}
finally
{
Complete();
}
SetBuffer(array.Array, array.Offset, array.Count);
}
internal bool HasMultipleBuffers
internal void CopyBufferFrom(SocketAsyncEventArgs source)
{
get { return _bufferList != null; }
StartConfiguring();
try
{
_buffer = source._buffer;
_offset = source._offset;
_count = source._count;
_bufferIsExplicitArray = source._bufferIsExplicitArray;
}
finally
{
Complete();
}
}
private void SetBufferInternal(byte[] buffer, int offset, int count)
public void SetBuffer(byte[] buffer, int offset, int count)
{
StartConfiguring();
try
@@ -317,9 +329,10 @@ namespace System.Net.Sockets
if (buffer == null)
{
// Clear out existing buffer.
_buffer = null;
_buffer = default;
_offset = 0;
_count = 0;
_bufferIsExplicitArray = false;
}
else
{
@@ -329,13 +342,13 @@ namespace System.Net.Sockets
throw new ArgumentException(SR.Format(SR.net_ambiguousbuffers, nameof(BufferList)));
}
// Offset and count can't be negative and the
// Offset and count can't be negative and the
// combination must be in bounds of the array.
if (offset < 0 || offset > buffer.Length)
if ((uint)offset > buffer.Length)
{
throw new ArgumentOutOfRangeException(nameof(offset));
}
if (count < 0 || count > (buffer.Length - offset))
if ((uint)count > (buffer.Length - offset))
{
throw new ArgumentOutOfRangeException(nameof(count));
}
@@ -343,10 +356,8 @@ namespace System.Net.Sockets
_buffer = buffer;
_offset = offset;
_count = count;
_bufferIsExplicitArray = true;
}
// Pin new or unpin old buffer if necessary.
SetupSingleBuffer();
}
finally
{
@@ -354,6 +365,29 @@ namespace System.Net.Sockets
}
}
public void SetBuffer(Memory<byte> buffer)
{
StartConfiguring();
try
{
if (buffer.Length != 0 && _bufferList != null)
{
throw new ArgumentException(SR.Format(SR.net_ambiguousbuffers, nameof(BufferList)));
}
_buffer = buffer;
_offset = 0;
_count = buffer.Length;
_bufferIsExplicitArray = false;
}
finally
{
Complete();
}
}
internal bool HasMultipleBuffers => _bufferList != null;
internal void SetResults(SocketError socketError, int bytesTransferred, SocketFlags flags)
{
_socketError = socketError;
@@ -393,14 +427,16 @@ namespace System.Net.Sockets
}
// Marks this object as no longer "in-use". Will also execute a Dispose deferred
// because I/O was in progress.
// because I/O was in progress.
internal void Complete()
{
CompleteCore();
// Mark as not in-use.
_operating = Free;
// Check for deferred Dispose().
// The deferred Dispose is not guaranteed if Dispose is called while an operation is in progress.
// The deferred Dispose is not guaranteed if Dispose is called while an operation is in progress.
// The _disposeCalled variable is not managed in a thread-safe manner on purpose for performance.
if (_disposeCalled)
{
@@ -461,7 +497,7 @@ namespace System.Net.Sockets
// Prepares for a native async socket call.
// This method performs the tasks common to all socket operations.
internal void StartOperationCommon(Socket socket)
internal void StartOperationCommon(Socket socket, SocketAsyncOperation operation)
{
// Change status to "in-use".
int status = Interlocked.CompareExchange(ref _operating, InProgress, Free);
@@ -470,6 +506,9 @@ namespace System.Net.Sockets
ThrowForNonFreeStatus(status);
}
// Set the operation type.
_completedOperation = operation;
// Prepare execution context for callback.
// If event delegates have changed or socket has changed
// then discard any existing context.
@@ -489,9 +528,6 @@ namespace System.Net.Sockets
internal void StartOperationAccept()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.Accept;
// AcceptEx needs a single buffer that's the size of two native sockaddr buffers with 16
// extra bytes each. It can also take additional buffer space in front of those special
// sockaddr structures that can be filled in with initial data coming in on a connection.
@@ -499,8 +535,8 @@ namespace System.Net.Sockets
// If our caller specified a buffer (willing to get received data with the Accept) then
// it needs to be large enough for the two special sockaddr buffers that AcceptEx requires.
// Throw if that buffer is not large enough.
bool userSuppliedBuffer = _buffer != null;
// Throw if that buffer is not large enough.
bool userSuppliedBuffer = !_buffer.Equals(default);
if (userSuppliedBuffer)
{
// Caller specified a buffer - see if it is large enough
@@ -508,8 +544,6 @@ namespace System.Net.Sockets
{
throw new ArgumentException(SR.Format(SR.net_buffercounttoosmall, nameof(Count)));
}
// Buffer is already pinned if necessary.
}
else
{
@@ -520,24 +554,11 @@ namespace System.Net.Sockets
_acceptBuffer = new byte[_acceptAddressBufferCount];
}
}
InnerStartOperationAccept(userSuppliedBuffer);
}
internal void StartOperationConnect()
internal void StartOperationConnect(MultipleConnectAsync multipleConnect = null)
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.Connect;
_multipleConnect = null;
_connectSocket = null;
InnerStartOperationConnect();
}
internal void StartOperationWrapperConnect(MultipleConnectAsync args)
{
_completedOperation = SocketAsyncOperation.Connect;
_multipleConnect = args;
_multipleConnect = multipleConnect;
_connectSocket = null;
}
@@ -563,75 +584,6 @@ namespace System.Net.Sockets
}
}
internal void StartOperationDisconnect()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.Disconnect;
InnerStartOperationDisconnect();
}
internal void StartOperationReceive()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.Receive;
InnerStartOperationReceive();
}
internal void StartOperationReceiveFrom()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.ReceiveFrom;
InnerStartOperationReceiveFrom();
}
internal void StartOperationReceiveMessageFrom()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.ReceiveMessageFrom;
InnerStartOperationReceiveMessageFrom();
}
internal void StartOperationSend()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.Send;
InnerStartOperationSend();
}
internal void StartOperationSendPackets()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.SendPackets;
InnerStartOperationSendPackets();
}
internal void StartOperationSendTo()
{
// Remember the operation type.
_completedOperation = SocketAsyncOperation.SendTo;
InnerStartOperationSendTo();
}
internal void UpdatePerfCounters(int size, bool sendOp)
{
if (sendOp)
{
SocketPerfCounter.Instance.Increment(SocketPerfCounterName.SocketBytesSent, size);
if (_currentSocket.Transport == TransportType.Udp)
{
SocketPerfCounter.Instance.Increment(SocketPerfCounterName.SocketDatagramsSent);
}
}
else
{
SocketPerfCounter.Instance.Increment(SocketPerfCounterName.SocketBytesReceived, size);
if (_currentSocket.Transport == TransportType.Udp)
{
SocketPerfCounter.Instance.Increment(SocketPerfCounterName.SocketDatagramsReceived);
}
}
}
internal void FinishOperationSyncFailure(SocketError socketError, int bytesTransferred, SocketFlags flags)
{
SetResults(socketError, bytesTransferred, flags);
@@ -710,9 +662,9 @@ namespace System.Net.Sockets
{
SetResults(SocketError.Success, bytesTransferred, flags);
if (NetEventSource.IsEnabled || Socket.s_perfCountersEnabled)
if (NetEventSource.IsEnabled && bytesTransferred > 0)
{
LogBytesTransferred(bytesTransferred, _completedOperation);
LogBuffer(bytesTransferred);
}
SocketError socketError = SocketError.Success;
@@ -802,32 +754,6 @@ namespace System.Net.Sockets
Complete();
}
private void LogBytesTransferred(int bytesTransferred, SocketAsyncOperation operation)
{
if (bytesTransferred > 0)
{
if (NetEventSource.IsEnabled)
{
LogBuffer(bytesTransferred);
}
if (Socket.s_perfCountersEnabled)
{
bool sendOp = false;
switch (operation)
{
case SocketAsyncOperation.Connect:
case SocketAsyncOperation.Send:
case SocketAsyncOperation.SendPackets:
case SocketAsyncOperation.SendTo:
sendOp = true;
break;
}
UpdatePerfCounters(bytesTransferred, sendOp);
}
}
}
internal void FinishOperationAsyncSuccess(int bytesTransferred, SocketFlags flags)
{
FinishOperationSyncSuccess(bytesTransferred, flags);

View File

@@ -69,7 +69,7 @@ namespace System.Net.Sockets
int sockAddrLen = socketAddress != null ? socketAddressLen : 0;
fixed (byte* sockAddr = socketAddress)
fixed (byte* b = &buffer.DangerousGetPinnableReference())
fixed (byte* b = &MemoryMarshal.GetReference(buffer))
{
var iov = new Interop.Sys.IOVector {
Base = b,
@@ -107,7 +107,7 @@ namespace System.Net.Sockets
{
int sent;
fixed (byte* sockAddr = socketAddress)
fixed (byte* b = &buffer.DangerousGetPinnableReference())
fixed (byte* b = &MemoryMarshal.GetReference(buffer))
{
var iov = new Interop.Sys.IOVector
{
@@ -342,7 +342,7 @@ namespace System.Net.Sockets
return checked((int)received);
}
private static unsafe int ReceiveMessageFrom(SafeCloseSocket socket, SocketFlags flags, byte[] buffer, int offset, int count, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno)
private static unsafe int ReceiveMessageFrom(SafeCloseSocket socket, SocketFlags flags, Span<byte> buffer, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out Interop.Error errno)
{
Debug.Assert(socketAddress != null, "Expected non-null socketAddress");
@@ -355,17 +355,15 @@ namespace System.Net.Sockets
long received;
fixed (byte* rawSocketAddress = socketAddress)
fixed (byte* b = buffer)
fixed (byte* b = &MemoryMarshal.GetReference(buffer))
{
var sockAddr = (byte*)rawSocketAddress;
var iov = new Interop.Sys.IOVector {
Base = &b[offset],
Count = (UIntPtr)count
Base = b,
Count = (UIntPtr)buffer.Length
};
messageHeader = new Interop.Sys.MessageHeader {
SocketAddress = sockAddr,
SocketAddress = rawSocketAddress,
SocketAddressLen = sockAddrLen,
IOVectors = &iov,
IOVectorCount = 1,
@@ -582,9 +580,6 @@ namespace System.Net.Sockets
return true;
}
public static bool TryCompleteReceiveFrom(SafeCloseSocket socket, byte[] buffer, int offset, int count, SocketFlags flags, byte[] socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, out SocketError errorCode) =>
TryCompleteReceiveFrom(socket, new Span<byte>(buffer, offset, count), null, flags, socketAddress, ref socketAddressLen, out bytesReceived, out receivedFlags, out errorCode);
public static bool TryCompleteReceiveFrom(SafeCloseSocket socket, Span<byte> buffer, SocketFlags flags, byte[] socketAddress, ref int socketAddressLen, out int bytesReceived, out SocketFlags receivedFlags, out SocketError errorCode) =>
TryCompleteReceiveFrom(socket, buffer, null, flags, socketAddress, ref socketAddressLen, out bytesReceived, out receivedFlags, out errorCode);
@@ -651,18 +646,14 @@ namespace System.Net.Sockets
}
}
public static unsafe bool TryCompleteReceiveMessageFrom(SafeCloseSocket socket, byte[] buffer, IList<ArraySegment<byte>> buffers, int offset, int count, SocketFlags flags, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out int bytesReceived, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out SocketError errorCode)
public static unsafe bool TryCompleteReceiveMessageFrom(SafeCloseSocket socket, Span<byte> buffer, IList<ArraySegment<byte>> buffers, SocketFlags flags, byte[] socketAddress, ref int socketAddressLen, bool isIPv4, bool isIPv6, out int bytesReceived, out SocketFlags receivedFlags, out IPPacketInformation ipPacketInformation, out SocketError errorCode)
{
Debug.Assert(
(buffer == null) ^ (buffers == null),
"One and only one of buffer and buffers must be null");
try
{
Interop.Error errno;
int received = buffer != null ?
ReceiveMessageFrom(socket, flags, buffer, offset, count, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno) :
int received = buffers == null ?
ReceiveMessageFrom(socket, flags, buffer, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno) :
ReceiveMessageFrom(socket, flags, buffers, socketAddress, ref socketAddressLen, isIPv4, isIPv6, out receivedFlags, out ipPacketInformation, out errno);
if (received != -1)
@@ -694,7 +685,7 @@ namespace System.Net.Sockets
}
}
public static bool TryCompleteSendTo(SafeCloseSocket socket, byte[] buffer, ref int offset, ref int count, SocketFlags flags, byte[] socketAddress, int socketAddressLen, ref int bytesSent, out SocketError errorCode)
public static bool TryCompleteSendTo(SafeCloseSocket socket, Span<byte> buffer, ref int offset, ref int count, SocketFlags flags, byte[] socketAddress, int socketAddressLen, ref int bytesSent, out SocketError errorCode)
{
int bufferIndex = 0;
return TryCompleteSendTo(socket, buffer, null, ref bufferIndex, ref offset, ref count, flags, socketAddress, socketAddressLen, ref bytesSent, out errorCode);
@@ -825,6 +816,15 @@ namespace System.Net.Sockets
return err == Interop.Error.SUCCESS ? SocketError.Success : GetSocketErrorForErrorCode(err);
}
public static unsafe SocketError GetAtOutOfBandMark(SafeCloseSocket handle, out int atOutOfBandMark)
{
int value = 0;
Interop.Error err = Interop.Sys.GetAtOutOfBandMark(handle, &value);
atOutOfBandMark = value;
return err == Interop.Error.SUCCESS ? SocketError.Success : GetSocketErrorForErrorCode(err);
}
public static unsafe SocketError GetPeerName(SafeCloseSocket handle, byte[] buffer, ref int nameLen)
{
Interop.Error err;
@@ -838,12 +838,12 @@ namespace System.Net.Sockets
return err == Interop.Error.SUCCESS ? SocketError.Success : GetSocketErrorForErrorCode(err);
}
public static unsafe SocketError Bind(SafeCloseSocket handle, byte[] buffer, int nameLen)
public static unsafe SocketError Bind(SafeCloseSocket handle, ProtocolType socketProtocolType, byte[] buffer, int nameLen)
{
Interop.Error err;
fixed (byte* rawBuffer = buffer)
{
err = Interop.Sys.Bind(handle, rawBuffer, nameLen);
err = Interop.Sys.Bind(handle, socketProtocolType, rawBuffer, nameLen);
}
return err == Interop.Error.SUCCESS ? SocketError.Success : GetSocketErrorForErrorCode(err);
@@ -977,12 +977,12 @@ namespace System.Net.Sockets
{
if (!handle.IsNonBlocking)
{
return handle.AsyncContext.Receive(buffer, offset, count, ref socketFlags, handle.ReceiveTimeout, out bytesTransferred);
return handle.AsyncContext.Receive(new Memory<byte>(buffer, offset, count), ref socketFlags, handle.ReceiveTimeout, out bytesTransferred);
}
int socketAddressLen = 0;
SocketError errorCode;
bool completed = TryCompleteReceiveFrom(handle, buffer, offset, count, socketFlags, null, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode);
bool completed = TryCompleteReceiveFrom(handle, new Span<byte>(buffer, offset, count), socketFlags, null, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode);
return completed ? errorCode : SocketError.WouldBlock;
}
@@ -1010,11 +1010,11 @@ namespace System.Net.Sockets
SocketError errorCode;
if (!handle.IsNonBlocking)
{
errorCode = handle.AsyncContext.ReceiveMessageFrom(buffer, null, offset, count, ref socketFlags, socketAddressBuffer, ref socketAddressLen, isIPv4, isIPv6, handle.ReceiveTimeout, out ipPacketInformation, out bytesTransferred);
errorCode = handle.AsyncContext.ReceiveMessageFrom(new Memory<byte>(buffer, offset, count), null, ref socketFlags, socketAddressBuffer, ref socketAddressLen, isIPv4, isIPv6, handle.ReceiveTimeout, out ipPacketInformation, out bytesTransferred);
}
else
{
if (!TryCompleteReceiveMessageFrom(handle, buffer, null, offset, count, socketFlags, socketAddressBuffer, ref socketAddressLen, isIPv4, isIPv6, out bytesTransferred, out socketFlags, out ipPacketInformation, out errorCode))
if (!TryCompleteReceiveMessageFrom(handle, new Span<byte>(buffer, offset, count), null, socketFlags, socketAddressBuffer, ref socketAddressLen, isIPv4, isIPv6, out bytesTransferred, out socketFlags, out ipPacketInformation, out errorCode))
{
errorCode = SocketError.WouldBlock;
}
@@ -1029,17 +1029,54 @@ namespace System.Net.Sockets
{
if (!handle.IsNonBlocking)
{
return handle.AsyncContext.ReceiveFrom(buffer, offset, count, ref socketFlags, socketAddress, ref socketAddressLen, handle.ReceiveTimeout, out bytesTransferred);
return handle.AsyncContext.ReceiveFrom(new Memory<byte>(buffer, offset, count), ref socketFlags, socketAddress, ref socketAddressLen, handle.ReceiveTimeout, out bytesTransferred);
}
SocketError errorCode;
bool completed = TryCompleteReceiveFrom(handle, buffer, offset, count, socketFlags, socketAddress, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode);
bool completed = TryCompleteReceiveFrom(handle, new Span<byte>(buffer, offset, count), socketFlags, socketAddress, ref socketAddressLen, out bytesTransferred, out socketFlags, out errorCode);
return completed ? errorCode : SocketError.WouldBlock;
}
public static SocketError WindowsIoctl(SafeCloseSocket handle, int ioControlCode, byte[] optionInValue, byte[] optionOutValue, out int optionLength)
{
throw new PlatformNotSupportedException(SR.PlatformNotSupported_IOControl);
{
// Three codes are called out in the Winsock IOCTLs documentation as "The following Unix IOCTL codes (commands) are supported." They are
// also the three codes available for use with ioctlsocket on Windows. Developers should be discouraged from using Socket.IOControl in
// cross -platform applications, as it accepts Windows-specific values (the value of FIONREAD is different on different platforms), but
// we make a best-effort attempt to at least keep these codes behaving as on Windows.
const int FIONBIO = unchecked((int)IOControlCode.NonBlockingIO);
const int FIONREAD = (int)IOControlCode.DataToRead;
const int SIOCATMARK = (int)IOControlCode.OobDataRead;
optionLength = 0;
switch (ioControlCode)
{
case FIONBIO:
// The Windows implementation explicitly throws this exception, so that all
// changes to blocking/non-blocking are done via Socket.Blocking.
throw new InvalidOperationException(SR.net_sockets_useblocking);
case FIONREAD:
case SIOCATMARK:
if (optionOutValue == null || optionOutValue.Length < sizeof(int))
{
return SocketError.Fault;
}
int result;
SocketError error = ioControlCode == FIONREAD ?
GetAvailable(handle, out result) :
GetAtOutOfBandMark(handle, out result);
if (error == SocketError.Success)
{
optionLength = sizeof(int);
BitConverter.TryWriteBytes(optionOutValue, result);
}
return error;
default:
// Every other control code is unknown to us for and is considered unsupported on Unix.
throw new PlatformNotSupportedException(SR.PlatformNotSupported_IOControl);
}
}
private static SocketError GetErrorAndTrackSetting(SafeCloseSocket handle, SocketOptionLevel optionLevel, SocketOptionName optionName, Interop.Error err)
@@ -1639,7 +1676,7 @@ namespace System.Net.Sockets
{
int bytesReceived;
SocketFlags receivedFlags;
SocketError socketError = handle.AsyncContext.ReceiveAsync(buffer, offset, count, socketFlags, out bytesReceived, out receivedFlags, asyncResult.CompletionCallback);
SocketError socketError = handle.AsyncContext.ReceiveAsync(new Memory<byte>(buffer, offset, count), socketFlags, out bytesReceived, out receivedFlags, asyncResult.CompletionCallback);
if (socketError == SocketError.Success)
{
asyncResult.CompletionCallback(bytesReceived, null, 0, receivedFlags, SocketError.Success);
@@ -1666,7 +1703,7 @@ namespace System.Net.Sockets
int socketAddressSize = socketAddress.InternalSize;
int bytesReceived;
SocketFlags receivedFlags;
SocketError socketError = handle.AsyncContext.ReceiveFromAsync(buffer, offset, count, socketFlags, socketAddress.Buffer, ref socketAddressSize, out bytesReceived, out receivedFlags, asyncResult.CompletionCallback);
SocketError socketError = handle.AsyncContext.ReceiveFromAsync(new Memory<byte>(buffer, offset, count), socketFlags, socketAddress.Buffer, ref socketAddressSize, out bytesReceived, out receivedFlags, asyncResult.CompletionCallback);
if (socketError == SocketError.Success)
{
asyncResult.CompletionCallback(bytesReceived, socketAddress.Buffer, socketAddressSize, receivedFlags, SocketError.Success);
@@ -1685,7 +1722,7 @@ namespace System.Net.Sockets
int bytesReceived;
SocketFlags receivedFlags;
IPPacketInformation ipPacketInformation;
SocketError socketError = handle.AsyncContext.ReceiveMessageFromAsync(buffer, null, offset, count, socketFlags, socketAddress.Buffer, ref socketAddressSize, isIPv4, isIPv6, out bytesReceived, out receivedFlags, out ipPacketInformation, asyncResult.CompletionCallback);
SocketError socketError = handle.AsyncContext.ReceiveMessageFromAsync(new Memory<byte>(buffer, offset, count), null, socketFlags, socketAddress.Buffer, ref socketAddressSize, isIPv4, isIPv6, out bytesReceived, out receivedFlags, out ipPacketInformation, asyncResult.CompletionCallback);
if (socketError == SocketError.Success)
{
asyncResult.CompletionCallback(bytesReceived, socketAddress.Buffer, socketAddressSize, receivedFlags, ipPacketInformation, SocketError.Success);

View File

@@ -34,12 +34,7 @@ namespace System.Net.Sockets
public static SocketError GetLastSocketError()
{
int win32Error = Marshal.GetLastWin32Error();
if (win32Error == 0)
{
NetEventSource.Fail(null, "GetLastWin32Error() returned zero.");
}
Debug.Assert(win32Error != 0, "Expected non-0 error");
return (SocketError)win32Error;
}
@@ -91,7 +86,7 @@ namespace System.Net.Sockets
return errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success;
}
public static SocketError Bind(SafeCloseSocket handle, byte[] buffer, int nameLen)
public static SocketError Bind(SafeCloseSocket handle, ProtocolType socketProtocolType, byte[] buffer, int nameLen)
{
SocketError errorCode = Interop.Winsock.bind(handle, buffer, nameLen);
return errorCode == SocketError.SocketError ? GetLastSocketError() : SocketError.Success;
@@ -180,7 +175,7 @@ namespace System.Net.Sockets
public static unsafe SocketError Send(SafeCloseSocket handle, ReadOnlySpan<byte> buffer, SocketFlags socketFlags, out int bytesTransferred)
{
int bytesSent;
fixed (byte* bufferPtr = &buffer.DangerousGetPinnableReference())
fixed (byte* bufferPtr = &MemoryMarshal.GetReference(buffer))
{
bytesSent = Interop.Winsock.send(handle.DangerousGetHandle(), bufferPtr, buffer.Length, socketFlags);
}
@@ -300,7 +295,7 @@ namespace System.Net.Sockets
public static unsafe SocketError Receive(SafeCloseSocket handle, Span<byte> buffer, SocketFlags socketFlags, out int bytesTransferred)
{
int bytesReceived;
fixed (byte* bufferPtr = &buffer.DangerousGetPinnableReference())
fixed (byte* bufferPtr = &MemoryMarshal.GetReference(buffer))
{
bytesReceived = Interop.Winsock.recv(handle.DangerousGetHandle(), bufferPtr, buffer.Length, socketFlags);
}

View File

@@ -4,11 +4,19 @@
namespace System.Net.Sockets
{
public struct UdpReceiveResult : IEquatable<UdpReceiveResult>
/// <summary>
/// Presents UDP receive result information from a call to the <see cref="UdpClient.ReceiveAsync"/> method
/// </summary>
public struct UdpReceiveResult : IEquatable<UdpReceiveResult>
{
private byte[] _buffer;
private IPEndPoint _remoteEndPoint;
/// <summary>
/// Initializes a new instance of the <see cref="UdpReceiveResult"/> class
/// </summary>
/// <param name="buffer">A buffer for data to receive in the UDP packet</param>
/// <param name="remoteEndPoint">The remote endpoint of the UDP packet</param>
public UdpReceiveResult(byte[] buffer, IPEndPoint remoteEndPoint)
{
if (buffer == null)
@@ -25,6 +33,9 @@ namespace System.Net.Sockets
_remoteEndPoint = remoteEndPoint;
}
/// <summary>
/// Gets a buffer with the data received in the UDP packet
/// </summary>
public byte[] Buffer
{
get
@@ -33,6 +44,9 @@ namespace System.Net.Sockets
}
}
/// <summary>
/// Gets the remote endpoint from which the UDP packet was received
/// </summary>
public IPEndPoint RemoteEndPoint
{
get
@@ -41,11 +55,20 @@ namespace System.Net.Sockets
}
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>The hash code</returns>
public override int GetHashCode()
{
return (_buffer != null) ? (_buffer.GetHashCode() ^ _remoteEndPoint.GetHashCode()) : 0;
}
/// <summary>
/// Returns a value that indicates whether this instance is equal to a specified object
/// </summary>
/// <param name="obj">The object to compare with this instance</param>
/// <returns>true if obj is an instance of <see cref="UdpReceiveResult"/> and equals the value of the instance; otherwise, false</returns>
public override bool Equals(object obj)
{
if (!(obj is UdpReceiveResult))
@@ -56,16 +79,33 @@ namespace System.Net.Sockets
return Equals((UdpReceiveResult)obj);
}
/// <summary>
/// Returns a value that indicates whether this instance is equal to a specified object
/// </summary>
/// <param name="other">The object to compare with this instance</param>
/// <returns>true if other is an instance of <see cref="UdpReceiveResult"/> and equals the value of the instance; otherwise, false</returns>
public bool Equals(UdpReceiveResult other)
{
return object.Equals(_buffer, other._buffer) && object.Equals(_remoteEndPoint, other._remoteEndPoint);
}
/// <summary>
/// Tests whether two specified <see cref="UdpReceiveResult"/> instances are equivalent
/// </summary>
/// <param name="left">The <see cref="UdpReceiveResult"/> instance that is to the left of the equality operator</param>
/// <param name="right">The <see cref="UdpReceiveResult"/> instance that is to the right of the equality operator</param>
/// <returns>true if left and right are equal; otherwise, false</returns>
public static bool operator ==(UdpReceiveResult left, UdpReceiveResult right)
{
return left.Equals(right);
}
/// <summary>
/// Tests whether two specified <see cref="UdpReceiveResult"/> instances are not equal
/// </summary>
/// <param name="left">The <see cref="UdpReceiveResult"/> instance that is to the left of the not equal operator</param>
/// <param name="right">The <see cref="UdpReceiveResult"/> instance that is to the right of the not equal operator</param>
/// <returns>true if left and right are unequal; otherwise, false</returns>
public static bool operator !=(UdpReceiveResult left, UdpReceiveResult right)
{
return !left.Equals(right);

View File

@@ -0,0 +1,135 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
using System.Text;
namespace System.Net.Sockets
{
/// <summary>Represents a Unix Domain Socket endpoint as a path.</summary>
public sealed class UnixDomainSocketEndPoint : EndPoint
{
private const AddressFamily EndPointAddressFamily = AddressFamily.Unix;
private static readonly Encoding s_pathEncoding = Encoding.UTF8;
private static readonly int s_nativePathOffset;
private static readonly int s_nativePathLength;
private static readonly int s_nativeAddressSize;
private readonly string _path;
private readonly byte[] _encodedPath;
static UnixDomainSocketEndPoint()
{
Interop.Sys.GetDomainSocketSizes(out s_nativePathOffset, out s_nativePathLength, out s_nativeAddressSize);
Debug.Assert(s_nativePathOffset >= 0, "Expected path offset to be positive");
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)
{
if (path == null)
{
throw new ArgumentNullException(nameof(path));
}
// 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);
int bufferLength = s_pathEncoding.GetByteCount(path);
if (!isAbstract)
{
// for null terminator
bufferLength++;
}
if (path.Length == 0 || bufferLength > s_nativePathLength)
{
throw new ArgumentOutOfRangeException(
nameof(path), path,
SR.Format(SR.ArgumentOutOfRange_PathLengthInvalid, path, s_nativePathLength));
}
_path = path;
_encodedPath = new byte[bufferLength];
int bytesEncoded = s_pathEncoding.GetBytes(path, 0, path.Length, _encodedPath, 0);
Debug.Assert(bufferLength - (isAbstract ? 0 : 1) == bytesEncoded);
}
internal UnixDomainSocketEndPoint(SocketAddress socketAddress)
{
if (socketAddress == null)
{
throw new ArgumentNullException(nameof(socketAddress));
}
if (socketAddress.Family != EndPointAddressFamily ||
socketAddress.Size > s_nativeAddressSize)
{
throw new ArgumentOutOfRangeException(nameof(socketAddress));
}
if (socketAddress.Size > s_nativePathOffset)
{
_encodedPath = new byte[socketAddress.Size - s_nativePathOffset];
for (int i = 0; i < _encodedPath.Length; i++)
{
_encodedPath[i] = socketAddress[s_nativePathOffset + i];
}
// Strip trailing null of pathname socket addresses.
int length = _encodedPath.Length;
if (!IsAbstract(_encodedPath))
{
// Since this isn't an abstract path, we're sure our first byte isn't 0.
while (_encodedPath[length - 1] == 0)
{
length--;
}
}
_path = s_pathEncoding.GetString(_encodedPath, 0, length);
}
else
{
_encodedPath = Array.Empty<byte>();
_path = string.Empty;
}
}
public override SocketAddress Serialize()
{
var result = new SocketAddress(AddressFamily.Unix, s_nativePathOffset + _encodedPath.Length);
for (int index = 0; index < _encodedPath.Length; index++)
{
result[s_nativePathOffset + index] = _encodedPath[index];
}
return result;
}
public override EndPoint Create(SocketAddress socketAddress) => new UnixDomainSocketEndPoint(socketAddress);
public override AddressFamily AddressFamily => EndPointAddressFamily;
public override string ToString()
{
bool isAbstract = IsAbstract(_path);
if (isAbstract)
{
return "@" + _path.Substring(1);
}
else
{
return _path;
}
}
private static bool IsAbstract(string path) => path.Length > 0 && path[0] == '\0';
private static bool IsAbstract(byte[] encodedPath) => encodedPath.Length > 0 && encodedPath[0] == 0;
}
}

Some files were not shown because too many files have changed in this diff Show More