Exemple #1
0
        private static void ReadFromStreamAsyncContinuation(Task <int> t, object state)
        {
            SNIPacket packet = (SNIPacket)state;
            SNIError  error  = null;

            Exception e = t.Exception?.InnerException;

            if (e != null)
            {
                error = new SNIError(SNIProviders.TCP_PROV, 0, 0, e.Message);
            }
            else
            {
                packet._length = t.Result;

                if (packet._length == 0)
                {
                    error = new SNIError(SNIProviders.TCP_PROV, 0, SNIErrorCode.ConnTerminatedError, string.Empty);
                }
            }

            SNIAsyncCallback callback = packet._completionCallback;

            packet._completionCallback = null;
            callback(packet, error);
        }
Exemple #2
0
        /// <summary>
        /// Enables MARS for a TdsParserStateObject and returns its new handle.
        /// </summary>
        public static SNIMarsHandle EnableMars(TdsParserStateObject stateObject, out SNIError sniError)
        {
            Debug.Assert(!(stateObject.Handle is SNIMarsHandle), "Cannot enable MARS on a SNIMarsHandle");
            SNIMarsConnection marsConnection = new SNIMarsConnection(stateObject.Handle);

            marsConnection.StartReceive();
            return(marsConnection.CreateSession(stateObject, out sniError));
        }
Exemple #3
0
        private void ReceiveAsyncErrorContinuation(object rawState)
        {
            var       state    = (Tuple <SNIPacket, SNIError>)rawState;
            SNIPacket packet   = state.Item1;
            SNIError  sniError = state.Item2;

            _receiveCallback(packet, sniError);
        }
Exemple #4
0
        private static void SendAsyncErrorContinuation(object rawState)
        {
            var              state    = (Tuple <SNIPacket, SNIAsyncCallback, SNIError>)rawState;
            SNIPacket        packet   = state.Item1;
            SNIAsyncCallback callback = state.Item2;
            SNIError         sniError = state.Item3;

            callback(packet, sniError);
        }
Exemple #5
0
 /// <summary>
 /// Process a receive error
 /// </summary>
 public void HandleReceiveError(SNIError sniError)
 {
     Debug.Assert(Monitor.IsEntered(this), "HandleReceiveError was called without being locked.");
     foreach (SNIMarsHandle handle in _sessions.Values)
     {
         handle.HandleReceiveError(new SNIPacket(), sniError);
     }
     _lowerHandle.Dispose();
 }
Exemple #6
0
 public SNIMarsHandle CreateSession(TdsParserStateObject callbackObject, out SNIError sniError)
 {
     lock (this)
     {
         ushort        sessionId = _nextSessionId++;
         SNIMarsHandle handle    = new SNIMarsHandle(this, sessionId, callbackObject, out sniError);
         _sessions.Add(sessionId, handle);
         return(handle);
     }
 }
Exemple #7
0
        /// <summary>
        /// Handle receive error
        /// </summary>
        public void HandleReceiveError(SNIPacket packet)
        {
            lock (_receivedPacketQueue)
            {
                _connectionError = SNILoadHandle.SingletonInstance.LastError;
                _packetEvent.Set();
            }

            ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(packet, 1);
        }
        /// <summary>
        /// Handle receive error
        /// </summary>
        public void HandleReceiveError()
        {
            lock (_receivedPacketQueue)
            {
                _connectionError = SNILoadHandle.SingletonInstance.LastError;
                _packetEvent.Set();
            }

#if MANAGED_SNI // Causes build issue if uncommented in unmanaged version
            ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(null, 1);
#endif
        }
