public static EndPoint Create(this EndPoint thisObj, Internals.SocketAddress socketAddress) { AddressFamily family = socketAddress.Family; if (family != thisObj.AddressFamily) { throw new ArgumentException(SR.Format(SR.net_InvalidAddressFamily, family.ToString(), thisObj.GetType().FullName, thisObj.AddressFamily.ToString()), nameof(socketAddress)); } if (family == AddressFamily.InterNetwork || family == AddressFamily.InterNetworkV6) { if (socketAddress.Size < 8) { throw new ArgumentException(SR.Format(SR.net_InvalidSocketAddressSize, socketAddress.GetType().FullName, thisObj.GetType().FullName), nameof(socketAddress)); } return(socketAddress.GetIPEndPoint()); } else if (family == AddressFamily.Unknown) { return(thisObj); } System.Net.SocketAddress address = GetNetSocketAddress(socketAddress); return(thisObj.Create(address)); }
public void AcceptStart(Internals.SocketAddress address) { if (IsEnabled(EventLevel.Informational, EventKeywords.All)) { AcceptStart(address.ToString()); } }
private unsafe IPEndPoint Start(QuicListenerOptions options) { List <SslApplicationProtocol> applicationProtocols = options.ServerAuthenticationOptions !.ApplicationProtocols !; IPEndPoint listenEndPoint = options.ListenEndPoint !; Internals.SocketAddress address = IPEndPointExtensions.Serialize(listenEndPoint); Debug.Assert(_stateHandle.IsAllocated); try { Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); using var msquicBuffers = new MsQuicBuffers(); msquicBuffers.Initialize(applicationProtocols, applicationProtocol => applicationProtocol.Protocol); // TODO: is the layout same for SocketAddress.Buffer and QuicAddr? // TODO: maybe add simple extensions/helpers: // - QuicAddr ToQuicAddr(this IPEndPoint ipEndPoint) // - IPEndPoint ToIPEndPoint(this ref QuicAddr quicAddress) fixed(byte *paddress = address.Buffer) { ThrowIfFailure(MsQuicApi.Api.ApiTable->ListenerStart( _state.Handle.QuicHandle, msquicBuffers.Buffers, (uint)applicationProtocols.Count, (QuicAddr *)paddress), "ListenerStart failed"); } } catch { _stateHandle.Free(); throw; } Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); return(MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, QUIC_PARAM_LISTENER_LOCAL_ADDRESS)); }
private SocketError FinishOperationAccept(Internals.SocketAddress remoteSocketAddress) { System.Buffer.BlockCopy(_acceptBuffer, 0, remoteSocketAddress.Buffer, 0, _acceptAddressBufferCount); _acceptSocket = _currentSocket.CreateAcceptSocket( SafeCloseSocket.CreateSocket(_acceptedFileDescriptor), _currentSocket._rightEndPoint.Create(remoteSocketAddress)); return(SocketError.Success); }
// SetUnmanagedStructures // // Fills in overlapped Structures used in an async overlapped Winsock call. // These calls are outside the runtime and are unmanaged code, so we need // to prepare specific structures and ints that lie in unmanaged memory // since the overlapped calls may complete asynchronously. internal void SetUnmanagedStructures(byte[] buffer, int offset, int size, Internals.SocketAddress socketAddress, SocketFlags socketFlags) { _messageBuffer = new byte[s_wsaMsgSize]; _wsaBufferArray = new byte[s_wsaBufferSize]; bool ipv4, ipv6; Socket.GetIPProtocolInformation(((Socket)AsyncObject).AddressFamily, socketAddress, out ipv4, out ipv6); // Prepare control buffer. if (ipv4) { _controlBuffer = new byte[s_controlDataSize]; } else if (ipv6) { _controlBuffer = new byte[s_controlDataIPv6Size]; } // Pin buffers. object[] objectsToPin = new object[(_controlBuffer != null) ? 5 : 4]; objectsToPin[0] = buffer; objectsToPin[1] = _messageBuffer; objectsToPin[2] = _wsaBufferArray; // Prepare socketaddress buffer. _socketAddress = socketAddress; _socketAddress.CopyAddressSizeIntoBuffer(); objectsToPin[3] = _socketAddress.Buffer; if (_controlBuffer != null) { objectsToPin[4] = _controlBuffer; } base.SetUnmanagedStructures(objectsToPin); // Prepare data buffer. _wsaBuffer = (WSABuffer *)Marshal.UnsafeAddrOfPinnedArrayElement(_wsaBufferArray, 0); _wsaBuffer->Length = size; _wsaBuffer->Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset); // Setup structure. _message = (Interop.Winsock.WSAMsg *)Marshal.UnsafeAddrOfPinnedArrayElement(_messageBuffer, 0); _message->socketAddress = Marshal.UnsafeAddrOfPinnedArrayElement(_socketAddress.Buffer, 0); _message->addressLength = (uint)_socketAddress.Size; _message->buffers = Marshal.UnsafeAddrOfPinnedArrayElement(_wsaBufferArray, 0); _message->count = 1; if (_controlBuffer != null) { _message->controlBuffer.Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(_controlBuffer, 0); _message->controlBuffer.Length = _controlBuffer.Length; } _message->flags = socketFlags; }
public void ConnectStart(Internals.SocketAddress address) { Interlocked.Increment(ref _currentOutgoingConnectAttempts); if (IsEnabled(EventLevel.Informational, EventKeywords.All)) { ConnectStart(address.ToString()); } }
private static Internals.SocketAddress GetInternalSocketAddress(System.Net.SocketAddress address) { var result = new Internals.SocketAddress(address.Family, address.Size); for (int index = 0; index < address.Size; index++) { result[index] = address[index]; } return result; }
private static System.Net.SocketAddress GetNetSocketAddress(Internals.SocketAddress address) { var result = new System.Net.SocketAddress(address.Family, address.Size); for (int index = 0; index < address.Size; index++) { result[index] = address[index]; } return(result); }
internal static unsafe QuicAddr ToQuicAddr(this IPEndPoint iPEndPoint) { // TODO: is the layout same for SocketAddress.Buffer and QuicAddr on all platforms? QuicAddr result = default; Span <byte> rawAddress = MemoryMarshal.AsBytes(MemoryMarshal.CreateSpan(ref result, 1)); Internals.SocketAddress address = IPEndPointExtensions.Serialize(iPEndPoint); Debug.Assert(address.Size <= rawAddress.Length); address.Buffer.AsSpan(0, address.Size).CopyTo(rawAddress); return(result); }
private static int GetBestInterfaceForAddress(IPAddress addr) { int index; Internals.SocketAddress address = new Internals.SocketAddress(addr); int error = (int)Interop.IpHlpApi.GetBestInterfaceEx(address.Buffer, out index); if (error != 0) { throw new NetworkInformationException(error); } return index; }
public static EndPoint Create(this EndPoint thisObj, Internals.SocketAddress socketAddress) { if (socketAddress.Family != thisObj.AddressFamily) { throw new ArgumentException(SR.Format(SR.net_InvalidAddressFamily, socketAddress.Family.ToString(), thisObj.GetType().FullName, thisObj.AddressFamily.ToString()), "socketAddress"); } if (socketAddress.Size < 8) { throw new ArgumentException(SR.Format(SR.net_InvalidSocketAddressSize, socketAddress.GetType().FullName, thisObj.GetType().FullName), "socketAddress"); } return(socketAddress.GetIPEndPoint()); }
private static int GetBestInterfaceForAddress(IPAddress addr) { int index; Internals.SocketAddress address = new Internals.SocketAddress(addr); int error = (int)Interop.IpHlpApi.GetBestInterfaceEx(address.Buffer, out index); if (error != 0) { throw new NetworkInformationException(error); } return(index); }
internal static unsafe void SetIPEndPointParam(MsQuicApi api, SafeHandle nativeObject, uint param, IPEndPoint value) { Internals.SocketAddress socketAddress = IPEndPointExtensions.Serialize(value); // MsQuic always reads same amount of memory as if IPv6 was used, so we can't pass pointer to socketAddress.Buffer directly Span <byte> address = stackalloc byte[Internals.SocketAddress.IPv6AddressSize]; socketAddress.Buffer.AsSpan(0, socketAddress.Size).CopyTo(address); address.Slice(socketAddress.Size).Clear(); fixed(byte *paddress = &MemoryMarshal.GetReference(address)) { QuicExceptionHelpers.ThrowIfFailed( api.SetParamDelegate(nativeObject, param, (uint)address.Length, paddress), "Could not set IPEndPoint"); } }
public void CompletionCallback(IntPtr acceptedFileDescriptor, byte[] socketAddress, int socketAddressLen, SocketError errorCode) { _buffer = null; _numBytes = 0; if (errorCode == SocketError.Success) { Internals.SocketAddress remoteSocketAddress = IPEndPointExtensions.Serialize(_listenSocket._rightEndPoint); System.Buffer.BlockCopy(socketAddress, 0, remoteSocketAddress.Buffer, 0, socketAddressLen); _acceptedSocket = _listenSocket.CreateAcceptSocket( SocketPal.CreateSocket(acceptedFileDescriptor), _listenSocket._rightEndPoint.Create(remoteSocketAddress)); } base.CompletionCallback(0, errorCode); }
public void CompletionCallback(int acceptedFileDescriptor, byte[] socketAddress, int socketAddressLen, SocketError errorCode) { // TODO: receive bytes on accepted socket if requested _buffer = null; _localBytesTransferred = 0; if (errorCode == SocketError.Success) { Internals.SocketAddress remoteSocketAddress = IPEndPointExtensions.Serialize(_listenSocket._rightEndPoint); System.Buffer.BlockCopy(socketAddress, 0, remoteSocketAddress.Buffer, 0, socketAddressLen); _acceptedSocket = _listenSocket.CreateAcceptSocket( SafeCloseSocket.CreateSocket(acceptedFileDescriptor), _listenSocket._rightEndPoint.Create(remoteSocketAddress)); } base.CompletionCallback(0, errorCode); }
private int SendEcho(IPAddress address, byte[] buffer, int timeout, PingOptions options, bool isAsync) { Interop.IpHlpApi.IPOptions ipOptions = new Interop.IpHlpApi.IPOptions(options); if (!_ipv6) { return((int)Interop.IpHlpApi.IcmpSendEcho2( _handlePingV4, GetWaitHandle(isAsync), IntPtr.Zero, IntPtr.Zero, #pragma warning disable CS0618 // Address is marked obsolete (uint)address.Address, #pragma warning restore CS0618 _requestBuffer, (ushort)buffer.Length, ref ipOptions, _replyBuffer, MaxUdpPacket, (uint)timeout)); } IPEndPoint ep = new IPEndPoint(address, 0); Internals.SocketAddress remoteAddr = IPEndPointExtensions.Serialize(ep); byte[] sourceAddr = new byte[28]; return((int)Interop.IpHlpApi.Icmp6SendEcho2( _handlePingV6, GetWaitHandle(isAsync), IntPtr.Zero, IntPtr.Zero, sourceAddr, remoteAddr.Buffer, _requestBuffer, (ushort)buffer.Length, ref ipOptions, _replyBuffer, MaxUdpPacket, (uint)timeout)); }
// SetUnmanagedStructures // // Fills in overlapped structures used in an async overlapped Winsock call. // These calls are outside the runtime and are unmanaged code, so we need // to prepare specific structures and ints that lie in unmanaged memory // since the overlapped calls may complete asynchronously. internal void SetUnmanagedStructures(byte[] buffer, int offset, int size, Internals.SocketAddress socketAddress, bool pinSocketAddress) { // Fill in Buffer Array structure that will be used for our send/recv Buffer _socketAddress = socketAddress; if (pinSocketAddress && _socketAddress != null) { object[] objectsToPin = null; objectsToPin = new object[2]; objectsToPin[0] = buffer; _socketAddress.CopyAddressSizeIntoBuffer(); objectsToPin[1] = _socketAddress.Buffer; base.SetUnmanagedStructures(objectsToPin); } else { base.SetUnmanagedStructures(buffer); } _singleBuffer.Length = size; _singleBuffer.Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, offset); }
private unsafe IPEndPoint Start(QuicListenerOptions options) { List <SslApplicationProtocol> applicationProtocols = options.ServerAuthenticationOptions !.ApplicationProtocols !; IPEndPoint listenEndPoint = options.ListenEndPoint !; Internals.SocketAddress address = IPEndPointExtensions.Serialize(listenEndPoint); uint status; Debug.Assert(_stateHandle.IsAllocated); MemoryHandle[]? handles = null; QuicBuffer[]? buffers = null; try { Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); MsQuicAlpnHelper.Prepare(applicationProtocols, out handles, out buffers); fixed(byte *paddress = address.Buffer) { status = MsQuicApi.Api.ListenerStartDelegate(_state.Handle, (QuicBuffer *)Marshal.UnsafeAddrOfPinnedArrayElement(buffers, 0), (uint)applicationProtocols.Count, paddress); } } catch { _stateHandle.Free(); throw; } finally { MsQuicAlpnHelper.Return(ref handles, ref buffers); } QuicExceptionHelpers.ThrowIfFailed(status, "ListenerStart failed."); Debug.Assert(!Monitor.IsEntered(_state), "!Monitor.IsEntered(_state)"); return(MsQuicParameterHelpers.GetIPEndPointParam(MsQuicApi.Api, _state.Handle, (uint)QUIC_PARAM_LISTENER.LOCAL_ADDRESS)); }
public static unsafe SocketError ReceiveMessageFromAsync(Socket socket, SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, ReceiveMessageOverlappedAsyncResult asyncResult) { asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, socketFlags); int bytesTransfered; SocketError errorCode = (SocketError)socket.WSARecvMsg( handle, Marshal.UnsafeAddrOfPinnedArrayElement(asyncResult._messageBuffer, 0), out bytesTransfered, asyncResult.OverlappedHandle, IntPtr.Zero); if (errorCode != SocketError.Success) { errorCode = GetLastSocketError(); } return(errorCode); }
public static unsafe SocketError ReceiveFromAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSARecvFrom. // This call will use completion ports on WinNT and Overlapped IO on Win9x. asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, true); int bytesTransferred; SocketError errorCode = Interop.Winsock.WSARecvFrom( handle, ref asyncResult._singleBuffer, 1, out bytesTransferred, ref socketFlags, asyncResult.GetSocketAddressPtr(), asyncResult.GetSocketAddressSizePtr(), asyncResult.OverlappedHandle, IntPtr.Zero); if (errorCode != SocketError.Success) { errorCode = GetLastSocketError(); } return(errorCode); }
public static unsafe SocketError SendToAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSASendTo. // This call will use completion ports. asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, false /* don't pin RemoteEP*/); int bytesTransferred; SocketError errorCode = Interop.Winsock.WSASendTo( handle, ref asyncResult._singleBuffer, 1, // There is only ever 1 buffer being sent. out bytesTransferred, socketFlags, asyncResult.GetSocketAddressPtr(), asyncResult.SocketAddress.Size, asyncResult.OverlappedHandle, IntPtr.Zero); if (errorCode != SocketError.Success) { errorCode = GetLastSocketError(); } return(errorCode); }
public static SocketError ReceiveMessageFrom(Socket socket, SafeCloseSocket handle, byte[] buffer, int offset, int size, ref SocketFlags socketFlags, Internals.SocketAddress socketAddress, out Internals.SocketAddress receiveAddress, out IPPacketInformation ipPacketInformation, out int bytesTransferred) { ReceiveMessageOverlappedAsyncResult asyncResult = new ReceiveMessageOverlappedAsyncResult(socket, null, null); asyncResult.SetUnmanagedStructures(buffer, offset, size, socketAddress, socketFlags); SocketError errorCode = SocketError.Success; bytesTransferred = 0; try { // This can throw ObjectDisposedException (retrieving the delegate AND resolving the handle). if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), Marshal.UnsafeAddrOfPinnedArrayElement(asyncResult._messageBuffer, 0), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { errorCode = (SocketError)Marshal.GetLastWin32Error(); } } finally { asyncResult.SyncReleaseUnmanagedStructures(); } socketFlags = asyncResult.SocketFlags; receiveAddress = asyncResult.SocketAddress; ipPacketInformation = asyncResult.IPPacketInformation; return(errorCode); }
// This method will be called by us when the IO completes synchronously and // by the ThreadPool when the IO completes asynchronously. (only called on WinNT) internal override object PostCompletion(int numBytes) { SocketError errorCode = (SocketError)ErrorCode; Internals.SocketAddress remoteSocketAddress = null; if (errorCode == SocketError.Success) { _localBytesTransferred = numBytes; if (NetEventSource.IsEnabled) { LogBuffer(numBytes); } // get the endpoint remoteSocketAddress = IPEndPointExtensions.Serialize(_listenSocket._rightEndPoint); IntPtr localAddr; int localAddrLength; IntPtr remoteAddr; // set the socket context try { _listenSocket.GetAcceptExSockaddrs( Marshal.UnsafeAddrOfPinnedArrayElement(_buffer, 0), _buffer.Length - (_addressBufferLength * 2), _addressBufferLength, _addressBufferLength, out localAddr, out localAddrLength, out remoteAddr, out remoteSocketAddress.InternalSize); Marshal.Copy(remoteAddr, remoteSocketAddress.Buffer, 0, remoteSocketAddress.Size); IntPtr handle = _listenSocket.SafeHandle.DangerousGetHandle(); errorCode = Interop.Winsock.setsockopt( _acceptSocket.SafeHandle, SocketOptionLevel.Socket, SocketOptionName.UpdateAcceptContext, ref handle, Marshal.SizeOf(handle)); if (errorCode == SocketError.SocketError) { errorCode = (SocketError)Marshal.GetLastWin32Error(); } if (NetEventSource.IsEnabled) { NetEventSource.Info(this, $"setsockopt handle:{handle}, AcceptSocket:{_acceptSocket}, returns:{errorCode}"); } } catch (ObjectDisposedException) { errorCode = SocketError.OperationAborted; } ErrorCode = (int)errorCode; } if (errorCode != SocketError.Success) { return(null); } return(_listenSocket.UpdateAcceptSocket(_acceptSocket, _listenSocket._rightEndPoint.Create(remoteSocketAddress))); }
public static unsafe SocketError SendToAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSASendTo. asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, false /* don't pin RemoteEP*/); try { int bytesTransferred; SocketError errorCode = Interop.Winsock.WSASendTo( handle, ref asyncResult._singleBuffer, 1, // There is only ever 1 buffer being sent. out bytesTransferred, socketFlags, asyncResult.GetSocketAddressPtr(), asyncResult.SocketAddress.Size, asyncResult.OverlappedHandle, IntPtr.Zero); return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred)); } catch { asyncResult.ReleaseUnmanagedStructures(); throw; } }
public static unsafe SocketError ReceiveMessageFrom(Socket socket, SafeCloseSocket handle, byte[] buffer, int offset, int size, ref SocketFlags socketFlags, Internals.SocketAddress socketAddress, out Internals.SocketAddress receiveAddress, out IPPacketInformation ipPacketInformation, out int bytesTransferred) { bool ipv4, ipv6; Socket.GetIPProtocolInformation(socket.AddressFamily, socketAddress, out ipv4, out ipv6); bytesTransferred = 0; receiveAddress = socketAddress; ipPacketInformation = default(IPPacketInformation); fixed(byte *ptrBuffer = buffer) fixed(byte *ptrSocketAddress = socketAddress.Buffer) { Interop.Winsock.WSAMsg wsaMsg; wsaMsg.socketAddress = (IntPtr)ptrSocketAddress; wsaMsg.addressLength = (uint)socketAddress.Size; wsaMsg.flags = socketFlags; WSABuffer wsaBuffer; wsaBuffer.Length = size; wsaBuffer.Pointer = (IntPtr)(ptrBuffer + offset); wsaMsg.buffers = (IntPtr)(&wsaBuffer); wsaMsg.count = 1; if (ipv4) { Interop.Winsock.ControlData controlBuffer; wsaMsg.controlBuffer.Pointer = (IntPtr)(&controlBuffer); wsaMsg.controlBuffer.Length = sizeof(Interop.Winsock.ControlData); if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), (IntPtr)(&wsaMsg), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { return(GetLastSocketError()); } ipPacketInformation = GetIPPacketInformation(&controlBuffer); } else if (ipv6) { Interop.Winsock.ControlDataIPv6 controlBuffer; wsaMsg.controlBuffer.Pointer = (IntPtr)(&controlBuffer); wsaMsg.controlBuffer.Length = sizeof(Interop.Winsock.ControlDataIPv6); if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), (IntPtr)(&wsaMsg), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { return(GetLastSocketError()); } ipPacketInformation = GetIPPacketInformation(&controlBuffer); } else { wsaMsg.controlBuffer.Pointer = IntPtr.Zero; wsaMsg.controlBuffer.Length = 0; if (socket.WSARecvMsgBlocking( handle.DangerousGetHandle(), (IntPtr)(&wsaMsg), out bytesTransferred, IntPtr.Zero, IntPtr.Zero) == SocketError.SocketError) { return(GetLastSocketError()); } } socketFlags = wsaMsg.flags; } return(SocketError.Success); }
public static unsafe SocketError ReceiveFromAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSARecvFrom. asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, true); try { int bytesTransferred; SocketError errorCode = Interop.Winsock.WSARecvFrom( handle, ref asyncResult._singleBuffer, 1, out bytesTransferred, ref socketFlags, asyncResult.GetSocketAddressPtr(), asyncResult.GetSocketAddressSizePtr(), asyncResult.OverlappedHandle, IntPtr.Zero); return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred)); } catch { asyncResult.ReleaseUnmanagedStructures(); throw; } }
public static unsafe SocketError ReceiveMessageFromAsync(Socket socket, SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, ReceiveMessageOverlappedAsyncResult asyncResult) { asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress, socketFlags); try { int bytesTransfered; SocketError errorCode = (SocketError)socket.WSARecvMsg( handle, Marshal.UnsafeAddrOfPinnedArrayElement(asyncResult._messageBuffer, 0), out bytesTransfered, asyncResult.DangerousOverlappedPointer, // SafeHandle was just created in SetUnmanagedStructures IntPtr.Zero); return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransfered)); } catch { asyncResult.ReleaseUnmanagedStructures(); throw; } }
internal void FinishOperationSuccess(SocketError socketError, int bytesTransferred, SocketFlags flags) { SetResults(socketError, bytesTransferred, flags); switch (_completedOperation) { case SocketAsyncOperation.Accept: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, false); } } // Get the endpoint. Internals.SocketAddress remoteSocketAddress = IPEndPointExtensions.Serialize(_currentSocket._rightEndPoint); socketError = FinishOperationAccept(remoteSocketAddress); if (socketError == SocketError.Success) { _acceptSocket = _currentSocket.UpdateAcceptSocket(_acceptSocket, _currentSocket._rightEndPoint.Create(remoteSocketAddress)); if (s_loggingEnabled) { SocketsEventSource.Accepted(_acceptSocket, _acceptSocket.RemoteEndPoint, _acceptSocket.LocalEndPoint); } } else { SetResults(socketError, bytesTransferred, SocketFlags.None); _acceptSocket = null; } break; case SocketAsyncOperation.Connect: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, true); } } socketError = FinishOperationConnect(); // Mark socket connected. if (socketError == SocketError.Success) { if (s_loggingEnabled) { SocketsEventSource.Connected(_currentSocket, _currentSocket.LocalEndPoint, _currentSocket.RemoteEndPoint); } _currentSocket.SetToConnected(); _connectSocket = _currentSocket; } break; case SocketAsyncOperation.Disconnect: _currentSocket.SetToDisconnected(); _currentSocket._remoteEndPoint = null; break; case SocketAsyncOperation.Receive: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, false); } } break; case SocketAsyncOperation.ReceiveFrom: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, false); } } // Deal with incoming address. _socketAddress.InternalSize = GetSocketAddressSize(); Internals.SocketAddress socketAddressOriginal = IPEndPointExtensions.Serialize(_remoteEndPoint); if (!socketAddressOriginal.Equals(_socketAddress)) { try { _remoteEndPoint = _remoteEndPoint.Create(_socketAddress); } catch { } } break; case SocketAsyncOperation.ReceiveMessageFrom: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, false); } } // Deal with incoming address. _socketAddress.InternalSize = GetSocketAddressSize(); socketAddressOriginal = IPEndPointExtensions.Serialize(_remoteEndPoint); if (!socketAddressOriginal.Equals(_socketAddress)) { try { _remoteEndPoint = _remoteEndPoint.Create(_socketAddress); } catch { } } FinishOperationReceiveMessageFrom(); break; case SocketAsyncOperation.Send: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, true); } } break; case SocketAsyncOperation.SendPackets: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogSendPacketsBuffers(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, true); } } FinishOperationSendPackets(); break; case SocketAsyncOperation.SendTo: if (bytesTransferred > 0) { // Log and Perf counters. if (s_loggingEnabled) { LogBuffer(bytesTransferred); } if (Socket.s_perfCountersEnabled) { UpdatePerfCounters(bytesTransferred, true); } } break; } if (socketError != SocketError.Success) { // Asynchronous failure or something went wrong after async success. SetResults(socketError, bytesTransferred, flags); _currentSocket.UpdateStatusAfterSocketError(socketError); } // Complete the operation and raise completion event. Complete(); if (_contextCopy == null) { OnCompleted(this); } else { ExecutionContext.Run(_contextCopy, _executionCallback, null); } }
// This method will be called by us when the IO completes synchronously and // by the ThreadPool when the IO completes asynchronously. (only called on WinNT) internal override object PostCompletion(int numBytes) { SocketError errorCode = (SocketError)ErrorCode; Internals.SocketAddress remoteSocketAddress = null; if (errorCode == SocketError.Success) { _localBytesTransferred = numBytes; if (SocketsEventSource.Log.IsEnabled()) { LogBuffer((long)numBytes); } // get the endpoint remoteSocketAddress = IPEndPointExtensions.Serialize(_listenSocket._rightEndPoint); IntPtr localAddr; int localAddrLength; IntPtr remoteAddr; // set the socket context try { _listenSocket.GetAcceptExSockaddrs( Marshal.UnsafeAddrOfPinnedArrayElement(_buffer, 0), _buffer.Length - (_addressBufferLength * 2), _addressBufferLength, _addressBufferLength, out localAddr, out localAddrLength, out remoteAddr, out remoteSocketAddress.InternalSize); Marshal.Copy(remoteAddr, remoteSocketAddress.Buffer, 0, remoteSocketAddress.Size); IntPtr handle = _listenSocket.SafeHandle.DangerousGetHandle(); errorCode = Interop.Winsock.setsockopt( _acceptSocket.SafeHandle, SocketOptionLevel.Socket, SocketOptionName.UpdateAcceptContext, ref handle, Marshal.SizeOf(handle)); if (errorCode == SocketError.SocketError) { errorCode = (SocketError)Marshal.GetLastWin32Error(); } if (GlobalLog.IsEnabled) { GlobalLog.Print("AcceptOverlappedAsyncResult#" + LoggingHash.HashString(this) + "::PostCallback() setsockopt handle:" + handle.ToString() + " AcceptSocket:" + LoggingHash.HashString(_acceptSocket) + " itsHandle:" + _acceptSocket.SafeHandle.DangerousGetHandle().ToString() + " returns:" + errorCode.ToString()); } } catch (ObjectDisposedException) { errorCode = SocketError.OperationAborted; } ErrorCode = (int)errorCode; } if (errorCode != SocketError.Success) { return(null); } return(_listenSocket.UpdateAcceptSocket(_acceptSocket, _listenSocket._rightEndPoint.Create(remoteSocketAddress))); }
public static unsafe SocketError SendToAsync(SafeCloseSocket handle, byte[] buffer, int offset, int count, SocketFlags socketFlags, Internals.SocketAddress socketAddress, OverlappedAsyncResult asyncResult) { // Set up asyncResult for overlapped WSASendTo. asyncResult.SetUnmanagedStructures(buffer, offset, count, socketAddress); try { int bytesTransferred; SocketError errorCode = Interop.Winsock.WSASendTo( handle.DangerousGetHandle(), // to minimize chances of handle recycling from misuse, this should use DangerousAddRef/Release, but it adds too much overhead ref asyncResult._singleBuffer, 1, // There is only ever 1 buffer being sent. out bytesTransferred, socketFlags, asyncResult.GetSocketAddressPtr(), asyncResult.SocketAddress.Size, asyncResult.DangerousOverlappedPointer, // SafeHandle was just created in SetUnmanagedStructures IntPtr.Zero); GC.KeepAlive(handle); // small extra safe guard against handle getting collected/finalized while P/Invoke in progress return(asyncResult.ProcessOverlappedResult(errorCode == SocketError.Success, bytesTransferred)); } catch { asyncResult.ReleaseUnmanagedStructures(); throw; } }
public CachedSerializedEndPoint(IPAddress address) { IPEndPoint = new IPEndPoint(address, 0); SocketAddress = IPEndPointExtensions.Serialize(IPEndPoint); }
public static unsafe SocketError ReceiveMessageFrom(Socket socket, SafeSocketHandle handle, byte[] buffer, int offset, int size, ref SocketFlags socketFlags, Internals.SocketAddress socketAddress, out Internals.SocketAddress receiveAddress, out IPPacketInformation ipPacketInformation, out int bytesTransferred) { return(ReceiveMessageFrom(socket, handle, new Span <byte>(buffer, offset, size), ref socketFlags, socketAddress, out receiveAddress, out ipPacketInformation, out bytesTransferred)); }