Enter() public static méthode

public static Enter ( object thisOrContextObject, object arg1 = null, object arg2 = null, object arg3 = null ) : void
thisOrContextObject object
arg1 object
arg2 object
arg3 object
Résultat void
Exemple #1
0
        public static IPHostEntry EndResolve(IAsyncResult asyncResult)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, asyncResult);
            }
            IPHostEntry ipHostEntry;

            try
            {
                ipHostEntry = TaskToApm.End <IPHostEntry>(asyncResult);
            }
            catch (SocketException ex)
            {
                IPAddress?address = asyncResult switch
                {
                    Task t => t.AsyncState as IPAddress,
                         TaskToApm.TaskAsyncResult twar => twar._task.AsyncState as IPAddress,
                         _ => null
                };

                if (address is null)
                {
                    throw; // BeginResolve was called with a HostName, not an IPAddress
                }
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(null, ex);
                }
                ipHostEntry = CreateHostEntryForAddress(address);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null, ipHostEntry);
            }
            return(ipHostEntry);
        }
Exemple #2
0
        } // EndGetHostByName()

        public static IPHostEntry GetHostEntry(string hostNameOrAddress)
        {
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Enter(NetEventSource.ComponentType.Socket, "DNS", "GetHostEntry", hostNameOrAddress);
            }

            NameResolutionPal.EnsureSocketsAreInitialized();

            if (hostNameOrAddress == null)
            {
                throw new ArgumentNullException(nameof(hostNameOrAddress));
            }

            // See if it's an IP Address.
            IPAddress   address;
            IPHostEntry ipHostEntry;

            if (IPAddress.TryParse(hostNameOrAddress, out address))
            {
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                {
                    throw new ArgumentException(SR.Format(SR.net_invalid_ip_addr, nameof(hostNameOrAddress)));
                }

                ipHostEntry = InternalGetHostByAddress(address, true);
            }
            else
            {
                ipHostEntry = InternalGetHostByName(hostNameOrAddress, true);
            }

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Exit(NetEventSource.ComponentType.Socket, "DNS", "GetHostEntry", ipHostEntry);
            }
            return(ipHostEntry);
        }
Exemple #3
0
        public void Start()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }
            lock (_internalLock)
            {
                try
                {
                    CheckDisposed();
                    if (_state == State.Started)
                    {
                        return;
                    }

                    HttpEndPointManager.AddListener(this);

                    _state = State.Started;
                }
                catch (Exception exception)
                {
                    _state = State.Closed;
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Error(this, $"Start {exception}");
                    }
                    throw;
                }
                finally
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Exit(this);
                    }
                }
            }
        }
Exemple #4
0
        } // GetHostEntry

        public static IPAddress[] GetHostAddresses(string hostNameOrAddress)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, hostNameOrAddress);
            }
            NameResolutionPal.EnsureSocketsAreInitialized();

            if (hostNameOrAddress == null)
            {
                throw new ArgumentNullException(nameof(hostNameOrAddress));
            }

            // See if it's an IP Address.
            IPAddress address;

            IPAddress[] addresses;
            if (IPAddress.TryParse(hostNameOrAddress, out address))
            {
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                {
                    throw new ArgumentException(SR.Format(SR.net_invalid_ip_addr, nameof(hostNameOrAddress)));
                }
                addresses = new IPAddress[] { address };
            }
            else
            {
                // InternalGetHostByName works with IP addresses (and avoids a reverse-lookup), but we need
                // explicit handling in order to do the ArgumentException and guarantee the behavior.
                addresses = InternalGetHostByName(hostNameOrAddress).AddressList;
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null, addresses);
            }
            return(addresses);
        }
        private void Initialize(bool isServer, string package, NetworkCredential credential, string?spn, ContextFlagsPal requestedContextFlags, ChannelBinding?channelBinding)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this, package, spn, requestedContextFlags);
            }

            _tokenSize             = NegotiateStreamPal.QueryMaxTokenSize(package);
            _isServer              = isServer;
            _spn                   = spn;
            _securityContext       = null;
            _requestedContextFlags = requestedContextFlags;
            _package               = package;
            _channelBinding        = channelBinding;

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, $"Peer SPN-> '{_spn}'");
            }

            //
            // Check if we're using DefaultCredentials.
            //

            Debug.Assert(CredentialCache.DefaultCredentials == CredentialCache.DefaultNetworkCredentials);
            if (credential == CredentialCache.DefaultCredentials)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, "using DefaultCredentials");
                }
                _credentialsHandle = NegotiateStreamPal.AcquireDefaultCredential(package, _isServer);
            }
            else
            {
                _credentialsHandle = NegotiateStreamPal.AcquireCredentialsHandle(package, _isServer, credential);
            }
        }
        private static unsafe uint Verify(SafeX509ChainHandle chainContext, ref Interop.Crypt32.CERT_CHAIN_POLICY_PARA cpp)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(chainContext, cpp.dwFlags);
            }

            Interop.Crypt32.CERT_CHAIN_POLICY_STATUS status = default;
            status.cbSize = (uint)sizeof(Interop.Crypt32.CERT_CHAIN_POLICY_STATUS);

            bool errorCode =
                Interop.Crypt32.CertVerifyCertificateChainPolicy(
                    (IntPtr)Interop.Crypt32.CertChainPolicy.CERT_CHAIN_POLICY_SSL,
                    chainContext,
                    ref cpp,
                    ref status);

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(chainContext, $"CertVerifyCertificateChainPolicy returned: {errorCode}. Status: {status.dwError}");
            }
            return(status.dwError);
        }