Exemple #9
0
        /// <summary>
        /// Receive a packet synchronously
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="timeoutInMilliseconds">Timeout in Milliseconds</param>
        /// <returns>SNI error code</returns>
        public sealed override SNIError Receive(ref SNIPacket packet, int timeoutInMilliseconds)
        {
            packet = packet ?? new SNIPacket();

            using (_debugLock.Acquire(this))
            {
                try
                {
                    SNIError timeoutError = SetupTimeoutForReceive(timeoutInMilliseconds);
                    if (timeoutError != null)
                    {
                        return(timeoutError);
                    }

                    packet.Allocate(_bufferSize);
                    packet.ReadFromStream(_stream);

                    if (packet.Length == 0)
                    {
                        return(new SNIError(ProviderNumber, 0, 0, "Connection was terminated"));
                    }

                    return(null);
                }
                catch (ObjectDisposedException ode)
                {
                    packet = null;
                    return(new SNIError(ProviderNumber, 0, ode));
                }
                catch (SocketException se)
                {
                    packet = null;
                    return(new SNIError(ProviderNumber, 0, se));
                }
                catch (IOException ioe)
                {
                    SNIErrorCode errorCode = SNIErrorCode.NoError;
                    if (ioe.InnerException is SocketException && ((SocketException)(ioe.InnerException)).SocketErrorCode == SocketError.TimedOut)
                    {
                        errorCode = SNIErrorCode.ConnTimeoutError;
                    }

                    packet = null;
                    return(new SNIError(ProviderNumber, errorCode, ioe));
                }
            }
        }
Exemple #10
0
        private static void SendAsyncContinuation(Task task, object rawState)
        {
            var state = (Tuple <SNITransportHandle, SNIPacket, SNIAsyncCallback>)rawState;
            SNITransportHandle handle   = state.Item1;
            SNIPacket          packet   = state.Item2;
            SNIAsyncCallback   callback = state.Item3;

            if (task.IsFaulted)
            {
                SNIError sniError = new SNIError(handle.ProviderNumber, 0, task.Exception);
                callback(packet, sniError);
            }
            else
            {
                callback(packet, null);
            }
        }
Exemple #11
0
        public SNINpHandle(string serverName, string pipeName, long timerExpire, out SNIError error)
            : base(serverName)
        {
            try
            {
                _pipeStream = new NamedPipeClientStream(serverName, pipeName, PipeDirection.InOut, PipeOptions.WriteThrough | PipeOptions.Asynchronous);

                bool isInfiniteTimeOut = long.MaxValue == timerExpire;
                if (isInfiniteTimeOut)
                {
                    _pipeStream.Connect(Threading.Timeout.Infinite);
                }
                else
                {
                    TimeSpan ts = DateTime.FromFileTime(timerExpire) - DateTime.Now;
                    ts = ts.Ticks < 0 ? TimeSpan.FromTicks(0) : ts;

                    _pipeStream.Connect((int)ts.TotalMilliseconds);
                }
            }
            catch (TimeoutException te)
            {
                error = new SNIError(SNIProviders.NP_PROV, SNIErrorCode.ConnTimeoutError, te);
                return;
            }
            catch (IOException ioe)
            {
                error = new SNIError(SNIProviders.NP_PROV, SNIErrorCode.ConnOpenFailedError, ioe);
                return;
            }

            if (!_pipeStream.IsConnected || !_pipeStream.CanWrite || !_pipeStream.CanRead)
            {
                error = new SNIError(SNIProviders.NP_PROV, 0, SNIErrorCode.ConnOpenFailedError, string.Empty);
                return;
            }

            _sslOverTdsStream = new SslOverTdsStream(_pipeStream);
            _sslStream        = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);

            _stream = _pipeStream;
            error   = null;
        }
Exemple #12
0
        /// <summary>
        /// Receive a packet asynchronously
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <returns>SNI error code</returns>
        public sealed override bool ReceiveAsync(bool forceCallback, ref SNIPacket packet, out SNIError sniError)
        {
            packet = packet ?? new SNIPacket();
            packet.Allocate(_bufferSize);

            using (_debugLock.Acquire(this))
            {
                try
                {
                    packet.ReadFromStreamAsync(_stream, _receiveCallback);
                    sniError = null;
                    return(false);
                }
                catch (ObjectDisposedException ode)
                {
                    sniError = new SNIError(ProviderNumber, 0, ode);
                }
                catch (SocketException se)
                {
                    sniError = new SNIError(ProviderNumber, 0, se);
                }
                catch (IOException ioe)
                {
                    sniError = new SNIError(ProviderNumber, 0, ioe);
                }

                // Fallthrough: Something failed
                Debug.Assert(sniError != null, "Error should be set if we didn't already return");
                if (forceCallback)
                {
                    Task.Factory.StartNew(
                        ReceiveAsyncErrorContinuation,
                        Tuple.Create(packet, sniError),
                        CancellationToken.None,
                        TaskCreationOptions.DenyChildAttach,
                        TaskScheduler.Default);
                    sniError = null;
                    return(false);
                }
                return(true);
            }
        }
