예제 #1
0
        /// <summary>
        /// Handle receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="header">SMUX header</param>
        public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header)
        {
            lock (this)
            {
                if (_sendHighwater != header.highwater)
                {
                    HandleAck(header.highwater);
                }

                lock (_receivedPacketQueue)
                {
                    if (_asyncReceives == 0)
                    {
                        _receivedPacketQueue.Enqueue(packet);
                        _packetEvent.Set();
                        return;
                    }

                    _asyncReceives--;
                    Debug.Assert(_callbackObject != null);

#if MANAGED_SNI // Causes build issue if uncommented in unmanaged version
                    ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 0);
#endif
                }
            }

            lock (this)
            {
                _receiveHighwater++;
            }

            SendAckIfNecessary();
        }
예제 #2
0
        /// <summary>
        /// Handle receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="header">SMUX header</param>
        public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header)
        {
            lock (this)
            {
                if (_sendHighwater != header.highwater)
                {
                    HandleAck(header.highwater);
                }

                lock (_receivedPacketQueue)
                {
                    if (_asyncReceives == 0)
                    {
                        _receivedPacketQueue.Enqueue(packet);
                        _packetEvent.Set();
                        return;
                    }

                    _asyncReceives--;
                    Debug.Assert(_callbackObject != null);

                    ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 0);
                }
            }

            lock (this)
            {
                _receiveHighwater++;
            }

            SendAckIfNecessary();
        }
예제 #3
0
        /// <summary>
        /// Handle receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="header">SMUX header</param>
        public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header)
        {
            lock (this)
            {
                if (_sendHighwater != header.highwater)
                {
                    HandleAck(header.highwater);
                }

                lock (_receivedPacketQueue)
                {
                    // The error callback takes care of completing all pending receives
                    if (_connectionError == null)
                    {
                        if (_asyncReceives == 0)
                        {
                            _receivedPacketQueue.Enqueue(packet);
                            _packetEvent.Set();
                            return;
                        }

                        _asyncReceives--;
                    }
                }
            }

            _callbackObject.ReadAsyncCallback(packet, null);

            lock (this)
            {
                _receiveHighwater++;
            }

            SendAckIfNecessary();
        }