Exemple #7
0
 public X509Certificate2 GetClientCertificate()
 {
     if (NetEventSource.IsEnabled)
     {
         NetEventSource.Enter(this);
     }
     try
     {
         ProcessClientCertificate();
         if (NetEventSource.IsEnabled)
         {
             NetEventSource.Info(this, $"_clientCertificate:{_clientCertificate}");
         }
     }
     finally
     {
         if (NetEventSource.IsEnabled)
         {
             NetEventSource.Exit(this);
         }
     }
     return(_clientCertificate);
 }
Exemple #8
0
        public HttpListener()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }

            _state               = State.Stopped;
            _internalLock        = new object();
            _defaultServiceNames = new ServiceNameStore();

            _timeoutManager = new HttpListenerTimeoutManager(this);
            _prefixes       = new HttpListenerPrefixCollection(this);

            // default: no CBT checks on any platform (appcompat reasons); applies also to PolicyEnforcement
            // config element
            _extendedProtectionPolicy = new ExtendedProtectionPolicy(PolicyEnforcement.Never);

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(this);
            }
        }
 protected override void Dispose(bool disposing)
 {
     if (NetEventSource.IsEnabled)
     {
         NetEventSource.Enter(this);
     }
     try
     {
         if (NetEventSource.IsEnabled)
         {
             NetEventSource.Info(this, "_closed:" + _closed);
         }
         _closed = true;
     }
     finally
     {
         base.Dispose(disposing);
     }
     if (NetEventSource.IsEnabled)
     {
         NetEventSource.Exit(this);
     }
 }
Exemple #10
0
        public void Stop()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }
            try
            {
                lock (_internalLock)
                {
                    CheckDisposed();
                    if (_state == State.Stopped)
                    {
                        return;
                    }

                    Close(false);

                    _state = State.Stopped;
                }
            }
            catch (Exception exception)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(this, $"Stop {exception}");
                }
                throw;
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this);
                }
            }
        }
        public void Abort()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }
            try
            {
                if (_responseState >= ResponseState.Closed)
                {
                    return;
                }

                _responseState = ResponseState.Closed;
                HttpListenerContext.Abort();
            }
            finally
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this);
                }
            }
        }
Exemple #12
0
        private void Dispose()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }

            lock (_internalLock)
            {
                try
                {
                    if (_state == State.Closed)
                    {
                        return;
                    }

                    Close(true);
                }
                catch (Exception exception)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Error(this, $"Dispose {exception}");
                    }
                    throw;
                }
                finally
                {
                    _state = State.Closed;
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Exit(this);
                    }
                }
            }
        }
Exemple #13
0
        private static IPHostEntry InternalGetHostByName(string hostName)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, hostName);
            }
            IPHostEntry ipHostEntry = null;

            ValidateHostName(hostName);

            int         nativeErrorCode;
            SocketError errorCode = NameResolutionPal.TryGetAddrInfo(hostName, out ipHostEntry, out nativeErrorCode);

            if (errorCode != SocketError.Success)
            {
                throw SocketExceptionFactory.CreateSocketException(errorCode, nativeErrorCode);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null, ipHostEntry);
            }
            return(ipHostEntry);
        } // GetHostByName
Exemple #14
0
        public static IPHostEntry GetHostEntry(string hostNameOrAddress)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, hostNameOrAddress);
            }
            NameResolutionPal.EnsureSocketsAreInitialized();

            if (hostNameOrAddress is null)
            {
                throw new ArgumentNullException(nameof(hostNameOrAddress));
            }

            // See if it's an IP Address.
            IPHostEntry ipHostEntry;

            if (IPAddress.TryParse(hostNameOrAddress, out IPAddress address))
            {
                if (address.Equals(IPAddress.Any) || address.Equals(IPAddress.IPv6Any))
                {
                    throw new ArgumentException(SR.Format(SR.net_invalid_ip_addr, nameof(hostNameOrAddress)));
                }

                ipHostEntry = GetHostEntryCore(address);
            }
            else
            {
                ipHostEntry = GetHostEntryCore(hostNameOrAddress);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null, ipHostEntry);
            }
            return(ipHostEntry);
        }
        public override IAsyncResult BeginRead(byte[] buffer, int offset, int size, AsyncCallback callback, object state)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(this, "buffer.Length:" + buffer.Length + " size:" + size + " offset:" + offset);
            }
            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));
            }
            if (size == 0 || _closed)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this);
                }
                HttpRequestStreamAsyncResult result = new HttpRequestStreamAsyncResult(this, state, callback);
                result.InvokeCallback((uint)0);
                return(result);
            }

            HttpRequestStreamAsyncResult asyncResult = null;

            uint dataRead = 0;

            if (_dataChunkIndex != -1)
            {
                dataRead = Interop.HttpApi.GetChunks(_httpContext.Request.RequestBuffer, _httpContext.Request.OriginalBlobAddress, ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
                if (_dataChunkIndex != -1 && dataRead == size)
                {
                    asyncResult = new HttpRequestStreamAsyncResult(_httpContext.RequestQueueBoundHandle, this, state, callback, buffer, offset, (uint)size, 0);
                    asyncResult.InvokeCallback(dataRead);
                }
            }

            if (_dataChunkIndex == -1 && dataRead < size)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, "size:" + size + " offset:" + offset);
                }
                uint statusCode = 0;
                offset += (int)dataRead;
                size   -= (int)dataRead;

                //the http.sys team recommends that we limit the size to 128kb
                if (size > MaxReadSize)
                {
                    size = MaxReadSize;
                }

                asyncResult = new HttpRequestStreamAsyncResult(_httpContext.RequestQueueBoundHandle, this, state, callback, buffer, offset, (uint)size, dataRead);
                uint bytesReturned;

                try
                {
                    fixed(byte *pBuffer = buffer)
                    {
                        // issue unmanaged blocking call
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveRequestEntityBody");
                        }

                        uint flags = 0;

                        if (!_inOpaqueMode)
                        {
                            flags = (uint)Interop.HttpApi.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY;
                        }

                        statusCode =
                            Interop.HttpApi.HttpReceiveRequestEntityBody(
                                _httpContext.RequestQueueHandle,
                                _httpContext.RequestId,
                                flags,
                                asyncResult._pPinnedBuffer,
                                (uint)size,
                                out bytesReturned,
                                asyncResult._pOverlapped);

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveRequestEntityBody returned:" + statusCode + " dataRead:" + dataRead);
                        }
                    }
                }
                catch (Exception e)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Error(this, e.ToString());
                    }
                    asyncResult.InternalCleanup();
                    throw;
                }

                if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_IO_PENDING)
                {
                    asyncResult.InternalCleanup();
                    if (statusCode == Interop.HttpApi.ERROR_HANDLE_EOF)
                    {
                        asyncResult = new HttpRequestStreamAsyncResult(this, state, callback, dataRead);
                        asyncResult.InvokeCallback((uint)0);
                    }
                    else
                    {
                        Exception exception = new HttpListenerException((int)statusCode);
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Error(this, exception.ToString());
                        }
                        asyncResult.InternalCleanup();
                        throw exception;
                    }
                }
                else if (statusCode == Interop.HttpApi.ERROR_SUCCESS &&
                         HttpListener.SkipIOCPCallbackOnSuccess)
                {
                    // IO operation completed synchronously - callback won't be called to signal completion.
                    asyncResult.IOCompleted(statusCode, bytesReturned);
                }
            }
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(this);
            }
            return(asyncResult);
        }