Exemple #13
0
        /// <summary>
        /// Handle receive error
        /// </summary>
        public void HandleReceiveError(SNIPacket packet, SNIError sniError)
        {
            int callbacksPending;

            lock (_receivedPacketQueue)
            {
                Debug.Assert(_connectionError == null, "Already have a stored connection error");
                _connectionError = sniError;

                // Wake any pending sync receives
                _packetEvent.Set();

                callbacksPending = _asyncReceives;
                _asyncReceives   = 0;
            }

            // Callback to any pending async receives
            for (int i = 0; i < _asyncReceives; i++)
            {
                _callbackObject.ReadAsyncCallback(packet, _connectionError);
            }
        }
Exemple #14
0
        /// <summary>
        /// Receive a packet asynchronously
        /// </summary>
        /// <returns>True if completed synchronously, otherwise false</returns>
        public override bool ReceiveAsync(bool forceCallback, ref SNIPacket packet, out SNIError sniError)
        {
            Debug.Assert(!forceCallback, "SNIMarsHandles should never be forced to use a callback");

            lock (_receivedPacketQueue)
            {
                int queueCount = _receivedPacketQueue.Count;

                if (_connectionError != null)
                {
                    sniError = _connectionError;
                    return(true);
                }

                if (queueCount == 0)
                {
                    _asyncReceives++;
                    sniError = null;
                    return(false);
                }

                packet = _receivedPacketQueue.Dequeue();

                if (queueCount == 1)
                {
                    _packetEvent.Reset();
                }
            }

            lock (this)
            {
                _receiveHighwater++;
            }

            sniError = SendAckIfNecessary();
            return(true);
        }
Exemple #15
0
        /// <summary>
        /// Send a packet asynchronously
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="callback">Completion callback</param>
        /// <returns>SNI error code</returns>
        public override bool SendAsync(SNIPacket packet, SNIAsyncCallback callback, bool forceCallback, out SNIError sniError)
        {
            lock (this)
            {
                _sendPacketQueue.Enqueue(new SNIMarsQueuedPacket(packet, callback != null ? callback : HandleSendComplete));
            }

            SendPendingPackets();
            sniError = null;
            return(false);
        }
Exemple #16
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;
                    }
                }
            }
        }
Exemple #17
0
 /// <summary>
 /// Process a send completion
 /// </summary>
 public void HandleSendComplete(SNIPacket packet, SNIError sniError)
 {
     packet.InvokeCompletionCallback(sniError);
 }
Exemple #18
0
 /// <summary>
 /// Creates a new MARS session.
 /// </summary>
 public override SNIHandle CreateSession(TdsParserStateObject callbackObject, out SNIError sniError)
 {
     return(_connection.CreateSession(callbackObject, out sniError));
 }
