예제 #1
0
        private static unsafe void CreateSocket()
        {
            Debug.Assert(Monitor.IsEntered(s_gate));
            Debug.Assert(Socket == null, "Socket is not null, must close existing socket before opening another.");

            var sh = new SafeSocketHandle();

            IntPtr newSocket;

            Interop.Error result = Interop.Sys.CreateNetworkChangeListenerSocket(&newSocket);
            if (result != Interop.Error.SUCCESS)
            {
                string message = Interop.Sys.GetLastErrorInfo().GetErrorMessage();
                sh.Dispose();
                throw new NetworkInformationException(message);
            }

            Marshal.InitHandle(sh, newSocket);
            Socket = new Socket(sh);

            // Don't capture ExecutionContext.
            ThreadPool.UnsafeQueueUserWorkItem(
예제 #2
0
 public void Dispose()
 {
     _handle.Dispose();
 }
예제 #3
0
        public ValueTask UnbindAsync(CancellationToken cancellationToken = default)
        {
            _listenSocket?.Dispose();

            _socketHandle?.Dispose();
            return(default);
예제 #4
0
        public async Task SendFileGetsCanceledByDispose(bool owning)
        {
            // Aborting sync operations for non-owning handles is not supported on Unix.
            if (!owning && UsesSync && !PlatformDetection.IsWindows)
            {
                return;
            }

            // We try this a couple of times to deal with a timing race: if the Dispose happens
            // before the operation is started, the peer won't see a ConnectionReset SocketException and we won't
            // see a SocketException either.
            int msDelay = 100;
            await RetryHelper.ExecuteAsync(async() =>
            {
                (Socket socket1, Socket socket2) = SocketTestExtensions.CreateConnectedSocketPair();
                using SafeSocketHandle? owner    = ReplaceWithNonOwning(ref socket1, owning);

                using (socket2)
                {
                    Task socketOperation = Task.Run(async() =>
                    {
                        // Create a large file that will cause SendFile to block until the peer starts reading.
                        using var tempFile = TempFile.Create();
                        using (var fs = new FileStream(tempFile.Path, FileMode.CreateNew, FileAccess.Write))
                        {
                            fs.SetLength(20 * 1024 * 1024 /* 20MB */);
                        }

                        await SendFileAsync(socket1, tempFile.Path);
                    });

                    // Wait a little so the operation is started.
                    await Task.Delay(msDelay);
                    msDelay         *= 2;
                    Task disposeTask = Task.Run(() => socket1.Dispose());

                    await Task.WhenAny(disposeTask, socketOperation).WaitAsync(TimeSpan.FromSeconds(30));
                    await disposeTask;

                    SocketError?localSocketError = null;

                    try
                    {
                        await socketOperation;
                    }
                    catch (SocketException se)
                    {
                        localSocketError = se.SocketErrorCode;
                    }

                    if (UsesSync)
                    {
                        Assert.Equal(SocketError.ConnectionAborted, localSocketError);
                    }
                    else
                    {
                        Assert.Equal(SocketError.OperationAborted, localSocketError);
                    }

                    owner?.Dispose();

                    // On OSX, we're unable to unblock the on-going socket operations and
                    // perform an abortive close.
                    if (!(UsesSync && PlatformDetection.IsOSXLike))
                    {
                        SocketError?peerSocketError = null;
                        var receiveBuffer           = new byte[4096];
                        while (true)
                        {
                            try
                            {
                                int received = socket2.Receive(receiveBuffer);
                                if (received == 0)
                                {
                                    break;
                                }
                            }
                            catch (SocketException se)
                            {
                                peerSocketError = se.SocketErrorCode;
                                break;
                            }
                        }
                        Assert.Equal(SocketError.ConnectionReset, peerSocketError);
                    }
                }
            }, maxAttempts : 10, retryWhen : e => e is XunitException);
        }