/// <summary> /// Send a packet synchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public uint Send(SNIPacket packet) { lock (this) { return _lowerHandle.Send(packet); } }
/// <summary> /// Receive a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public override uint ReceiveAsync(ref SNIPacket packet) { lock (this) { packet = new SNIPacket(null); packet.Allocate(_bufferSize); try { packet.ReadFromStreamAsync(_stream, _receiveCallback); return TdsEnums.SNI_SUCCESS_IO_PENDING; } catch (ObjectDisposedException ode) { return ReportErrorAndReleasePacket(packet, ode); } catch (SocketException se) { return ReportErrorAndReleasePacket(packet, se); } catch (IOException ioe) { return ReportErrorAndReleasePacket(packet, ioe); } } }
/// <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 override uint Receive(out SNIPacket packet, int timeoutInMilliseconds) { lock (this) { packet = null; try { if (timeoutInMilliseconds > 0) { _socket.ReceiveTimeout = timeoutInMilliseconds; } else if (timeoutInMilliseconds == -1) { // SqlCient internally represents infinite timeout by -1, and for TcpClient this is translated to a timeout of 0 _socket.ReceiveTimeout = 0; } else { // otherwise it is timeout for 0 or less than -1 ReportTcpSNIError(0, SNICommon.ConnTimeoutError, string.Empty); return TdsEnums.SNI_WAIT_TIMEOUT; } packet = new SNIPacket(null); packet.Allocate(_bufferSize); packet.ReadFromStream(_stream); if (packet.Length == 0) { return ReportErrorAndReleasePacket(packet, 0, SNICommon.ConnTerminatedError, string.Empty); } return TdsEnums.SNI_SUCCESS; } catch (ObjectDisposedException ode) { return ReportErrorAndReleasePacket(packet, ode); } catch (SocketException se) { return ReportErrorAndReleasePacket(packet, se); } catch (IOException ioe) { uint errorCode = ReportErrorAndReleasePacket(packet, ioe); if (ioe.InnerException is SocketException && ((SocketException)(ioe.InnerException)).SocketErrorCode == SocketError.TimedOut) { errorCode = TdsEnums.SNI_WAIT_TIMEOUT; } return errorCode; } finally { _socket.ReceiveTimeout = 0; } } }
/// <summary> /// Receive a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public abstract uint ReceiveAsync(ref SNIPacket packet);
/// <summary> /// Send a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <param name="callback">Completion callback</param> /// <returns>SNI error code</returns> public abstract uint SendAsync(SNIPacket packet, SNIAsyncCallback callback = null);
/// <summary> /// Constructor /// </summary> /// <param name="packet">SNI packet</param> /// <param name="callback">Completion callback</param> public SNIMarsQueuedPacket(SNIPacket packet, SNIAsyncCallback callback) { _packet = packet; _callback = callback; }
/// <summary> /// Set packet data /// </summary> /// <param name="packet">SNI packet</param> /// <param name="data">Data</param> /// <param name="length">Length</param> public void PacketSetData(SNIPacket packet, byte[] data, int length) { packet.SetData(data, length); }
/// <summary> /// Receive a packet synchronously /// </summary> /// <param name="packet">SNI packet</param> /// <param name="timeout">Timeout</param> /// <returns>SNI error code</returns> public abstract uint Receive(ref SNIPacket packet, int timeout);
/// <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 uint SendAsync(SNIPacket packet, SNIAsyncCallback callback = null) { lock (this) { _sendPacketQueue.Enqueue(new SNIMarsQueuedPacket(packet, callback != null ? callback : HandleSendComplete)); } SendPendingPackets(); return TdsEnums.SNI_SUCCESS_IO_PENDING; }
/// <summary> /// Send a packet synchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public abstract uint Send(SNIPacket packet);
/// <summary> /// Constructor /// </summary> /// <param name="packet">SNI packet</param> /// <param name="callback">Completion callback</param> public SNIMarsQueuedPacket(SNIPacket packet, SNIAsyncCallback callback) { Packet = packet; Callback = callback; }
/// <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 abstract uint Receive(out SNIPacket packet, int timeoutInMilliseconds);
private uint ReportErrorAndReleasePacket(SNIPacket packet, uint nativeError, uint sniError, string errorMessage) { if (packet != null) { packet.Release(); } return ReportTcpSNIError(nativeError, sniError, errorMessage); }
/// <summary> /// Receive a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public override uint ReceiveAsync(ref SNIPacket packet) { lock (_receivedPacketQueue) { int queueCount = _receivedPacketQueue.Count; if (_connectionError != null) { return SNICommon.ReportSNIError(_connectionError); } if (queueCount == 0) { _asyncReceives++; return TdsEnums.SNI_SUCCESS_IO_PENDING; } packet = _receivedPacketQueue.Dequeue(); if (queueCount == 1) { _packetEvent.Reset(); } } lock (this) { _receiveHighwater++; } SendAckIfNecessary(); return TdsEnums.SNI_SUCCESS; }
/// <summary> /// Process a send completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="sniErrorCode">SNI error code</param> public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) { packet.InvokeCompletionCallback(sniErrorCode); }
/// <summary> /// Handle send completion /// </summary> /// <param name="packet">SNI packet</param> /// <param name="sniErrorCode">SNI error code</param> public void HandleSendComplete(SNIPacket packet, uint sniErrorCode) { lock (this) { Debug.Assert(_callbackObject != null); #if MANAGED_SNI // Causes build issue if uncommented in unmanaged version ((TdsParserStateObject)_callbackObject).WriteAsyncCallback(packet, sniErrorCode); #endif } }
/// <summary> /// Send a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <param name="callback">Completion callback</param> /// <returns>SNI error code</returns> public abstract uint SendAsync(SNIPacket packet, bool disposePacketAfterSendAsync, SNIAsyncCallback callback = null);
/// <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(); }
/// <summary> /// Release packet /// </summary> /// <param name="packet">SNI packet</param> public void PacketRelease(SNIPacket packet) { packet.Release(); }
/// <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 override uint Receive(out SNIPacket packet, int timeoutInMilliseconds) { packet = null; int queueCount; uint result = TdsEnums.SNI_SUCCESS_IO_PENDING; while (true) { lock (_receivedPacketQueue) { if (_connectionError != null) { return SNICommon.ReportSNIError(_connectionError); } queueCount = _receivedPacketQueue.Count; if (queueCount > 0) { packet = _receivedPacketQueue.Dequeue(); if (queueCount == 1) { _packetEvent.Reset(); } result = TdsEnums.SNI_SUCCESS; } } if (result == TdsEnums.SNI_SUCCESS) { lock (this) { _receiveHighwater++; } SendAckIfNecessary(); return result; } if (!_packetEvent.Wait(timeoutInMilliseconds)) { SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.SMUX_PROV, 0, 11, SR.SNI_ERROR_11); return TdsEnums.SNI_WAIT_TIMEOUT; } } }
/// <summary> /// Send control packet /// </summary> /// <param name="flags">SMUX header flags</param> private void SendControlPacket(SNISMUXFlags flags) { byte[] headerBytes = null; lock (this) { GetSMUXHeaderBytes(0, (byte)flags, ref headerBytes); } SNIPacket packet = new SNIPacket(null); packet.SetData(headerBytes, SNISMUXHeader.HEADER_LENGTH); _connection.Send(packet); }
private uint ReportErrorAndReleasePacket(SNIPacket packet, string errorMessage) { packet.Release(); return ReportTcpSNIError(0, 0, errorMessage); }
/// <summary> /// Send a packet synchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public override uint Send(SNIPacket packet) { lock (this) { try { packet.WriteToStream(_stream); return TdsEnums.SNI_SUCCESS; } catch (ObjectDisposedException ode) { return ReportTcpSNIError(ode); } catch (SocketException se) { return ReportTcpSNIError(se); } catch (IOException ioe) { return ReportTcpSNIError(ioe); } } }
/// <summary> /// Get packet data /// </summary> /// <param name="packet">SNI packet</param> /// <param name="inBuff">Buffer</param> /// <param name="dataSize">Data size</param> /// <returns>SNI error status</returns> public uint PacketGetData(SNIPacket packet, byte[] inBuff, ref uint dataSize) { int dataSizeInt = 0; packet.GetData(inBuff, ref dataSizeInt); dataSize = (uint)dataSizeInt; return TdsEnums.SNI_SUCCESS; }
/// <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 uint SendAsync(SNIPacket packet, SNIAsyncCallback callback = null) { SNIPacket newPacket = packet; _writeTaskFactory.StartNew(() => { try { lock (this) { packet.WriteToStream(_stream); } } catch (Exception e) { SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, SNICommon.InternalExceptionError, e); if (callback != null) { callback(packet, TdsEnums.SNI_ERROR); } else { _sendCallback(packet, TdsEnums.SNI_ERROR); } return; } if (callback != null) { callback(packet, TdsEnums.SNI_SUCCESS); } else { _sendCallback(packet, TdsEnums.SNI_SUCCESS); } }); return TdsEnums.SNI_SUCCESS_IO_PENDING; }
/// <summary> /// Read synchronously /// </summary> /// <param name="handle">SNI handle</param> /// <param name="packet">SNI packet</param> /// <param name="timeout">Timeout</param> /// <returns>SNI error status</returns> public uint ReadSyncOverAsync(SNIHandle handle, out SNIPacket packet, int timeout) { return handle.Receive(out packet, timeout); }
private uint ReportErrorAndReleasePacket(SNIPacket packet, Exception sniException) { if (packet != null) { packet.Release(); } return ReportTcpSNIError(sniException); }
/// <summary> /// Send a packet /// </summary> /// <param name="handle">SNI handle</param> /// <param name="packet">SNI packet</param> /// <param name="sync">true if synchronous, false if asynchronous</param> /// <returns>SNI error status</returns> public uint WritePacket(SNIHandle handle, SNIPacket packet, bool sync) { if (sync) { return handle.Send(packet.Clone()); } else { return handle.SendAsync(packet.Clone()); } }
/// <summary> /// Receive a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public uint ReceiveAsync(ref SNIPacket packet) { lock (this) { return _lowerHandle.ReceiveAsync(ref packet); } }
/// <summary> /// Reset a packet /// </summary> /// <param name="handle">SNI handle</param> /// <param name="write">true if packet is for write</param> /// <param name="packet">SNI packet</param> public void PacketReset(SNIHandle handle, bool write, SNIPacket packet) { packet.Reset(); }
/// <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; } } } }
/// <summary> /// Read packet asynchronously /// </summary> /// <param name="handle">SNI handle</param> /// <param name="packet">Packet</param> /// <returns>SNI error status</returns> public uint ReadAsync(SNIHandle handle, ref SNIPacket packet) { packet = new SNIPacket(null); return handle.ReceiveAsync(ref packet); }
/// <summary> /// Send a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <param name="callback">Completion callback</param> /// <returns>SNI error code</returns> public uint SendAsync(SNIPacket packet, SNIAsyncCallback callback) { lock (this) { return _lowerHandle.SendAsync(packet, callback); } }
/// <summary> /// Receive a packet asynchronously /// </summary> /// <param name="packet">SNI packet</param> /// <returns>SNI error code</returns> public abstract uint ReceiveAsync(ref SNIPacket packet, bool isMars = false);