コード例 #1
0
        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));
        }
コード例 #2
0
ファイル: SocketsTelemetry.cs プロジェクト: mikem8361/runtime
 public void AcceptStart(Internals.SocketAddress address)
 {
     if (IsEnabled(EventLevel.Informational, EventKeywords.All))
     {
         AcceptStart(address.ToString());
     }
 }
コード例 #3
0
ファイル: MsQuicListener.cs プロジェクト: naricc/runtime
        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));
        }
コード例 #4
0
 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);
 }
コード例 #5
0
        // 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;
        }
コード例 #6
0
ファイル: SocketsTelemetry.cs プロジェクト: mikem8361/runtime
        public void ConnectStart(Internals.SocketAddress address)
        {
            Interlocked.Increment(ref _currentOutgoingConnectAttempts);

            if (IsEnabled(EventLevel.Informational, EventKeywords.All))
            {
                ConnectStart(address.ToString());
            }
        }
コード例 #7
0
        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;
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        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;
        }
コード例 #11
0
        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());
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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");
            }
        }
コード例 #14
0
        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);
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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));
        }
コード例 #17
0
        // 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);
        }
コード例 #18
0
        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));
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        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);
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        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);
        }
コード例 #23
0
        // 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)));
        }
コード例 #24
0
        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;
            }
        }
コード例 #25
0
        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);
        }
コード例 #26
0
        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;
            }
        }
コード例 #27
0
ファイル: SocketPal.Windows.cs プロジェクト: zeroyou/corefx
        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;
            }
        }
コード例 #28
0
        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);
            }
        }
コード例 #29
0
        // 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)));
        }
コード例 #30
0
ファイル: SocketPal.Windows.cs プロジェクト: zeroyou/corefx
        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;
            }
        }
コード例 #31
0
 public CachedSerializedEndPoint(IPAddress address)
 {
     IPEndPoint    = new IPEndPoint(address, 0);
     SocketAddress = IPEndPointExtensions.Serialize(IPEndPoint);
 }
コード例 #32
0
 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));
 }