Exemple #19
0
        /// <summary>
        /// Send a packet asynchronously
        /// </summary>
        /// <param name="packet">SNI packet</param>
        /// <param name="callback">Completion callback</param>
        /// <returns>SNI error code</returns>
        public sealed override bool SendAsync(SNIPacket packet, SNIAsyncCallback callback, bool forceCallback, out SNIError sniError)
        {
            try
            {
                Task writeTask;
                using (_debugLock.Acquire(this))
                {
                    writeTask = packet.WriteToStreamAsync(_stream);
                }

                if (writeTask.IsCompleted && !forceCallback)
                {
                    if (writeTask.IsFaulted)
                    {
                        sniError = new SNIError(ProviderNumber, 0, writeTask.Exception);
                    }
                    else
                    {
                        sniError = null;
                    }
                    return(true);
                }
                else
                {
                    writeTask.ContinueWith(SendAsyncContinuation,
                                           Tuple.Create(this, packet, callback ?? _sendCallback),
                                           CancellationToken.None,
                                           TaskContinuationOptions.DenyChildAttach,
                                           TaskScheduler.Default);
                    sniError = null;
                    return(false);
                }
            }
            catch (ObjectDisposedException ode)
            {
                sniError = new SNIError(ProviderNumber, 0, ode);
            }
            catch (SocketException se)
            {
                sniError = new SNIError(ProviderNumber, 0, se);
            }
            catch (IOException ioe)
            {
                sniError = new SNIError(ProviderNumber, 0, ioe);
            }

            // Fallthrough: We caught an error
            Debug.Assert(sniError != null, "Should have either set an error or returned early");
            if (forceCallback)
            {
                Task.Factory.StartNew(SendAsyncErrorContinuation,
                                      Tuple.Create(packet, callback ?? _sendCallback, sniError),
                                      CancellationToken.None,
                                      TaskCreationOptions.DenyChildAttach,
                                      TaskScheduler.Default);
                sniError = null;
                return(false);
            }
            else
            {
                return(true);
            }
        }
Exemple #20
0
 public override SNIHandle CreateSession(TdsParserStateObject callbackObject, out SNIError sniError)
 {
     Debug.Assert(false, "Not a MARS connection");
     sniError = null;
     return(null);
 }
Exemple #21
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="serverName">Server name</param>
        /// <param name="port">TCP port number</param>
        /// <param name="timerExpire">Connection timer expiration</param>
        /// <param name="callbackObject">Callback object</param>
        public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel, out SNIError sniError)
            : base(serverName)
        {
            try
            {
                TimeSpan ts;

                // In case the Timeout is Infinite, we will receive the max value of Int64 as the tick count
                // The infinite Timeout is a function of ConnectionString Timeout=0
                bool isInfiniteTimeOut = long.MaxValue == timerExpire;
                if (!isInfiniteTimeOut)
                {
                    ts = DateTime.FromFileTime(timerExpire) - DateTime.Now;
                    ts = ts.Ticks < 0 ? TimeSpan.FromTicks(0) : ts;
                }

                Task <Socket> connectTask;
                if (parallel)
                {
                    Task <IPAddress[]> serverAddrTask = Dns.GetHostAddressesAsync(serverName);
                    serverAddrTask.Wait(ts);
                    IPAddress[] serverAddresses = serverAddrTask.Result;

                    if (serverAddresses.Length > MaxParallelIpAddresses)
                    {
                        // Fail if above 64 to match legacy behavior
                        sniError = new SNIError(SNIProviders.TCP_PROV, 0, SNIErrorCode.MultiSubnetFailoverWithMoreThan64IPs, string.Empty);
                        return;
                    }

                    connectTask = ConnectAsync(serverAddresses, port);
                }
                else
                {
                    connectTask = ConnectAsync(serverName, port);
                }

                if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts)))
                {
                    sniError = new SNIError(SNIProviders.TCP_PROV, 0, SNIErrorCode.ConnOpenFailedError, SQLMessage.Timeout());
                    return;
                }

                _socket         = connectTask.Result;
                _socket.NoDelay = true;
                _tcpStream      = new NetworkStream(_socket, true);

                _sslOverTdsStream = new SslOverTdsStream(_tcpStream);
                _sslStream        = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
            }
            catch (SocketException se)
            {
                sniError = new SNIError(SNIProviders.TCP_PROV, 0, se);
                return;
            }
            catch (Exception e)
            {
                sniError = new SNIError(SNIProviders.TCP_PROV, 0, e);
                return;
            }

            _stream  = _tcpStream;
            sniError = null;
        }
Exemple #22
0
 private static void NullCallback(SNIPacket packet, SNIError error)
 {
 }
