internal void SetStatus(NetConnectionStatus status, NetConnectionResult reason)
        {
            // user or library thread

            m_status = status;

            if (m_status == NetConnectionStatus.Connected)
            {
                m_timeoutDeadline = NetTime.Now + m_peerConfiguration.m_connectionTimeout;
                m_peer.LogVerbose("Timeout deadline initialized to  " + m_timeoutDeadline);
            }

            if (m_peerConfiguration.IsMessageTypeEnabled(NetIncomingMessageType.StatusChanged))
            {
                if (m_outputtedStatus != status)
                {
                    NetIncomingMessage info = m_peer.CreateIncomingMessage(NetIncomingMessageType.StatusChanged, 1);
                    info.m_senderConnection = this;
                    info.m_senderEndPoint   = m_remoteEndPoint;
                    info.Write((byte)m_status);
                    info.Write((byte)reason);
                    m_peer.ReleaseMessage(info);
                    m_outputtedStatus = status;
                }
            }
            else
            {
                // app dont want those messages, update visible status immediately
                m_outputtedStatus = m_status;
                m_visibleStatus   = m_status;
            }
        }
        /// <summary>
        /// Denies this connection; disconnecting it
        /// </summary>
        /// <param name="reason">The stated reason for the disconnect, readable as a string in the StatusChanged message on the remote host</param>
        public void Deny(NetConnectionResult reason)
        {
            // send disconnect; remove from handshakes
            SendDisconnect(reason, false);

            // remove from handshakes
            lock (m_peer.m_handshakes)
                m_peer.m_handshakes.Remove(m_remoteEndPoint);
        }
        internal void SendDisconnect(NetConnectionResult reason, bool onLibraryThread)
        {
            if (onLibraryThread)
            {
                m_peer.VerifyNetworkThread();
            }

            NetOutgoingMessage om = m_peer.CreateMessage();

            om.Write((byte)reason);
            om.m_messageType = NetMessageType.Disconnect;
            Interlocked.Increment(ref om.m_recyclingCount);
            if (onLibraryThread)
            {
                m_peer.SendLibrary(om, m_remoteEndPoint);
            }
            else
            {
                m_peer.m_unsentUnconnectedMessages.Enqueue(new NetTuple <NetEndPoint, NetOutgoingMessage>(m_remoteEndPoint, om));
            }
        }
        internal void ExecuteDisconnect(NetConnectionResult reason, bool sendByeMessage)
        {
            m_peer.VerifyNetworkThread();

            // clear send queues
            for (int i = 0; i < m_sendChannels.Length; i++)
            {
                NetSenderChannelBase channel = m_sendChannels[i];
                if (channel != null)
                {
                    channel.Reset();
                }
            }

            if (sendByeMessage)
            {
                SendDisconnect(reason, true);
            }

            if (m_status == NetConnectionStatus.ReceivedInitiation)
            {
                // nothing much has happened yet; no need to send disconnected status message
                m_status = NetConnectionStatus.Disconnected;
            }
            else
            {
                SetStatus(NetConnectionStatus.Disconnected, reason);
            }

            // in case we're still in handshake
            lock (m_peer.m_handshakes)
                m_peer.m_handshakes.Remove(m_remoteEndPoint);

            m_disconnectRequested = false;
            m_connectRequested    = false;
            m_handshakeAttempts   = 0;
        }