Exemple #16
0
        public override void Write(byte[] buffer, int offset, int size)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
                NetEventSource.Info(this, "buffer.Length:" + buffer.Length + " size:" + size + " offset:" + offset);
            }
            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));
            }
            Interop.HttpApi.HTTP_FLAGS flags = ComputeLeftToWrite();
            if (_closed || (size == 0 && _leftToWrite != 0))
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this);
                }
                return;
            }
            if (_leftToWrite >= 0 && size > _leftToWrite)
            {
                throw new ProtocolViolationException(SR.net_entitytoobig);
            }

            uint statusCode;
            uint dataToWrite = (uint)size;
            SafeLocalAllocHandle bufferAsIntPtr = null;
            IntPtr pBufferAsIntPtr = IntPtr.Zero;
            bool   sentHeaders     = _httpContext.Response.SentHeaders;

            try
            {
                if (size == 0)
                {
                    statusCode = _httpContext.Response.SendHeaders(null, null, flags, false);
                }
                else
                {
                    fixed(byte *pDataBuffer = buffer)
                    {
                        byte *pBuffer = pDataBuffer;

                        if (_httpContext.Response.BoundaryType == BoundaryType.Chunked)
                        {
                            string chunkHeader = size.ToString("x", CultureInfo.InvariantCulture);
                            dataToWrite     = dataToWrite + (uint)(chunkHeader.Length + 4);
                            bufferAsIntPtr  = SafeLocalAllocHandle.LocalAlloc((int)dataToWrite);
                            pBufferAsIntPtr = bufferAsIntPtr.DangerousGetHandle();
                            for (int i = 0; i < chunkHeader.Length; i++)
                            {
                                Marshal.WriteByte(pBufferAsIntPtr, i, (byte)chunkHeader[i]);
                            }
                            Marshal.WriteInt16(pBufferAsIntPtr, chunkHeader.Length, 0x0A0D);
                            Marshal.Copy(buffer, offset, pBufferAsIntPtr + chunkHeader.Length + 2, size);
                            Marshal.WriteInt16(pBufferAsIntPtr, (int)(dataToWrite - 2), 0x0A0D);
                            pBuffer = (byte *)pBufferAsIntPtr;
                            offset  = 0;
                        }
                        Interop.HttpApi.HTTP_DATA_CHUNK dataChunk = new Interop.HttpApi.HTTP_DATA_CHUNK();
                        dataChunk.DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                        dataChunk.pBuffer       = (byte *)(pBuffer + offset);
                        dataChunk.BufferLength  = dataToWrite;

                        flags |= _leftToWrite == size ? Interop.HttpApi.HTTP_FLAGS.NONE : Interop.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_MORE_DATA;
                        if (!sentHeaders)
                        {
                            statusCode = _httpContext.Response.SendHeaders(&dataChunk, null, flags, false);
                        }
                        else
                        {
                            if (NetEventSource.IsEnabled)
                            {
                                NetEventSource.Info(this, "Calling Interop.HttpApi.HttpSendResponseEntityBody");
                            }

                            statusCode =
                                Interop.HttpApi.HttpSendResponseEntityBody(
                                    _httpContext.RequestQueueHandle,
                                    _httpContext.RequestId,
                                    (uint)flags,
                                    1,
                                    &dataChunk,
                                    null,
                                    SafeLocalAllocHandle.Zero,
                                    0,
                                    null,
                                    null);

                            if (NetEventSource.IsEnabled)
                            {
                                NetEventSource.Info(this, "Call to Interop.HttpApi.HttpSendResponseEntityBody returned:" + statusCode);
                            }
                            if (_httpContext.Listener.IgnoreWriteExceptions)
                            {
                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(this, "Write() suppressing error");
                                }
                                statusCode = Interop.HttpApi.ERROR_SUCCESS;
                            }
                        }
                    }
                }
            }
            finally
            {
                // free unmanaged buffer
                bufferAsIntPtr?.Close();
            }

            if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_HANDLE_EOF)
            {
                Exception exception = new HttpListenerException((int)statusCode);
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Error(this, exception.ToString());
                }
                _closed = true;
                _httpContext.Abort();
                throw exception;
            }
            UpdateAfterWrite(dataToWrite);
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.DumpBuffer(this, buffer, offset, (int)dataToWrite);
            }
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(this);
            }
        }
        // Accepts an incoming binary security blob and returns an outgoing binary security blob.
        internal byte[] GetOutgoingBlob(byte[] incomingBlob, bool throwOnError, out SecurityStatusPal statusCode)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this, incomingBlob);
            }

            SecurityBuffer[] inSecurityBufferArray = null;
            if (incomingBlob != null && _channelBinding != null)
            {
                inSecurityBufferArray = new SecurityBuffer[2]
                {
                    new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN),
                    new SecurityBuffer(_channelBinding)
                };
            }
            else if (incomingBlob != null)
            {
                inSecurityBufferArray = new SecurityBuffer[1] {
                    new SecurityBuffer(incomingBlob, SecurityBufferType.SECBUFFER_TOKEN)
                };
            }
            else if (_channelBinding != null)
            {
                inSecurityBufferArray = new SecurityBuffer[1] {
                    new SecurityBuffer(_channelBinding)
                };
            }

            var outSecurityBuffer = new SecurityBuffer(_tokenSize, SecurityBufferType.SECBUFFER_TOKEN);

            bool firstTime = _securityContext == null;

            try
            {
                if (!_isServer)
                {
                    // client session
                    statusCode = NegotiateStreamPal.InitializeSecurityContext(
                        _credentialsHandle,
                        ref _securityContext,
                        _spn,
                        _requestedContextFlags,
                        inSecurityBufferArray,
                        outSecurityBuffer,
                        ref _contextFlags);

                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, $"SSPIWrapper.InitializeSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})");
                    }

                    if (statusCode.ErrorCode == SecurityStatusPalErrorCode.CompleteNeeded)
                    {
                        var inSecurityBuffers = new SecurityBuffer[1];
                        inSecurityBuffers[0] = outSecurityBuffer;

                        statusCode = NegotiateStreamPal.CompleteAuthToken(ref _securityContext, inSecurityBuffers);

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Info(this, $"SSPIWrapper.CompleteAuthToken() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})");
                        }

                        outSecurityBuffer.token = null;
                    }
                }
                else
                {
                    // Server session.
                    statusCode = NegotiateStreamPal.AcceptSecurityContext(
                        _credentialsHandle,
                        ref _securityContext,
                        _requestedContextFlags,
                        inSecurityBufferArray,
                        outSecurityBuffer,
                        ref _contextFlags);

                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, $"SSPIWrapper.AcceptSecurityContext() returns statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})");
                    }
                }
            }
            finally
            {
                //
                // Assuming the ISC or ASC has referenced the credential on the first successful call,
                // we want to decrement the effective ref count by "disposing" it.
                // The real dispose will happen when the security context is closed.
                // Note if the first call was not successful the handle is physically destroyed here.
                //
                if (firstTime && _credentialsHandle != null)
                {
                    _credentialsHandle.Dispose();
                }
            }


            if (((int)statusCode.ErrorCode >= (int)SecurityStatusPalErrorCode.OutOfMemory))
            {
                CloseContext();
                _isCompleted = true;
                if (throwOnError)
                {
                    Exception exception = NegotiateStreamPal.CreateExceptionFromError(statusCode);
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Exit(this, exception);
                    }
                    throw exception;
                }

                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this, $"null statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode})");
                }
                return(null);
            }
            else if (firstTime && _credentialsHandle != null)
            {
                // Cache until it is pushed out by newly incoming handles.
                SSPIHandleCache.CacheCredential(_credentialsHandle);
            }

            // The return value will tell us correctly if the handshake is over or not
            if (statusCode.ErrorCode == SecurityStatusPalErrorCode.OK)
            {
                // Success.
                _isCompleted = true;
            }
            else if (NetEventSource.IsEnabled)
            {
                // We need to continue.
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, $"need continue statusCode:0x{((int)statusCode.ErrorCode):x8} ({statusCode}) _securityContext:{_securityContext}");
                }
            }

            if (NetEventSource.IsEnabled)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this, $"IsCompleted: {IsCompleted}");
                }
            }

            return(outSecurityBuffer.token);
        }
        public override int Read([In, Out] byte[] buffer, int offset, int size)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
                NetEventSource.Info(this, "size:" + size + " offset:" + offset);
            }
            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));
            }
            if (size == 0 || _closed)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Exit(this, "dataRead:0");
                }
                return(0);
            }

            uint dataRead = 0;

            if (_dataChunkIndex != -1)
            {
                dataRead = Interop.HttpApi.GetChunks(_httpContext.Request.RequestBuffer, _httpContext.Request.OriginalBlobAddress, ref _dataChunkIndex, ref _dataChunkOffset, buffer, offset, size);
            }

            if (_dataChunkIndex == -1 && dataRead < size)
            {
                if (NetEventSource.IsEnabled)
                {
                    NetEventSource.Info(this, "size:" + size + " offset:" + offset);
                }
                uint statusCode    = 0;
                uint extraDataRead = 0;
                offset += (int)dataRead;
                size   -= (int)dataRead;

                //the http.sys team recommends that we limit the size to 128kb
                if (size > MaxReadSize)
                {
                    size = MaxReadSize;
                }

                fixed(byte *pBuffer = buffer)
                {
                    // issue unmanaged blocking call
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, "Calling Interop.HttpApi.HttpReceiveRequestEntityBody");
                    }

                    uint flags = 0;

                    if (!_inOpaqueMode)
                    {
                        flags = (uint)Interop.HttpApi.HTTP_FLAGS.HTTP_RECEIVE_REQUEST_FLAG_COPY_BODY;
                    }

                    statusCode =
                        Interop.HttpApi.HttpReceiveRequestEntityBody(
                            _httpContext.RequestQueueHandle,
                            _httpContext.RequestId,
                            flags,
                            (void *)(pBuffer + offset),
                            (uint)size,
                            out extraDataRead,
                            null);

                    dataRead += extraDataRead;
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, "Call to Interop.HttpApi.HttpReceiveRequestEntityBody returned:" + statusCode + " dataRead:" + dataRead);
                    }
                }

                if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_HANDLE_EOF)
                {
                    Exception exception = new HttpListenerException((int)statusCode);
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Error(this, exception.ToString());
                    }
                    throw exception;
                }
                UpdateAfterRead(statusCode, dataRead);
            }
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.DumpBuffer(this, buffer, offset, (int)dataRead);
                NetEventSource.Info(this, "returning dataRead:" + dataRead);
                NetEventSource.Exit(this, "dataRead:" + dataRead);
            }
            return((int)dataRead);
        }