예제 #4
0
        /// <summary>
        /// Process a receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="sniErrorCode">SNI error code</param>
        public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode)
        {
            SNISMUXHeader currentHeader = null;
            SNIPacket currentPacket = null;
            SNIMarsHandle currentSession = null;

            if (sniErrorCode != TdsEnums.SNI_SUCCESS)
            {
                lock (this)
                {
                    HandleReceiveError();
                    return;
                }
            }

            while (true)
            {
                lock (this)
                {
                    if (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH)
                    {
                        currentHeader = null;
                        currentPacket = null;
                        currentSession = null;

                        while (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH)
                        {
                            int bytesTaken = packet.TakeData(_headerBytes, _currentHeaderByteCount, SNISMUXHeader.HEADER_LENGTH - _currentHeaderByteCount);
                            _currentHeaderByteCount += bytesTaken;

                            if (bytesTaken == 0)
                            {
                                sniErrorCode = ReceiveAsync(ref packet);

                                if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING)
                                {
                                    return;
                                }

                                HandleReceiveError();
                                return;
                            }
                        }

                        _currentHeader = new SNISMUXHeader()
                        {
                            SMID = _headerBytes[0],
                            flags = _headerBytes[1],
                            sessionId = BitConverter.ToUInt16(_headerBytes, 2),
                            length = BitConverter.ToUInt32(_headerBytes, 4) - SNISMUXHeader.HEADER_LENGTH,
                            sequenceNumber = BitConverter.ToUInt32(_headerBytes, 8),
                            highwater = BitConverter.ToUInt32(_headerBytes, 12)
                        };

                        _dataBytesLeft = (int)_currentHeader.length;
                        _currentPacket = new SNIPacket(null);
                        _currentPacket.Allocate((int)_currentHeader.length);
                    }

                    currentHeader = _currentHeader;
                    currentPacket = _currentPacket;

                    if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA)
                    {
                        if (_dataBytesLeft > 0)
                        {
                            int length = packet.TakeData(_currentPacket, _dataBytesLeft);
                            _dataBytesLeft -= length;

                            if (_dataBytesLeft > 0)
                            {
                                sniErrorCode = ReceiveAsync(ref packet);

                                if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING)
                                {
                                    return;
                                }

                                HandleReceiveError();
                                return;
                            }
                        }
                    }

                    _currentHeaderByteCount = 0;

                    if (!_sessions.ContainsKey(_currentHeader.sessionId))
                    {
                        SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, string.Empty);
                        HandleReceiveError();
                        _lowerHandle.Dispose();
                        _lowerHandle = null;
                        return;
                    }

                    if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_FIN)
                    {
                        _sessions.Remove(_currentHeader.sessionId);
                    }
                    else
                    {
                        currentSession = _sessions[_currentHeader.sessionId];
                    }
                }

                if (currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA)
                {
                    currentSession.HandleReceiveComplete(currentPacket, currentHeader);
                }

                if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_ACK)
                {
                    try
                    {
                        currentSession.HandleAck(currentHeader.highwater);
                    }
                    catch (Exception e)
                    {
                        SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, SNICommon.InternalExceptionError, e);
                    }
                }

                lock (this)
                {
                    if (packet.DataLeft == 0)
                    {
                        sniErrorCode = ReceiveAsync(ref packet);

                        if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING)
                        {
                            return;
                        }

                        HandleReceiveError();
                        return;
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Process a receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="sniErrorCode">SNI error code</param>
        public void HandleReceiveComplete(SNIPacket packet, uint sniErrorCode)
        {
            SNISMUXHeader currentHeader  = null;
            SNIPacket     currentPacket  = null;
            SNIMarsHandle currentSession = null;

            if (sniErrorCode != TdsEnums.SNI_SUCCESS)
            {
                lock (this)
                {
                    HandleReceiveError();
                    return;
                }
            }

            while (true)
            {
                lock (this)
                {
                    if (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH)
                    {
                        currentHeader  = null;
                        currentPacket  = null;
                        currentSession = null;

                        while (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH)
                        {
                            int bytesTaken = packet.TakeData(_headerBytes, _currentHeaderByteCount, SNISMUXHeader.HEADER_LENGTH - _currentHeaderByteCount);
                            _currentHeaderByteCount += bytesTaken;

                            if (bytesTaken == 0)
                            {
                                sniErrorCode = ReceiveAsync(ref packet);

                                if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING)
                                {
                                    return;
                                }

                                HandleReceiveError();
                                return;
                            }
                        }

                        _currentHeader = new SNISMUXHeader()
                        {
                            SMID           = _headerBytes[0],
                            flags          = _headerBytes[1],
                            sessionId      = BitConverter.ToUInt16(_headerBytes, 2),
                            length         = BitConverter.ToUInt32(_headerBytes, 4) - SNISMUXHeader.HEADER_LENGTH,
                            sequenceNumber = BitConverter.ToUInt32(_headerBytes, 8),
                            highwater      = BitConverter.ToUInt32(_headerBytes, 12)
                        };

                        _dataBytesLeft = (int)_currentHeader.length;
                        _currentPacket = new SNIPacket(null);
                        _currentPacket.Allocate((int)_currentHeader.length);
                    }

                    currentHeader = _currentHeader;
                    currentPacket = _currentPacket;

                    if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA)
                    {
                        if (_dataBytesLeft > 0)
                        {
                            int length = packet.TakeData(_currentPacket, _dataBytesLeft);
                            _dataBytesLeft -= length;

                            if (_dataBytesLeft > 0)
                            {
                                sniErrorCode = ReceiveAsync(ref packet);

                                if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING)
                                {
                                    return;
                                }

                                HandleReceiveError();
                                return;
                            }
                        }
                    }

                    _currentHeaderByteCount = 0;

                    if (!_sessions.ContainsKey(_currentHeader.sessionId))
                    {
                        SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, SNICommon.InvalidParameterError, string.Empty);
                        HandleReceiveError();
                        _lowerHandle.Dispose();
                        _lowerHandle = null;
                        return;
                    }

                    if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_FIN)
                    {
                        _sessions.Remove(_currentHeader.sessionId);
                    }
                    else
                    {
                        currentSession = _sessions[_currentHeader.sessionId];
                    }
                }

                if (currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA)
                {
                    currentSession.HandleReceiveComplete(currentPacket, currentHeader);
                }

                if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_ACK)
                {
                    try
                    {
                        currentSession.HandleAck(currentHeader.highwater);
                    }
                    catch (Exception e)
                    {
                        SNICommon.ReportSNIError(SNIProviders.SMUX_PROV, SNICommon.InternalExceptionError, e);
                    }
                }

                lock (this)
                {
                    if (packet.DataLeft == 0)
                    {
                        sniErrorCode = ReceiveAsync(ref packet);

                        if (sniErrorCode == TdsEnums.SNI_SUCCESS_IO_PENDING)
                        {
                            return;
                        }

                        HandleReceiveError();
                        return;
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Handle receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="header">SMUX header</param>
        public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header)
        {
            lock (this)
            {
                if (_sendHighwater != header.highwater)
                {
                    HandleAck(header.highwater);
                }

                lock (_receivedPacketQueue)
                {
                    if (_asyncReceives == 0)
                    {
                        _receivedPacketQueue.Enqueue(packet);
                        _packetEvent.Set();
                        return;
                    }

                    _asyncReceives--;
                    Debug.Assert(_callbackObject != null);

#if MANAGED_SNI // Causes build issue if uncommented in unmanaged version
                    ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 0);
#endif
                }
            }

            lock (this)
            {
                _receiveHighwater++;
            }

            SendAckIfNecessary();
        }
