// creates a physical connection internal SNIHandle( SNINativeMethodWrapper.ConsumerInfo myInfo, string serverName, byte[] spnBuffer, bool ignoreSniOpenTimeout, int timeout, out byte[] instanceName, bool flushCache, bool fSync, bool fParallel, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true) { try { } finally { _fSync = fSync; instanceName = new byte[256]; // Size as specified by netlibs. if (ignoreSniOpenTimeout) { timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE } _status = SNINativeMethodWrapper.SNIOpenSyncEx(myInfo, serverName, ref base.handle, spnBuffer, instanceName, flushCache, fSync, timeout, fParallel, ipPreference, cachedDNSInfo); } }
internal override void AssignPendingDNSInfo(string userProtocol, string DNSCacheKey, ref SQLDNSInfo pendingDNSInfo) { uint result; ushort portFromSNI = 0; string IPStringFromSNI = string.Empty; IPAddress IPFromSNI; _parser.isTcpProtocol = false; SNINativeMethodWrapper.ProviderEnum providerNumber = SNINativeMethodWrapper.ProviderEnum.INVALID_PROV; if (string.IsNullOrEmpty(userProtocol)) { result = SNINativeMethodWrapper.SniGetProviderNumber(Handle, ref providerNumber); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetProviderNumber"); _parser.isTcpProtocol = (providerNumber == SNINativeMethodWrapper.ProviderEnum.TCP_PROV); } else if (userProtocol == TdsEnums.TCP) { _parser.isTcpProtocol = true; } // serverInfo.UserProtocol could be empty if (_parser.isTcpProtocol) { result = SNINativeMethodWrapper.SniGetConnectionPort(Handle, ref portFromSNI); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionPort"); result = SNINativeMethodWrapper.SniGetConnectionIPString(Handle, ref IPStringFromSNI); Debug.Assert(result == TdsEnums.SNI_SUCCESS, "Unexpected failure state upon calling SniGetConnectionIPString"); pendingDNSInfo = new SQLDNSInfo(DNSCacheKey, null, null, portFromSNI.ToString()); if (IPAddress.TryParse(IPStringFromSNI, out IPFromSNI)) { if (System.Net.Sockets.AddressFamily.InterNetwork == IPFromSNI.AddressFamily) { pendingDNSInfo.AddrIPv4 = IPStringFromSNI; } else if (System.Net.Sockets.AddressFamily.InterNetworkV6 == IPFromSNI.AddressFamily) { pendingDNSInfo.AddrIPv6 = IPStringFromSNI; } } } else { pendingDNSInfo = null; } }
internal bool AddDNSInfo(SQLDNSInfo item) { if (null != item) { if (DNSInfoCache.ContainsKey(item.FQDN)) { DeleteDNSInfo(item.FQDN); } return(DNSInfoCache.TryAdd(item.FQDN, item)); } return(false); }
internal bool IsDuplicate(SQLDNSInfo newItem) { if (null != newItem) { SQLDNSInfo oldItem; if (GetDNSInfo(newItem.FQDN, out oldItem)) { return(newItem.AddrIPv4 == oldItem.AddrIPv4 && newItem.AddrIPv6 == oldItem.AddrIPv6 && newItem.Port == oldItem.Port); } } return(false); }
// creates a physical connection internal SNIHandle( SNINativeMethodWrapper.ConsumerInfo myInfo, string serverName, byte[] spnBuffer, bool ignoreSniOpenTimeout, int timeout, out byte[] instanceName, bool flushCache, bool fSync, bool fParallel, TransparentNetworkResolutionState transparentNetworkResolutionState, int totalTimeout, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true) { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { _fSync = fSync; instanceName = new byte[256]; // Size as specified by netlibs. if (ignoreSniOpenTimeout) { // UNDONE: ITEM12001110 (DB Mirroring Reconnect) Old behavior of not truly honoring timeout presevered // for non-failover scenarios to avoid breaking changes as part of a QFE. Consider fixing timeout // handling in next full release and removing ignoreSniOpenTimeout parameter. timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE } int transparentNetworkResolutionStateNo = (int)transparentNetworkResolutionState; _status = SNINativeMethodWrapper.SNIOpenSyncEx(myInfo, serverName, ref base.handle, spnBuffer, instanceName, flushCache, fSync, timeout, fParallel, transparentNetworkResolutionStateNo, totalTimeout, ADP.IsAzureSqlServerEndpoint(serverName), ipPreference, cachedDNSInfo); } }
internal static unsafe uint SNIOpenSyncEx(ConsumerInfo consumerInfo, string constring, ref IntPtr pConn, byte[] spnBuffer, byte[] instanceName, bool fOverrideCache, bool fSync, int timeout, bool fParallel, Int32 transparentNetworkResolutionStateNo, Int32 totalTimeout, Boolean isAzureSqlServerEndpoint, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) { fixed(byte *pin_instanceName = &instanceName[0]) { SNI_CLIENT_CONSUMER_INFO clientConsumerInfo = new SNI_CLIENT_CONSUMER_INFO(); // initialize client ConsumerInfo part first MarshalConsumerInfo(consumerInfo, ref clientConsumerInfo.ConsumerInfo); clientConsumerInfo.wszConnectionString = constring; clientConsumerInfo.networkLibrary = PrefixEnum.UNKNOWN_PREFIX; clientConsumerInfo.szInstanceName = pin_instanceName; clientConsumerInfo.cchInstanceName = (uint)instanceName.Length; clientConsumerInfo.fOverrideLastConnectCache = fOverrideCache; clientConsumerInfo.fSynchronousConnection = fSync; clientConsumerInfo.timeout = timeout; clientConsumerInfo.fParallel = fParallel; clientConsumerInfo.isAzureSqlServerEndpoint = ADP.IsAzureSqlServerEndpoint(constring); switch (transparentNetworkResolutionStateNo) { case (0): clientConsumerInfo.transparentNetworkResolution = TransparentNetworkResolutionMode.DisabledMode; break; case (1): clientConsumerInfo.transparentNetworkResolution = TransparentNetworkResolutionMode.SequentialMode; break; case (2): clientConsumerInfo.transparentNetworkResolution = TransparentNetworkResolutionMode.ParallelMode; break; } ; clientConsumerInfo.totalTimeout = totalTimeout; clientConsumerInfo.ipAddressPreference = ipPreference; clientConsumerInfo.DNSCacheInfo.wszCachedFQDN = cachedDNSInfo?.FQDN; clientConsumerInfo.DNSCacheInfo.wszCachedTcpIPv4 = cachedDNSInfo?.AddrIPv4; clientConsumerInfo.DNSCacheInfo.wszCachedTcpIPv6 = cachedDNSInfo?.AddrIPv6; clientConsumerInfo.DNSCacheInfo.wszCachedTcpPort = cachedDNSInfo?.Port; if (spnBuffer != null) { fixed(byte *pin_spnBuffer = &spnBuffer[0]) { clientConsumerInfo.szSPN = pin_spnBuffer; clientConsumerInfo.cchSPN = (uint)spnBuffer.Length; return(SNIOpenSyncExWrapper(ref clientConsumerInfo, out pConn)); } } else { // else leave szSPN null (SQL Auth) return(SNIOpenSyncExWrapper(ref clientConsumerInfo, out pConn)); } } }
internal static unsafe uint SNIOpenMarsSession(ConsumerInfo consumerInfo, SNIHandle parent, ref IntPtr pConn, bool fSync, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) { // initialize consumer info for MARS Sni_Consumer_Info native_consumerInfo = new Sni_Consumer_Info(); MarshalConsumerInfo(consumerInfo, ref native_consumerInfo); SNI_DNSCache_Info native_cachedDNSInfo = new SNI_DNSCache_Info(); native_cachedDNSInfo.wszCachedFQDN = cachedDNSInfo?.FQDN; native_cachedDNSInfo.wszCachedTcpIPv4 = cachedDNSInfo?.AddrIPv4; native_cachedDNSInfo.wszCachedTcpIPv6 = cachedDNSInfo?.AddrIPv6; native_cachedDNSInfo.wszCachedTcpPort = cachedDNSInfo?.Port; return(SNIOpenWrapper(ref native_consumerInfo, "session:", parent, out pConn, fSync, ipPreference, ref native_cachedDNSInfo)); }
// constructs SNI Handle for MARS session internal SNIHandle(SNINativeMethodWrapper.ConsumerInfo myInfo, SNIHandle parent, SqlConnectionIPAddressPreference ipPreference, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true) { RuntimeHelpers.PrepareConstrainedRegions(); try { } finally { _status = SNINativeMethodWrapper.SNIOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync, ipPreference, cachedDNSInfo); } }
internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[] spnBuffer, bool flushCache, bool async, bool fParallel, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo, bool isIntegratedSecurity) { // We assume that the loadSSPILibrary has been called already. now allocate proper length of buffer spnBuffer = null; if (isIntegratedSecurity) { // now allocate proper length of buffer spnBuffer = new byte[SNINativeMethodWrapper.SniMaxComposedSpnLength]; } SNINativeMethodWrapper.ConsumerInfo myInfo = CreateConsumerInfo(async); // Translate to SNI timeout values (Int32 milliseconds) long timeout; if (long.MaxValue == timerExpire) { timeout = int.MaxValue; } else { timeout = ADP.TimerRemainingMilliseconds(timerExpire); if (timeout > int.MaxValue) { timeout = int.MaxValue; } else if (0 > timeout) { timeout = 0; } } SQLDNSInfo cachedDNSInfo; bool ret = SQLFallbackDNSCache.Instance.GetDNSInfo(cachedFQDN, out cachedDNSInfo); _sessionHandle = new SNIHandle(myInfo, serverName, spnBuffer, ignoreSniOpenTimeout, checked ((int)timeout), out instanceName, flushCache, !async, fParallel, cachedDNSInfo); }
internal bool GetDNSInfo(string FQDN, out SQLDNSInfo result) { return(DNSInfoCache.TryGetValue(FQDN, out result)); }
// constructs SNI Handle for MARS session internal SNIHandle(SNINativeMethodWrapper.ConsumerInfo myInfo, SNIHandle parent, SQLDNSInfo cachedDNSInfo) : base(IntPtr.Zero, true) { try { } finally { _status = SNINativeMethodWrapper.SNIOpenMarsSession(myInfo, parent, ref base.handle, parent._fSync, cachedDNSInfo); } }