Exemple #19
0
        public static object QueryContextAttributes(SSPIInterface secModule, SafeDeleteContext securityContext, Interop.SspiCli.ContextAttribute contextAttribute, out int errorCode)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, contextAttribute);
            }

            int  nativeBlockSize = IntPtr.Size;
            Type handleType      = null;

            switch (contextAttribute)
            {
            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                nativeBlockSize = SecPkgContext_Sizes.SizeOf;
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                nativeBlockSize = SecPkgContext_StreamSizes.SizeOf;
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                handleType = typeof(SafeFreeContextBuffer);
                unsafe
                {
                    nativeBlockSize = sizeof(SecPkgContext_NegotiationInfoW);
                }
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                handleType = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                handleType = typeof(SafeFreeCertContext);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                handleType = typeof(SafeFreeCertContext);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                nativeBlockSize = Marshal.SizeOf <Interop.SspiCli.SecPkgContext_IssuerListInfoEx>();
                handleType      = typeof(SafeFreeContextBuffer);
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                nativeBlockSize = Marshal.SizeOf <SecPkgContext_ConnectionInfo>();
                break;

            case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL:
                nativeBlockSize = Marshal.SizeOf <Interop.SecPkgContext_ApplicationProtocol>();
                break;

            default:
                throw new ArgumentException(System.StringsHelper.Format(Strings.net_invalid_enum, nameof(contextAttribute)), nameof(contextAttribute));
            }

            SafeHandle sspiHandle = null;
            object     attribute  = null;

            try
            {
                var nativeBuffer = new byte[nativeBlockSize];
                errorCode = secModule.QueryContextAttributes(securityContext, contextAttribute, nativeBuffer, handleType, out sspiHandle);
                if (errorCode != 0)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Exit(null, $"ERROR = {ErrorDescription(errorCode)}");
                    }
                    return(null);
                }

                switch (contextAttribute)
                {
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_SIZES:
                    attribute = new SecPkgContext_Sizes(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_STREAM_SIZES:
                    attribute = new SecPkgContext_StreamSizes(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NAMES:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_PACKAGE_INFO:
                    attribute = new SecurityPackageInfoClass(sspiHandle, 0);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_NEGOTIATION_INFO:
                    unsafe
                    {
                        fixed(void *ptr = &nativeBuffer[0])
                        {
                            attribute = new NegotiationInfoClass(sspiHandle, (int)((SecPkgContext_NegotiationInfoW *)ptr)->NegotiationState);
                        }
                    }
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CLIENT_SPECIFIED_TARGET:
                    attribute = Marshal.PtrToStringUni(sspiHandle.DangerousGetHandle());
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_LOCAL_CERT_CONTEXT:
                // Fall-through to RemoteCertificate is intentional.
                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_REMOTE_CERT_CONTEXT:
                    attribute  = sspiHandle;
                    sspiHandle = null;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_ISSUER_LIST_EX:
                    attribute  = new Interop.SspiCli.SecPkgContext_IssuerListInfoEx(sspiHandle, nativeBuffer);
                    sspiHandle = null;
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_CONNECTION_INFO:
                    attribute = new SecPkgContext_ConnectionInfo(nativeBuffer);
                    break;

                case Interop.SspiCli.ContextAttribute.SECPKG_ATTR_APPLICATION_PROTOCOL:
                    unsafe
                    {
                        fixed(void *ptr = nativeBuffer)
                        {
                            attribute = Marshal.PtrToStructure <Interop.SecPkgContext_ApplicationProtocol>(new IntPtr(ptr));
                        }
                    }
                    break;

                default:
                    // Will return null.
                    break;
                }
            }
            finally
            {
                if (sspiHandle != null)
                {
                    sspiHandle.Dispose();
                }
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null, attribute);
            }
            return(attribute);
        }