예제 #7
0
        /// <summary>
        /// Handle receive completion
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="header">SMUX header</param>
        public void HandleReceiveComplete(SNIPacket packet, SNISMUXHeader header)
        {
            lock (this)
            {
                if (_sendHighwater != header.highwater)
                {
                    HandleAck(header.highwater);
                }

                lock (_receivedPacketQueue)
                {
                    if (_asyncReceives == 0)
                    {
                        _receivedPacketQueue.Enqueue(packet);
                        _packetEvent.Set();
                        return;
                    }

                    _asyncReceives--;
                    Debug.Assert(_callbackObject != null);

                    ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 0);
                }
            }

            lock (this)
            {
                _receiveHighwater++;
            }

            SendAckIfNecessary();
        }
예제 #8
0
        /// <summary>
        /// Process a receive completion
        /// </summary>
        public void HandleReceiveComplete(SNIPacket packet, SNIError sniError)
        {
            SNISMUXHeader currentHeader  = null;
            SNIPacket     currentPacket  = null;
            SNIMarsHandle currentSession = null;

            if (sniError != null)
            {
                lock (this)
                {
                    HandleReceiveError(sniError);
                    return;
                }
            }

            int packetOffset = 0;

            while (true)
            {
                lock (this)
                {
                    bool sessionRemoved = false;

                    if (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH)
                    {
                        currentHeader  = null;
                        currentPacket  = null;
                        currentSession = null;

                        while (_currentHeaderByteCount != SNISMUXHeader.HEADER_LENGTH)
                        {
                            int bytesTaken = packet.TakeData(packetOffset, _headerBytes, _currentHeaderByteCount, SNISMUXHeader.HEADER_LENGTH - _currentHeaderByteCount);
                            packetOffset            += bytesTaken;
                            _currentHeaderByteCount += bytesTaken;

                            if (bytesTaken == 0)
                            {
                                packetOffset = 0;
                                ReceiveAsync(ref packet);
                                return;
                            }
                        }

                        _currentHeader = new SNISMUXHeader()
                        {
                            SMID           = _headerBytes[0],
                            flags          = _headerBytes[1],
                            sessionId      = BitConverter.ToUInt16(_headerBytes, 2),
                            length         = BitConverter.ToUInt32(_headerBytes, 4) - SNISMUXHeader.HEADER_LENGTH,
                            sequenceNumber = BitConverter.ToUInt32(_headerBytes, 8),
                            highwater      = BitConverter.ToUInt32(_headerBytes, 12)
                        };

                        _dataBytesLeft = (int)_currentHeader.length;
                        _currentPacket = new SNIPacket();
                        _currentPacket.Allocate((int)_currentHeader.length);
                    }

                    currentHeader = _currentHeader;
                    currentPacket = _currentPacket;

                    if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA)
                    {
                        if (_dataBytesLeft > 0)
                        {
                            int length = packet.TakeData(packetOffset, _currentPacket, _dataBytesLeft);
                            packetOffset   += length;
                            _dataBytesLeft -= length;

                            if (_dataBytesLeft > 0)
                            {
                                packetOffset = 0;
                                ReceiveAsync(ref packet);
                                return;
                            }
                        }
                    }

                    _currentHeaderByteCount = 0;

                    if (!sessionRemoved && !_sessions.TryGetValue(_currentHeader.sessionId, out currentSession))
                    {
                        sniError = new SNIError(SNIProviders.TCP_PROV, 0, 0, "Packet for unknown MARS session received");
                        HandleReceiveError(sniError);
                        return;
                    }

                    if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_FIN)
                    {
                        RemoveSession(_currentHeader.sessionId);
                        sessionRemoved = true;
                    }
                    else
                    {
                        currentSession = _sessions[_currentHeader.sessionId];
                    }
                }

                if (currentSession != null)
                {
                    if (currentHeader.flags == (byte)SNISMUXFlags.SMUX_DATA)
                    {
                        currentSession.HandleReceiveComplete(currentPacket, currentHeader);
                    }
                    else if (_currentHeader.flags == (byte)SNISMUXFlags.SMUX_ACK)
                    {
                        currentSession.HandleAck(currentHeader.highwater);
                    }
                }

                lock (this)
                {
                    if (packet.Length - packetOffset == 0)
                    {
                        packetOffset = 0;
                        ReceiveAsync(ref packet);
                        return;
                    }
                }
            }
        }