Exemple #23
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="connection">MARS connection</param>
 /// <param name="sessionId">MARS session ID</param>
 /// <param name="callbackObject">Callback object</param>
 /// <param name="async">true if connection is asynchronous</param>
 public SNIMarsHandle(SNIMarsConnection connection, ushort sessionId, TdsParserStateObject callbackObject, out SNIError sniError)
 {
     _sessionId      = sessionId;
     _connection     = connection;
     _callbackObject = callbackObject;
     sniError        = SendControlPacket(SNISMUXFlags.SMUX_SYN, true);
 }
Exemple #24
0
 /// <summary>
 /// Send a packet asynchronously
 /// </summary>
 /// <param name="packet">SNI packet</param>
 /// <param name="callback">Completion callback</param>
 /// <returns>True if completed synchronously, otherwise false</returns>
 public bool SendAsync(SNIPacket packet, SNIAsyncCallback callback, bool forceCallback, out SNIError sniError)
 {
     lock (this)
     {
         return(_lowerHandle.SendAsync(packet, callback, forceCallback, out sniError));
     }
 }
Exemple #25
0
 /// <summary>
 /// Receive a packet asynchronously
 /// </summary>
 public abstract bool ReceiveAsync(bool forceCallback, ref SNIPacket packet, out SNIError sniError);
Exemple #26
0
        /// <summary>
        /// Handle receive error
        /// </summary>
        public void HandleReceiveError()
        {
            lock (_receivedPacketQueue)
            {
                _connectionError = SNILoadHandle.SingletonInstance.LastError;
                _packetEvent.Set();
            }

            ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(null, 1);
        }
Exemple #27
0
 /// <summary>
 /// If this is a multiplexed connection, creates a new session.
 /// </summary>
 public abstract SNIHandle CreateSession(TdsParserStateObject callbackObject, out SNIError sniError);
Exemple #28
0
        /// <summary>
        /// Handle receive error
        /// </summary>
        public void HandleReceiveError()
        {
            lock (_receivedPacketQueue)
            {
                _connectionError = SNILoadHandle.SingletonInstance.LastError;
                _packetEvent.Set();
            }

#if MANAGED_SNI // Causes build issue if uncommented in unmanaged version
            ((TdsParserStateObject)_callbackObject).ReadAsyncCallback(null, 1);
#endif
        }
Exemple #29
0
        /// <summary>
        /// Handle send completion
        /// </summary>
        public void HandleSendComplete(SNIPacket packet, SNIError sniError)
        {
            Debug.Assert(_callbackObject != null);

            _callbackObject.WriteAsyncCallback(packet, sniError);
        }
Exemple #30
0
 /// <summary>
 /// Sets last error encountered for SNI
 /// </summary>
 /// <param name="error">SNI error</param>
 /// <returns></returns>
 internal static uint ReportSNIError(SNIError error)
 {
     SNILoadHandle.SingletonInstance.LastError = error;
     return(TdsEnums.SNI_ERROR);
 }
Exemple #31
0
 /// <summary>
 /// Send a packet asynchronously
 /// </summary>
 /// <param name="packet">SNI packet</param>
 /// <param name="callback">Completion callback</param>
 /// <returns>True if completed synchronously, otherwise false</returns>
 public abstract bool SendAsync(SNIPacket packet, SNIAsyncCallback callback, bool forceCallback, out SNIError error);
Exemple #32
0
 /// <summary>
 /// Sets last error encountered for SNI
 /// </summary>
 /// <param name="error">SNI error</param>
 /// <returns></returns>
 internal static uint ReportSNIError(SNIError error)
 {
     SNILoadHandle.SingletonInstance.LastError = error;
     return TdsEnums.SNI_ERROR;
 }
Exemple #33
0
 /// <summary>
 /// Invoke the completion callback
 /// </summary>
 /// <param name="sniError">SNI error</param>
 public void InvokeCompletionCallback(SNIError sniError)
 {
     _completionCallback(this, sniError);
 }