Exemple #20
0
        internal static IPHostEntry InternalGetHostByName(string hostName, bool includeIPv6)
        {
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Enter(NetEventSource.ComponentType.Socket, "DNS", "GetHostByName", hostName);
            }
            IPHostEntry ipHostEntry = null;

            if (GlobalLog.IsEnabled)
            {
                GlobalLog.Print("Dns.GetHostByName: " + hostName);
            }

            NameResolutionPal.EnsureSocketsAreInitialized();

            if (hostName.Length > MaxHostName || // If 255 chars, the last one must be a dot.
                hostName.Length == MaxHostName && hostName[MaxHostName - 1] != '.')
            {
                throw new ArgumentOutOfRangeException(nameof(hostName), SR.Format(SR.net_toolong,
                                                                                  "hostName", MaxHostName.ToString(NumberFormatInfo.CurrentInfo)));
            }

            //
            // IPv6 Changes: IPv6 requires the use of getaddrinfo() rather
            //               than the traditional IPv4 gethostbyaddr() / gethostbyname().
            //               getaddrinfo() is also protocol independent in that it will also
            //               resolve IPv4 names / addresses. As a result, it is the preferred
            //               resolution mechanism on platforms that support it (Windows 5.1+).
            //               If getaddrinfo() is unsupported, IPv6 resolution does not work.
            //
            // Consider    : If IPv6 is disabled, we could detect IPv6 addresses
            //               and throw an unsupported platform exception.
            //
            // Note        : Whilst getaddrinfo is available on WinXP+, we only
            //               use it if IPv6 is enabled (platform is part of that
            //               decision). This is done to minimize the number of
            //               possible tests that are needed.
            //
            if (includeIPv6 || SocketProtocolSupportPal.OSSupportsIPv6)
            {
                //
                // IPv6 enabled: use getaddrinfo() to obtain DNS information.
                //
                int         nativeErrorCode;
                SocketError errorCode = NameResolutionPal.TryGetAddrInfo(hostName, out ipHostEntry, out nativeErrorCode);
                if (errorCode != SocketError.Success)
                {
                    throw new InternalSocketException(errorCode, nativeErrorCode);
                }
            }
            else
            {
                ipHostEntry = NameResolutionPal.GetHostByName(hostName);
            }

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Exit(NetEventSource.ComponentType.Socket, "DNS", "GetHostByName", ipHostEntry);
            }
            return(ipHostEntry);
        } // GetHostByName
        private static byte[] GetChunkHeader(int size, out int offset)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null, $"size:{size}");
            }

            uint Mask = 0xf0000000;

            byte[] Header = new byte[10];
            int    i;

            offset = -1;

            //
            // Loop through the size, looking at each nibble. If it's not 0
            // convert it to hex. Save the index of the first non-zero
            // byte.
            //
            for (i = 0; i < 8; i++, size <<= 4)
            {
                //
                // offset == -1 means that we haven't found a non-zero nibble
                // yet. If we haven't found one, and the current one is zero,
                // don't do anything.
                //
                if (offset == -1)
                {
                    if ((size & Mask) == 0)
                    {
                        continue;
                    }
                }

                //
                // Either we have a non-zero nibble or we're no longer skipping
                // leading zeros. Convert this nibble to ASCII and save it.
                //
                uint Temp = (uint)size >> 28;

                if (Temp < 10)
                {
                    Header[i] = (byte)(Temp + '0');
                }
                else
                {
                    Header[i] = (byte)((Temp - 10) + 'A');
                }

                //
                // If we haven't found a non-zero nibble yet, we've found one
                // now, so remember that.
                //
                if (offset == -1)
                {
                    offset = i;
                }
            }

            Header[8] = (byte)'\r';
            Header[9] = (byte)'\n';

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(null);
            }
            return(Header);
        }
