/// <summary> /// Dispose object /// </summary> public override void Dispose() { lock (this) { if (_sslOverTdsStream != null) { _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; } if (_sslStream != null) { _sslStream.Dispose(); _sslStream = null; } if (_tcpStream != null) { _tcpStream.Dispose(); _tcpStream = null; } //Release any references held by _stream. _stream = null; } }
public SNINpHandle(string serverName, string pipeName, long timerExpire) { using (TrySNIEventScope.Create(nameof(SNINpHandle))) { SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO, "Connection Id {0}, Setting server name = {1}, pipe name = {2}", args0: _connectionId, args1: serverName, args2: pipeName); _sendSync = new object(); _targetServer = serverName; try { _pipeStream = new NamedPipeClientStream( serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough); bool isInfiniteTimeOut = long.MaxValue == timerExpire; if (isInfiniteTimeOut) { _pipeStream.Connect(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) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, SNICommon.ConnOpenFailedError, te); _status = TdsEnums.SNI_ERROR; SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.ERR, "Connection Id {0}, Connection Timed out. Error Code 1 Exception = {1}", args0: _connectionId, args1: te?.Message); return; } catch (IOException ioe) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, SNICommon.ConnOpenFailedError, ioe); _status = TdsEnums.SNI_ERROR; SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.ERR, "Connection Id {0}, IO Exception occurred. Error Code 1 Exception = {1}", args0: _connectionId, args1: ioe?.Message); return; } if (!_pipeStream.IsConnected || !_pipeStream.CanWrite || !_pipeStream.CanRead) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40); _status = TdsEnums.SNI_ERROR; SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.ERR, "Connection Id {0}, Pipe Stream not operational. Error Code 1 Exception = {1}", args0: _connectionId, args1: Strings.SNI_ERROR_1); return; } _sslOverTdsStream = new SslOverTdsStream(_pipeStream, _connectionId); _sslStream = new SNISslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate)); _stream = _pipeStream; _status = TdsEnums.SNI_SUCCESS; } }
public override void Dispose() { lock (this) { if (_sslOverTdsStream != null) { _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; } if (_sslStream != null) { _sslStream.Dispose(); _sslStream = null; } if (_pipeStream != null) { _pipeStream.Dispose(); _pipeStream = null; } //Release any references held by _stream. _stream = null; SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO, "Connection Id {0}, All streams disposed and references cleared.", args0: _connectionId); } }
/// <summary> /// Dispose object /// </summary> public override void Dispose() { lock (this) { if (_sslOverTdsStream != null) { _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; } if (_sslStream != null) { _sslStream.Dispose(); _sslStream = null; } if (_tcpStream != null) { _tcpStream.Dispose(); _tcpStream = null; } //Release any references held by _stream. _stream = null; SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, All streams disposed.", args0: _connectionId); } }
/// <summary> /// Disable SSL /// </summary> public override void DisableSsl() { _sslStream.Dispose(); _sslStream = null; _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; _stream = _tcpStream; }
/// <summary> /// Disable SSL /// </summary> public override void DisableSsl() { _sslStream.Dispose(); _sslStream = null; _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; _stream = _tcpStream; SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, SSL Disabled. Communication will continue on TCP Stream.", args0: _connectionId); }
public SNINpHandle(string serverName, string pipeName, long timerExpire, object callbackObject) { _sendSync = new object(); _targetServer = serverName; _callbackObject = callbackObject; try { _pipeStream = new NamedPipeClientStream( serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough); bool isInfiniteTimeOut = long.MaxValue == timerExpire; if (isInfiniteTimeOut) { _pipeStream.Connect(System.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) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, SNICommon.ConnOpenFailedError, te); _status = TdsEnums.SNI_ERROR; return; } catch (IOException ioe) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, SNICommon.ConnOpenFailedError, ioe); _status = TdsEnums.SNI_ERROR; return; } if (!_pipeStream.IsConnected || !_pipeStream.CanWrite || !_pipeStream.CanRead) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, string.Empty); _status = TdsEnums.SNI_ERROR; return; } _sslOverTdsStream = new SslOverTdsStream(_pipeStream); _sslStream = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); _stream = _pipeStream; _status = TdsEnums.SNI_SUCCESS; }
public override void DisableSsl() { _sslStream.Dispose(); _sslStream = null; if (_sslOverTdsStream != null) { _sslOverTdsStream.Dispose(); _sslOverTdsStream = null; } _stream = _pipeStream; }
/// <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> /// <param name="parallel">Parallel executions</param> public SNITCPHandle(string serverName, int port, long timerExpire, object callbackObject, bool parallel) { _callbackObject = callbackObject; _targetServer = serverName; try { TimeSpan ts = default(TimeSpan); // 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 ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, string.Empty); return; } connectTask = ParallelConnectAsync(serverAddresses, port); if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts))) { ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty); return; } _socket = connectTask.Result; } else { _socket = Connect(serverName, port, ts); } if (_socket == null || !_socket.Connected) { if (_socket != null) { _socket.Dispose(); _socket = null; } ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty); return; } _socket.NoDelay = true; _tcpStream = new NetworkStream(_socket, true); _sslOverTdsStream = new SslOverTdsStream(_tcpStream); _sslStream = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); } catch (SocketException se) { ReportTcpSNIError(se); return; } catch (Exception e) { ReportTcpSNIError(e); return; } _stream = _tcpStream; _status = TdsEnums.SNI_SUCCESS; }
public SNINpHandle(string serverName, string pipeName, long timerExpire, object callbackObject) { long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|INFO|SCOPE> Constructor"); SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|INFO> Constructor. server name = {0}, pipe name = {1}", serverName, pipeName); try { _sendSync = new object(); _targetServer = serverName; _callbackObject = callbackObject; try { _pipeStream = new NamedPipeClientStream( serverName, pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough); bool isInfiniteTimeOut = long.MaxValue == timerExpire; if (isInfiniteTimeOut) { _pipeStream.Connect(System.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) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, SNICommon.ConnOpenFailedError, te); _status = TdsEnums.SNI_ERROR; SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|ERR> Timed out. Exception = {0}", te.Message); return; } catch (IOException ioe) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, SNICommon.ConnOpenFailedError, ioe); _status = TdsEnums.SNI_ERROR; SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|ERR> IOException = {0}", ioe.Message); return; } if (!_pipeStream.IsConnected || !_pipeStream.CanWrite || !_pipeStream.CanRead) { SNICommon.ReportSNIError(SNIProviders.NP_PROV, 0, SNICommon.ConnOpenFailedError, string.Empty); _status = TdsEnums.SNI_ERROR; SqlClientEventSource.Log.TrySNITraceEvent("<sc.SNI.SNINpHandle.SNINpHandle |SNI|ERR> Pipe stream is not connected or cannot write or read to/from it."); return; } _sslOverTdsStream = new SslOverTdsStream(_pipeStream); _sslStream = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null); _stream = _pipeStream; _status = TdsEnums.SNI_SUCCESS; } finally { SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); } }
/// <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> /// <param name="parallel">Parallel executions</param> /// <param name="cachedFQDN">Key for DNS Cache</param> /// <param name="pendingDNSInfo">Used for DNS Cache</param> public SNITCPHandle(string serverName, int port, long timerExpire, object callbackObject, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo) { _callbackObject = callbackObject; _targetServer = serverName; _sendSync = new object(); SQLDNSInfo cachedDNSInfo; bool hasCachedDNSInfo = SQLFallbackDNSCache.Instance.GetDNSInfo(cachedFQDN, out cachedDNSInfo); try { TimeSpan ts = default(TimeSpan); // 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; } bool reportError = true; // We will always first try to connect with serverName as before and let the DNS server to resolve the serverName. // If the DSN resolution fails, we will try with IPs in the DNS cache if existed. We try with IPv4 first and followed by IPv6 if // IPv4 fails. The exceptions will be throw to upper level and be handled as before. try { if (parallel) { _socket = TryConnectParallel(serverName, port, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo); } else { _socket = Connect(serverName, port, ts, isInfiniteTimeOut, cachedFQDN, ref pendingDNSInfo); } } catch (Exception ex) { // Retry with cached IP address if (ex is SocketException || ex is ArgumentException || ex is AggregateException) { if (hasCachedDNSInfo == false) { throw; } else { int portRetry = String.IsNullOrEmpty(cachedDNSInfo.Port) ? port : Int32.Parse(cachedDNSInfo.Port); try { if (parallel) { _socket = TryConnectParallel(cachedDNSInfo.AddrIPv4, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo); } else { _socket = Connect(cachedDNSInfo.AddrIPv4, portRetry, ts, isInfiniteTimeOut, cachedFQDN, ref pendingDNSInfo); } } catch (Exception exRetry) { if (exRetry is SocketException || exRetry is ArgumentNullException || exRetry is ArgumentException || exRetry is ArgumentOutOfRangeException || exRetry is AggregateException) { if (parallel) { _socket = TryConnectParallel(cachedDNSInfo.AddrIPv6, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo); } else { _socket = Connect(cachedDNSInfo.AddrIPv6, portRetry, ts, isInfiniteTimeOut, cachedFQDN, ref pendingDNSInfo); } } else { throw; } } } } else { throw; } } if (_socket == null || !_socket.Connected) { if (_socket != null) { _socket.Dispose(); _socket = null; } if (reportError) { ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty); } return; } _socket.NoDelay = true; _tcpStream = new SNINetworkStream(_socket, true); _sslOverTdsStream = new SslOverTdsStream(_tcpStream); _sslStream = new SNISslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate)); } catch (SocketException se) { ReportTcpSNIError(se); return; } catch (Exception e) { ReportTcpSNIError(e); return; } _stream = _tcpStream; _status = TdsEnums.SNI_SUCCESS; }
/// <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="parallel">Parallel executions</param> /// <param name="cachedFQDN">Key for DNS Cache</param> /// <param name="pendingDNSInfo">Used for DNS Cache</param> public SNITCPHandle(string serverName, int port, long timerExpire, bool parallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo) { long scopeID = SqlClientEventSource.Log.TrySNIScopeEnterEvent(s_className); SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, Setting server name = {1}", args0: _connectionId, args1: serverName); try { _targetServer = serverName; _sendSync = new object(); SQLDNSInfo cachedDNSInfo; bool hasCachedDNSInfo = SQLFallbackDNSCache.Instance.GetDNSInfo(cachedFQDN, out cachedDNSInfo); try { TimeSpan ts = default(TimeSpan); // 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; } bool reportError = true; SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, Connecting to serverName {1} and port {2}", args0: _connectionId, args1: serverName, args2: port); // We will always first try to connect with serverName as before and let the DNS server to resolve the serverName. // If the DSN resolution fails, we will try with IPs in the DNS cache if existed. We try with IPv4 first and followed by IPv6 if // IPv4 fails. The exceptions will be throw to upper level and be handled as before. try { if (parallel) { _socket = TryConnectParallel(serverName, port, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo); } else { _socket = Connect(serverName, port, ts, isInfiniteTimeOut, cachedFQDN, ref pendingDNSInfo); } } catch (Exception ex) { // Retry with cached IP address if (ex is SocketException || ex is ArgumentException || ex is AggregateException) { if (hasCachedDNSInfo == false) { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0}, Cached DNS Info not found, exception occurred thrown: {1}", args0: _connectionId, args1: ex?.Message); throw; } else { int portRetry = string.IsNullOrEmpty(cachedDNSInfo.Port) ? port : int.Parse(cachedDNSInfo.Port); SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, Retrying with cached DNS IP Address {1} and port {2}", args0: _connectionId, args1: cachedDNSInfo.AddrIPv4, args2: cachedDNSInfo.Port); try { if (parallel) { _socket = TryConnectParallel(cachedDNSInfo.AddrIPv4, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo); } else { _socket = Connect(cachedDNSInfo.AddrIPv4, portRetry, ts, isInfiniteTimeOut, cachedFQDN, ref pendingDNSInfo); } } catch (Exception exRetry) { if (exRetry is SocketException || exRetry is ArgumentNullException || exRetry is ArgumentException || exRetry is ArgumentOutOfRangeException || exRetry is AggregateException) { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0}, Retrying exception {1}", args0: _connectionId, args1: exRetry?.Message); if (parallel) { _socket = TryConnectParallel(cachedDNSInfo.AddrIPv6, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo); } else { _socket = Connect(cachedDNSInfo.AddrIPv6, portRetry, ts, isInfiniteTimeOut, cachedFQDN, ref pendingDNSInfo); } } else { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0}, Retry failed, exception occurred: {1}", args0: _connectionId, args1: exRetry?.Message); throw; } } } } else { throw; } } if (_socket == null || !_socket.Connected) { if (_socket != null) { _socket.Dispose(); _socket = null; } if (reportError) { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0} could not be opened, exception occurred: {1}", args0: _connectionId, args1: Strings.SNI_ERROR_40); ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, Strings.SNI_ERROR_40); } SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0} Socket could not be opened.", args0: _connectionId); return; } _socket.NoDelay = true; _tcpStream = new SNINetworkStream(_socket, true); _sslOverTdsStream = new SslOverTdsStream(_tcpStream, _connectionId); _sslStream = new SNISslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate)); } catch (SocketException se) { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0} Socket exception occurred: Error Code {1}, Message {2}", args0: _connectionId, args1: se?.SocketErrorCode, args2: se?.Message); ReportTcpSNIError(se); return; } catch (Exception e) { SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "Connection Id {0} Exception occurred: {1}", args0: _connectionId, args1: e?.Message); ReportTcpSNIError(e); return; } _stream = _tcpStream; _status = TdsEnums.SNI_SUCCESS; SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connection Id {0} Socket opened successfully, TCP stream ready.", args0: _connectionId); } finally { SqlClientEventSource.Log.TrySNIScopeLeaveEvent(scopeID); } }