public override int EndRead(IAsyncResult asyncResult) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif _negoState.CheckThrow(true); if (!_negoState.CanGetSecureStream) { return(TaskToApm.End <int>(asyncResult)); } if (asyncResult == null) { throw new ArgumentNullException(nameof(asyncResult)); } BufferAsyncResult bufferResult = asyncResult as BufferAsyncResult; if (bufferResult == null) { throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); } if (Interlocked.Exchange(ref _NestedRead, 0) == 0) { throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndRead")); } // No "artificial" timeouts implemented so far, InnerStream controls timeout. bufferResult.InternalWaitForCompletion(); if (bufferResult.Result is Exception e) { if (e is IOException) { ExceptionDispatchInfo.Throw(e); } throw new IOException(SR.net_io_read, e); } return(bufferResult.Int32Result); #if DEBUG } #endif }
// BeginWrite - provide async write functionality. // // This method provides async write functionality. All we do is // call through to the underlying socket async send. // // Input: // // buffer - Buffer to write into. // offset - Offset into the buffer where we're to write. // size - Number of bytes to written. // // Returns: // // An IASyncResult, representing the write. public override IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, object state) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif bool canWrite = CanWrite; // Prevent race with Dispose. ThrowIfDisposed(); if (!canWrite) { throw new InvalidOperationException(SR.net_readonlystream); } // Validate input parameters. if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if ((uint)offset > buffer.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } if ((uint)size > buffer.Length - offset) { throw new ArgumentOutOfRangeException(nameof(size)); } try { // Call BeginSend on the Socket. return(_streamSocket.BeginSend( buffer, offset, size, SocketFlags.None, callback, state)); } catch (Exception exception) when(!(exception is OutOfMemoryException)) { // Some sort of error occurred on the socket call, // set the SocketException as InnerException and throw. throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } #if DEBUG } #endif }
private int _closeTimeout = Socket.DefaultCloseTimeout; // -1 = respect linger options public void Close(int timeout) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif if (timeout < -1) { throw new ArgumentOutOfRangeException(nameof(timeout)); } _closeTimeout = timeout; Dispose(); #if DEBUG } #endif }
public NetworkStream(Socket socket, FileAccess access, bool ownsSocket) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif if (socket == null) { throw new ArgumentNullException(nameof(socket)); } if (!socket.Blocking) { throw new IOException(SR.net_sockets_blocking); } if (!socket.Connected) { throw new IOException(SR.net_notconnected); } if (socket.SocketType != SocketType.Stream) { throw new IOException(SR.net_notstream); } _streamSocket = socket; _ownsSocket = ownsSocket; switch (access) { case FileAccess.Read: _readable = true; break; case FileAccess.Write: _writeable = true; break; case FileAccess.ReadWrite: default: // assume FileAccess.ReadWrite _readable = true; _writeable = true; break; } #if DEBUG } #endif }
public override void EndWrite(IAsyncResult asyncResult) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif _negoState.CheckThrow(true); if (!_negoState.CanGetSecureStream) { InnerStream.EndWrite(asyncResult); return; } if (asyncResult == null) { throw new ArgumentNullException(nameof(asyncResult)); } BufferAsyncResult bufferResult = asyncResult as BufferAsyncResult; if (bufferResult == null) { throw new ArgumentException(SR.Format(SR.net_io_async_result, asyncResult.GetType().FullName), nameof(asyncResult)); } if (Interlocked.Exchange(ref _NestedWrite, 0) == 0) { throw new InvalidOperationException(SR.Format(SR.net_io_invalidendcall, "EndWrite")); } // No "artificial" timeouts implemented so far, InnerStream controls timeout. bufferResult.InternalWaitForCompletion(); if (bufferResult.Result is Exception) { if (bufferResult.Result is IOException) { throw (Exception)bufferResult.Result; } throw new IOException(SR.net_io_write, (Exception)bufferResult.Result); } #if DEBUG } #endif }
// Write - provide core Write functionality. // // Provide core write functionality. All we do is call through to the // socket Send method.. // // Input: // // Buffer - Buffer to write from. // Offset - Offset into the buffer from where we'll start writing. // Count - Number of bytes to write. // // Returns: // // Number of bytes written. We'll throw an exception if we // can't write everything. It's brutal, but there's no other // way to indicate an error. public override void Write(byte[] buffer, int offset, int size) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif bool canWrite = CanWrite; // Prevent race with Dispose. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (!canWrite) { throw new InvalidOperationException(SR.net_readonlystream); } // Validate input parameters. if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException(nameof(size)); } try { // Since the socket is in blocking mode this will always complete // after ALL the requested number of bytes was transferred. _streamSocket.Send(buffer, offset, size, SocketFlags.None); } catch (Exception exception) when(!(exception is OutOfMemoryException)) { // Some sort of error occurred on the socket call, // set the SocketException as InnerException and throw. throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } #if DEBUG } #endif }
protected override void Dispose(bool disposing) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif try { _negoState.Close(); } finally { base.Dispose(disposing); } #if DEBUG } #endif }
// Read - provide core Read functionality. // // Provide core read functionality. All we do is call through to the // socket Receive functionality. // // Input: // // Buffer - Buffer to read into. // Offset - Offset into the buffer where we're to read. // Count - Number of bytes to read. // // Returns: // // Number of bytes we read, or 0 if the socket is closed. public override int Read(byte[] buffer, int offset, int size) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif bool canRead = CanRead; // Prevent race with Dispose. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (!canRead) { throw new InvalidOperationException(SR.net_writeonlystream); } // Validate input parameters. if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException(nameof(size)); } try { return(_streamSocket.Receive(buffer, offset, size, 0)); } catch (Exception exception) when(!(exception is OutOfMemoryException)) { // Some sort of error occurred on the socket call, // set the SocketException as InnerException and throw. throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } #if DEBUG } #endif }
public override int Read(byte[] buffer, int offset, int count) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif _negoState.CheckThrow(true); if (!_negoState.CanGetSecureStream) { return(InnerStream.Read(buffer, offset, count)); } return(ProcessRead(buffer, offset, count, null)); #if DEBUG } #endif }
public override void Write(byte[] buffer, int offset, int count) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Sync)) { #endif _negoState.CheckThrow(true); if (!_negoState.CanGetSecureStream) { InnerStream.Write(buffer, offset, count); return; } ProcessWrite(buffer, offset, count, null); #if DEBUG } #endif }
public int EndRead(IAsyncResult asyncResult) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } // Validate input parameters. if (asyncResult == null) { throw new ArgumentNullException(nameof(asyncResult)); } Socket chkStreamSocket = _streamSocket; if (chkStreamSocket == null) { throw new IOException(SR.Format(SR.net_io_readfailure, SR.net_io_connectionclosed)); } try { int bytesTransferred = chkStreamSocket.EndReceive(asyncResult); return(bytesTransferred); } catch (Exception exception) { if (exception is OutOfMemoryException) { throw; } // Some sort of error occurred on the socket call, // set the SocketException as InnerException and throw. throw new IOException(SR.Format(SR.net_io_readfailure, exception.Message), exception); } #if DEBUG } #endif }
protected override void Dispose(bool disposing) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif // Mark this as disposed before changing anything else. bool cleanedUp = _cleanedUp; _cleanedUp = true; if (!cleanedUp && disposing) { // The only resource we need to free is the network stream, since this // is based on the client socket, closing the stream will cause us // to flush the data to the network, close the stream and (in the // NetoworkStream code) close the socket as well. if (_streamSocket != null) { _readable = false; _writeable = false; if (_ownsSocket) { // If we own the Socket (false by default), close it // ignoring possible exceptions (eg: the user told us // that we own the Socket but it closed at some point of time, // here we would get an ObjectDisposedException) Socket chkStreamSocket = _streamSocket; if (chkStreamSocket != null) { chkStreamSocket.InternalShutdown(SocketShutdown.Both); chkStreamSocket.Close(_closeTimeout); } } } } #if DEBUG } #endif base.Dispose(disposing); }
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback?asyncCallback, object?asyncState) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif _negoState.CheckThrow(true); if (!_negoState.CanGetSecureStream) { return(TaskToApm.Begin(InnerStream.ReadAsync(buffer, offset, count), asyncCallback, asyncState)); } BufferAsyncResult bufferResult = new BufferAsyncResult(this, buffer, offset, count, asyncState, asyncCallback); AsyncProtocolRequest asyncRequest = new AsyncProtocolRequest(bufferResult); ProcessRead(buffer, offset, count, asyncRequest); return(bufferResult); #if DEBUG } #endif }
public virtual IAsyncResult BeginAuthenticateAsServer( NetworkCredential credential, ExtendedProtectionPolicy?policy, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel requiredImpersonationLevel, AsyncCallback?asyncCallback, object?asyncState) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif _negoState.ValidateCreateContext(_package, credential, string.Empty, policy, requiredProtectionLevel, requiredImpersonationLevel); LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback); _negoState.ProcessAuthentication(result); return(result); #if DEBUG } #endif }
public virtual IAsyncResult BeginAuthenticateAsClient( NetworkCredential credential, ChannelBinding?binding, string targetName, ProtectionLevel requiredProtectionLevel, TokenImpersonationLevel allowedImpersonationLevel, AsyncCallback?asyncCallback, object?asyncState) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif _negoState.ValidateCreateContext(_package, false, credential, targetName, binding, requiredProtectionLevel, allowedImpersonationLevel); LazyAsyncResult result = new LazyAsyncResult(_negoState, asyncState, asyncCallback); _negoState.ProcessAuthentication(result); return(result); #if DEBUG } #endif }
private static unsafe void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { #if DEBUG DebugThreadTracking.SetThreadSource(ThreadKinds.CompletionPort); using (DebugThreadTracking.SetThreadKind(ThreadKinds.System)) { #endif BaseOverlappedAsyncResult asyncResult = (BaseOverlappedAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped); object returnObject = null; if (asyncResult.InternalPeekCompleted) { NetEventSource.Fail(null, $"asyncResult.IsCompleted: {asyncResult}"); } if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"errorCode:{errorCode} numBytes:{numBytes} nativeOverlapped:{(IntPtr)nativeOverlapped}"); } // Complete the IO and invoke the user's callback. SocketError socketError = (SocketError)errorCode; if (socketError != SocketError.Success && socketError != SocketError.OperationAborted) { // There are cases where passed errorCode does not reflect the details of the underlined socket error. // "So as of today, the key is the difference between WSAECONNRESET and ConnectionAborted, // .e.g remote party or network causing the connection reset or something on the local host (e.g. closesocket // or receiving data after shutdown (SD_RECV)). With Winsock/TCP stack rewrite in longhorn, there may // be other differences as well." Socket socket = asyncResult.AsyncObject as Socket; if (socket == null) { socketError = SocketError.NotSocket; } else if (socket.CleanedUp) { socketError = SocketError.OperationAborted; } else { try { // The async IO completed with a failure. // Here we need to call WSAGetOverlappedResult() just so Marshal.GetLastWin32Error() will return the correct error. SocketFlags ignore; bool success = Interop.Winsock.WSAGetOverlappedResult( socket.SafeHandle, asyncResult.NativeOverlapped, out numBytes, false, out ignore); if (!success) { socketError = (SocketError)Marshal.GetLastWin32Error(); if (socketError == 0) { NetEventSource.Fail(asyncResult, $"socketError:0 numBytes:{numBytes}"); } } if (success) { NetEventSource.Fail(asyncResult, $"Unexpectedly succeeded. errorCode:{errorCode} numBytes:{numBytes}"); } } catch (ObjectDisposedException) { // CleanedUp check above does not always work since this code is subject to race conditions socketError = SocketError.OperationAborted; } } } asyncResult.ErrorCode = (int)socketError; returnObject = asyncResult.PostCompletion((int)numBytes); asyncResult.ReleaseUnmanagedStructures(); asyncResult.InvokeCallback(returnObject); #if DEBUG } #endif }
public IAsyncResult BeginWrite(byte[] buffer, int offset, int size, AsyncCallback callback, Object state) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif bool canWrite = CanWrite; // Prevent race with Dispose. if (_cleanedUp) { throw new ObjectDisposedException(this.GetType().FullName); } if (!canWrite) { throw new InvalidOperationException(SR.net_readonlystream); } // Validate input parameters. if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException(nameof(offset)); } if (size < 0 || size > buffer.Length - offset) { throw new ArgumentOutOfRangeException(nameof(size)); } Socket chkStreamSocket = _streamSocket; if (chkStreamSocket == null) { throw new IOException(SR.Format(SR.net_io_writefailure, SR.net_io_connectionclosed)); } try { // Call BeginSend on the Socket. IAsyncResult asyncResult = chkStreamSocket.BeginSend( buffer, offset, size, SocketFlags.None, callback, state); return(asyncResult); } catch (Exception exception) { if (exception is OutOfMemoryException) { throw; } // Some sort of error occurred on the socket call, // set the SocketException as InnerException and throw. throw new IOException(SR.Format(SR.net_io_writefailure, exception.Message), exception); } #if DEBUG } #endif }