Exemple #22
0
        // Create a WebRequest.
        //
        // This is the main creation routine. We take a Uri object, look
        // up the Uri in the prefix match table, and invoke the appropriate
        // handler to create the object. We also have a parameter that
        // tells us whether or not to use the whole Uri or just the
        // scheme portion of it.
        //
        // Input:
        //     requestUri - Uri object for request.
        //     useUriBase - True if we're only to look at the scheme portion of the Uri.
        //
        // Returns:
        //     Newly created WebRequest.
        private static WebRequest Create(Uri requestUri, bool useUriBase)
        {
            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Enter(NetEventSource.ComponentType.Requests, "WebRequest", "Create", requestUri.ToString());
            }

            string LookupUri;
            WebRequestPrefixElement Current = null;
            bool Found = false;

            if (!useUriBase)
            {
                LookupUri = requestUri.AbsoluteUri;
            }
            else
            {
                // schemes are registered as <schemeName>":", so add the separator
                // to the string returned from the Uri object
                LookupUri = requestUri.Scheme + ':';
            }

            int LookupLength = LookupUri.Length;

            // Copy the prefix list so that if it is updated it will
            // not affect us on this thread.

            List <WebRequestPrefixElement> prefixList = PrefixList;

            // Look for the longest matching prefix.

            // Walk down the list of prefixes. The prefixes are kept longest
            // first. When we find a prefix that is shorter or the same size
            // as this Uri, we'll do a compare to see if they match. If they
            // do we'll break out of the loop and call the creator.

            for (int i = 0; i < prefixList.Count; i++)
            {
                Current = prefixList[i];

                // See if this prefix is short enough.

                if (LookupLength >= Current.Prefix.Length)
                {
                    // It is. See if these match.
                    if (String.Compare(Current.Prefix,
                                       0,
                                       LookupUri,
                                       0,
                                       Current.Prefix.Length,
                                       StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        // These match. Remember that we found it and break
                        // out.
                        Found = true;
                        break;
                    }
                }
            }

            WebRequest webRequest = null;

            if (Found)
            {
                // We found a match, so just call the creator and return what it does.
                webRequest = Current.Creator.Create(requestUri);
                if (NetEventSource.Log.IsEnabled())
                {
                    NetEventSource.Exit(NetEventSource.ComponentType.Requests, "WebRequest", "Create", webRequest);
                }
                return(webRequest);
            }

            if (NetEventSource.Log.IsEnabled())
            {
                NetEventSource.Exit(NetEventSource.ComponentType.Requests, "WebRequest", "Create", null);
            }

            // Otherwise no match, throw an exception.
            throw new NotSupportedException(SR.net_unknown_prefix);
        }
