// // To avoid recursion when decrypted 0 bytes this method will loop until a decrypted result at least 1 byte. // private int StartReading(byte[] buffer, int offset, int count) { int result = 0; if (GlobalLog.IsEnabled && InternalBufferCount != 0) { GlobalLog.AssertFormat("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:{0}", InternalBufferCount); } do { int copyBytes = _SslState.CheckEnqueueRead(buffer, offset, count, null); if (copyBytes == 0) { //Queued but not completed! return(0); } if (copyBytes != -1) { return(copyBytes); } } // When we read -1 bytes means we have decrypted 0 bytes or rehandshaking, need looping. while ((result = StartFrameHeader(buffer, offset, count)) == -1); return(result); }
private void LogBuffer(int size) { if (!SocketsEventSource.Log.IsEnabled() && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("OverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this)); } if (size > -1) { if (_wsaBuffers != null) { foreach (WSABuffer wsaBuffer in _wsaBuffers) { SocketsEventSource.Dump(SocketsEventSource.MethodType.PostCompletion, wsaBuffer.Pointer, Math.Min(wsaBuffer.Length, size)); if ((size -= wsaBuffer.Length) <= 0) { break; } } } else { SocketsEventSource.Dump(SocketsEventSource.MethodType.PostCompletion, _singleBuffer.Pointer, Math.Min(_singleBuffer.Length, size)); } } }
private void LogBuffer(int size) { if (!SocketsEventSource.Log.IsEnabled() && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("ReceiveMessageOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this)); } SocketsEventSource.Dump(SocketsEventSource.MethodType.PostCompletion, _wsaBuffer->Pointer, Math.Min(_wsaBuffer->Length, size)); }
private int StartFrameBody(int readBytes, byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { if (readBytes == 0) { //EOF if (asyncRequest != null) { asyncRequest.CompleteUser((object)0); } return(0); } if ((readBytes == _ReadHeader.Length) && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("NegoStream::ProcessHeader()|Frame size must be 4 but received {0} bytes.", readBytes); } // Replace readBytes with the body size recovered from the header content. readBytes = _ReadHeader[3]; readBytes = (readBytes << 8) | _ReadHeader[2]; readBytes = (readBytes << 8) | _ReadHeader[1]; readBytes = (readBytes << 8) | _ReadHeader[0]; // // The body carries 4 bytes for trailer size slot plus trailer, hence <=4 frame size is always an error. // Additionally we'd like to restrict the read frame size to 64k. // if (readBytes <= 4 || readBytes > NegoState.MaxReadFrameSize) { throw new IOException(SR.net_frame_read_size); } // // Always pass InternalBuffer for SSPI "in place" decryption. // A user buffer can be shared by many threads in that case decryption/integrity check may fail cause of data corruption. // EnsureInternalBufferSize(readBytes); if (asyncRequest != null) { asyncRequest.SetNextRequest(InternalBuffer, 0, readBytes, s_readCallback); _FrameReader.AsyncReadPacket(asyncRequest); if (!asyncRequest.MustCompleteSynchronously) { return(0); } readBytes = asyncRequest.Result; } else //Sync { readBytes = _FrameReader.ReadPacket(InternalBuffer, 0, readBytes); } return(ProcessFrameBody(readBytes, buffer, offset, count, asyncRequest)); }
private void LogBuffer(int size) { if (!SocketsEventSource.Log.IsEnabled()) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("ReceiveMessageOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this)); } Debug.Fail("ReceiveMessageOverlappedAsyncResult#" + LoggingHash.HashString(this) + "::LogBuffer()|Logging is off!"); } SocketsEventSource.Dump(_wsaBuffer->Pointer, Math.Min(_wsaBuffer->Length, size)); }
// This method is implicitly reliable and called from a CER. protected override bool ReleaseHandle() { bool ret = false; #if DEBUG try { #endif if (GlobalLog.IsEnabled) { GlobalLog.Print("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")"); } SocketError errorCode = InnerReleaseHandle(); return(ret = errorCode == SocketError.Success); #if DEBUG } catch (Exception exception) { if (!ExceptionCheck.IsFatal(exception)) { if (GlobalLog.IsEnabled) { GlobalLog.Assert("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")", exception.Message); } Debug.Fail("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")", exception.Message); } ret = true; // Avoid a second assert. throw; } finally { _closeSocketThread = Environment.CurrentManagedThreadId; _closeSocketTick = Environment.TickCount; if (!ret) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("SafeCloseSocket::ReleaseHandle(handle:{0:x})|ReleaseHandle failed.", handle); } Debug.Fail("SafeCloseSocket::ReleaseHandle(handle:" + handle.ToString("x") + ")|ReleaseHandle failed."); } } #endif }
// // To avoid recursion when decrypted 0 bytes this method will loop until a decrypted result at least 1 byte. // private int StartReading(byte[] buffer, int offset, int count, AsyncProtocolRequest asyncRequest) { int result = 0; if (InternalBufferCount != 0) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:{0}", InternalBufferCount); } Debug.Fail("SslStream::StartReading()|Previous frame was not consumed. InternalBufferCount:" + InternalBufferCount); } do { if (asyncRequest != null) { asyncRequest.SetNextRequest(buffer, offset, count, s_resumeAsyncReadCallback); } int copyBytes = _sslState.CheckEnqueueRead(buffer, offset, count, asyncRequest); if (copyBytes == 0) { // Queued but not completed! return(0); } if (copyBytes != -1) { if (asyncRequest != null) { asyncRequest.CompleteUser((object)copyBytes); } return(copyBytes); } } // When we read -1 bytes means we have decrypted 0 bytes or rehandshaking, need looping. while ((result = StartFrameHeader(buffer, offset, count, asyncRequest)) == -1); return(result); }
private Authorization SetContextAndTryAuthenticate(ISmtpAuthenticationModule module, NetworkCredential credential, ContextAwareResult context) { // We may need to restore user thread token here if (ReferenceEquals(credential, CredentialCache.DefaultNetworkCredentials)) { #if DEBUG if (context != null && !context.IdentityRequested) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("SmtpConnection#{0}::SetContextAndTryAuthenticate|Authentication required when it wasn't expected. (Maybe Credentials was changed on another thread?)", LoggingHash.HashString(this)); } Debug.Fail("SmtpConnection#" + LoggingHash.HashString(this) + "::SetContextAndTryAuthenticate|Authentication required when it wasn't expected. (Maybe Credentials was changed on another thread?)"); } #endif try { ExecutionContext x = context == null ? null : context.ContextCopy; if (x != null) { AuthenticateCallbackContext authenticationContext = new AuthenticateCallbackContext(this, module, credential, _client.TargetName, _channelBindingToken); ExecutionContext.Run(x, s_AuthenticateCallback, authenticationContext); return(authenticationContext._result); } else { return(module.Authenticate(null, credential, this, _client.TargetName, _channelBindingToken)); } } catch { // Prevent the impersonation from leaking to upstack exception filters. throw; } } return(module.Authenticate(null, credential, this, _client.TargetName, _channelBindingToken)); }
private void LogBuffer(long size) { if (!SocketsEventSource.Log.IsEnabled() && GlobalLog.IsEnabled) { GlobalLog.AssertFormat("AcceptOverlappedAsyncResult#{0}::LogBuffer()|Logging is off!", LoggingHash.HashString(this)); } IntPtr pinnedBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(_buffer, 0); if (pinnedBuffer != IntPtr.Zero) { if (size > -1) { SocketsEventSource.Dump(pinnedBuffer, (int)Math.Min(size, (long)_buffer.Length)); } else { SocketsEventSource.Dump(pinnedBuffer, (int)_buffer.Length); } } }
private unsafe static void CompletionPortCallback(uint errorCode, uint numBytes, NativeOverlapped *nativeOverlapped) { #if DEBUG GlobalLog.SetThreadSource(ThreadKinds.CompletionPort); using (GlobalLog.SetThreadKind(ThreadKinds.System)) { #endif BaseOverlappedAsyncResult asyncResult = (BaseOverlappedAsyncResult)ThreadPoolBoundHandle.GetNativeOverlappedState(nativeOverlapped); object returnObject = null; if (asyncResult.InternalPeekCompleted) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("BaseOverlappedAsyncResult#{0}::CompletionPortCallback()|asyncResult.IsCompleted", LoggingHash.HashString(asyncResult)); } Debug.Fail("BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback()|asyncResult.IsCompleted"); } if (GlobalLog.IsEnabled) { GlobalLog.Print( "BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback" + " errorCode:" + errorCode.ToString() + " numBytes:" + numBytes.ToString() + " pOverlapped:" + ((int)nativeOverlapped).ToString()); } // 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) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("BaseOverlappedAsyncResult#{0}::CompletionPortCallback()|socketError:0 numBytes:{1}", LoggingHash.HashString(asyncResult), numBytes); } Debug.Fail("BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback()|socketError:0 numBytes:" + numBytes); } } if (success) { if (GlobalLog.IsEnabled) { GlobalLog.AssertFormat("BaseOverlappedAsyncResult#{0}::CompletionPortCallback()|Unexpectedly succeeded. errorCode:{1} numBytes:{2}", LoggingHash.HashString(asyncResult), errorCode, numBytes); } Debug.Fail("BaseOverlappedAsyncResult#" + LoggingHash.HashString(asyncResult) + "::CompletionPortCallback()|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 }