Exemple #23
0
        private static X509Certificate2?GetRemoteCertificate(SafeDeleteContext?securityContext, X509Certificate2Collection?remoteCertificateStore)
        {
            bool gotReference = false;

            if (securityContext == null)
            {
                return(null);
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(securityContext);
            }

            X509Certificate2?   result        = null;
            SafeFreeCertContext?remoteContext = null;

            try
            {
                int errorCode = QueryContextRemoteCertificate(securityContext, out remoteContext);

                if (remoteContext != null && !remoteContext.IsInvalid)
                {
                    remoteContext.DangerousAddRef(ref gotReference);
                    result = new X509Certificate2(remoteContext.DangerousGetHandle());
                }

                if (remoteCertificateStore != null)
                {
                    using (SafeSharedX509StackHandle chainStack =
                               Interop.OpenSsl.GetPeerCertificateChain(((SafeDeleteSslContext)securityContext).SslContext))
                    {
                        if (!chainStack.IsInvalid)
                        {
                            int count = Interop.Crypto.GetX509StackFieldCount(chainStack);

                            for (int i = 0; i < count; i++)
                            {
                                IntPtr certPtr = Interop.Crypto.GetX509StackField(chainStack, i);

                                if (certPtr != IntPtr.Zero)
                                {
                                    // X509Certificate2(IntPtr) calls X509_dup, so the reference is appropriately tracked.
                                    X509Certificate2 chainCert = new X509Certificate2(certPtr);
                                    remoteCertificateStore.Add(chainCert);
                                }
                            }
                        }
                    }
                }
            }
            catch
            {
                result?.Dispose();
                throw;
            }
            finally
            {
                if (remoteContext != null)
                {
                    if (gotReference)
                    {
                        remoteContext.DangerousRelease();
                    }

                    remoteContext.Dispose();
                }
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Log.RemoteCertificate(result);
                NetEventSource.Exit(securityContext, result);
            }
            return(result);
        }
Exemple #24
0
        /// <summary>
        /// <para>Thread for the timer.  Ignores all exceptions.  If no activity occurs for a while,
        /// the thread will shut down.</para>
        /// </summary>
        private static void ThreadProc()
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(null);
            }
#if DEBUG
            DebugThreadTracking.SetThreadSource(ThreadKinds.Timer);
            using (DebugThreadTracking.SetThreadKind(ThreadKinds.System | ThreadKinds.Async))
            {
#endif
            // Set this thread as a background thread.  On AppDomain/Process shutdown, the thread will just be killed.
            Thread.CurrentThread.IsBackground = true;

            // Keep a permanent lock on s_Queues.  This lets for example Shutdown() know when this thread isn't running.
            lock (s_Queues)
            {
                // If shutdown was recently called, abort here.
                if (Interlocked.CompareExchange(ref s_ThreadState, (int)TimerThreadState.Running, (int)TimerThreadState.Running) !=
                    (int)TimerThreadState.Running)
                {
                    return;
                }

                bool running = true;
                while (running)
                {
                    try
                    {
                        s_ThreadReadyEvent.Reset();

                        while (true)
                        {
                            // Copy all the new queues to the real queues.  Since only this thread modifies the real queues, it doesn't have to lock it.
                            if (s_NewQueues.Count > 0)
                            {
                                lock (s_NewQueues)
                                {
                                    for (LinkedListNode <WeakReference> node = s_NewQueues.First; node != null; node = s_NewQueues.First)
                                    {
                                        s_NewQueues.Remove(node);
                                        s_Queues.AddLast(node);
                                    }
                                }
                            }

                            int  now          = Environment.TickCount;
                            int  nextTick     = 0;
                            bool haveNextTick = false;
                            for (LinkedListNode <WeakReference> node = s_Queues.First; node != null; /* node = node.Next must be done in the body */)
                            {
                                TimerQueue queue = (TimerQueue)node.Value.Target;
                                if (queue == null)
                                {
                                    LinkedListNode <WeakReference> next = node.Next;
                                    s_Queues.Remove(node);
                                    node = next;
                                    continue;
                                }

                                // Fire() will always return values that should be interpreted as later than 'now' (that is, even if 'now' is
                                // returned, it is 0x100000000 milliseconds in the future).  There's also a chance that Fire() will return a value
                                // intended as > 0x100000000 milliseconds from 'now'.  Either case will just cause an extra scan through the timers.
                                int nextTickInstance;
                                if (queue.Fire(out nextTickInstance) && (!haveNextTick || IsTickBetween(now, nextTick, nextTickInstance)))
                                {
                                    nextTick     = nextTickInstance;
                                    haveNextTick = true;
                                }

                                node = node.Next;
                            }

                            // Figure out how long to wait, taking into account how long the loop took.
                            // Add 15 ms to compensate for poor TickCount resolution (want to guarantee a firing).
                            int newNow       = Environment.TickCount;
                            int waitDuration = haveNextTick ?
                                               (int)(IsTickBetween(now, nextTick, newNow) ?
                                                     Math.Min(unchecked ((uint)(nextTick - newNow)), (uint)(Int32.MaxValue - c_TickCountResolution)) + c_TickCountResolution :
                                                     0) :
                                               c_ThreadIdleTimeoutMilliseconds;

                            if (NetEventSource.IsEnabled)
                            {
                                NetEventSource.Info(null, $"Waiting for {waitDuration}ms");
                            }

                            int waitResult = WaitHandle.WaitAny(s_ThreadEvents, waitDuration, false);

                            // 0 is s_ThreadShutdownEvent - die.
                            if (waitResult == 0)
                            {
                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(null, "Awoke, cause: Shutdown");
                                }
                                running = false;
                                break;
                            }

                            if (NetEventSource.IsEnabled)
                            {
                                NetEventSource.Info(null, $"Awoke, cause {(waitResult == WaitHandle.WaitTimeout ? "Timeout" : "Prod")}");
                            }

                            // If we timed out with nothing to do, shut down.
                            if (waitResult == WaitHandle.WaitTimeout && !haveNextTick)
                            {
                                Interlocked.CompareExchange(ref s_ThreadState, (int)TimerThreadState.Idle, (int)TimerThreadState.Running);
                                // There could have been one more prod between the wait and the exchange.  Check, and abort if necessary.
                                if (s_ThreadReadyEvent.WaitOne(0, false))
                                {
                                    if (Interlocked.CompareExchange(ref s_ThreadState, (int)TimerThreadState.Running, (int)TimerThreadState.Idle) ==
                                        (int)TimerThreadState.Idle)
                                    {
                                        continue;
                                    }
                                }

                                running = false;
                                break;
                            }
                        }
                    }
                    catch (Exception exception)
                    {
                        if (ExceptionCheck.IsFatal(exception))
                        {
                            throw;
                        }

                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Error(null, exception);
                        }

                        // The only options are to continue processing and likely enter an error-loop,
                        // shut down timers for this AppDomain, or shut down the AppDomain.  Go with shutting
                        // down the AppDomain in debug, and going into a loop in retail, but try to make the
                        // loop somewhat slow.  Note that in retail, this can only be triggered by OutOfMemory or StackOverflow,
                        // or an exception thrown within TimerThread - the rest are caught in Fire().
#if !DEBUG
                        Thread.Sleep(1000);
#else
                        throw;
#endif
                    }
                }
            }

            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Info(null, "Stop");
            }
#if DEBUG
        }
#endif
        }
Exemple #25
0
        protected override void Dispose(bool disposing)
        {
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Enter(this);
            }

            try
            {
                if (disposing)
                {
                    if (NetEventSource.IsEnabled)
                    {
                        NetEventSource.Info(this, "_closed:" + _closed);
                    }
                    if (_closed)
                    {
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Exit(this);
                        }
                        return;
                    }
                    _closed = true;
                    Interop.HttpApi.HTTP_FLAGS flags = ComputeLeftToWrite();
                    if (_leftToWrite > 0 && !_inOpaqueMode)
                    {
                        throw new InvalidOperationException(SR.net_io_notenoughbyteswritten);
                    }
                    bool sentHeaders = _httpContext.Response.SentHeaders;
                    if (sentHeaders && _leftToWrite == 0)
                    {
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Exit(this);
                        }
                        return;
                    }

                    uint statusCode = 0;
                    if ((_httpContext.Response.BoundaryType == BoundaryType.Chunked || _httpContext.Response.BoundaryType == BoundaryType.None) && (String.Compare(_httpContext.Request.HttpMethod, "HEAD", StringComparison.OrdinalIgnoreCase) != 0))
                    {
                        if (_httpContext.Response.BoundaryType == BoundaryType.None)
                        {
                            flags |= Interop.HttpApi.HTTP_FLAGS.HTTP_SEND_RESPONSE_FLAG_DISCONNECT;
                        }
                        fixed(void *pBuffer = ChunkTerminator)
                        {
                            Interop.HttpApi.HTTP_DATA_CHUNK *pDataChunk = null;
                            if (_httpContext.Response.BoundaryType == BoundaryType.Chunked)
                            {
                                Interop.HttpApi.HTTP_DATA_CHUNK dataChunk = new Interop.HttpApi.HTTP_DATA_CHUNK();
                                dataChunk.DataChunkType = Interop.HttpApi.HTTP_DATA_CHUNK_TYPE.HttpDataChunkFromMemory;
                                dataChunk.pBuffer       = (byte *)pBuffer;
                                dataChunk.BufferLength  = (uint)ChunkTerminator.Length;
                                pDataChunk = &dataChunk;
                            }
                            if (!sentHeaders)
                            {
                                statusCode = _httpContext.Response.SendHeaders(pDataChunk, null, flags, false);
                            }
                            else
                            {
                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(this, "Calling Interop.HttpApi.HttpSendResponseEntityBody");
                                }

                                statusCode =
                                    Interop.HttpApi.HttpSendResponseEntityBody(
                                        _httpContext.RequestQueueHandle,
                                        _httpContext.RequestId,
                                        (uint)flags,
                                        pDataChunk != null ? (ushort)1 : (ushort)0,
                                        pDataChunk,
                                        null,
                                        SafeLocalAllocHandle.Zero,
                                        0,
                                        null,
                                        null);

                                if (NetEventSource.IsEnabled)
                                {
                                    NetEventSource.Info(this, "Call to Interop.HttpApi.HttpSendResponseEntityBody returned:" + statusCode);
                                }
                                if (_httpContext.Listener.IgnoreWriteExceptions)
                                {
                                    if (NetEventSource.IsEnabled)
                                    {
                                        NetEventSource.Info(this, "Suppressing error");
                                    }
                                    statusCode = Interop.HttpApi.ERROR_SUCCESS;
                                }
                            }
                        }
                    }
                    else
                    {
                        if (!sentHeaders)
                        {
                            statusCode = _httpContext.Response.SendHeaders(null, null, flags, false);
                        }
                    }
                    if (statusCode != Interop.HttpApi.ERROR_SUCCESS && statusCode != Interop.HttpApi.ERROR_HANDLE_EOF)
                    {
                        Exception exception = new HttpListenerException((int)statusCode);
                        if (NetEventSource.IsEnabled)
                        {
                            NetEventSource.Error(this, exception.ToString());
                        }
                        _httpContext.Abort();
                        throw exception;
                    }
                    _leftToWrite = 0;
                }
            }
            finally
            {
                base.Dispose(disposing);
            }
            if (NetEventSource.IsEnabled)
            {
                NetEventSource.Exit(this);
            }
        }