Exemplo n.º 1
0
        // 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);
            }
        }
Exemplo n.º 2
0
 internal static extern uint SNIOpenWrapper(
     [In] ref Sni_Consumer_Info pConsumerInfo,
     [MarshalAs(UnmanagedType.LPWStr)] string szConnect,
     [In] SNIHandle pConn,
     out IntPtr ppConn,
     [MarshalAs(UnmanagedType.Bool)] bool fSync,
     SqlConnectionIPAddressPreference ipPreference,
     [In] ref SNI_DNSCache_Info pDNSCachedInfo);
Exemplo n.º 3
0
        public void SetInvalidIPAddressPreference_Throws()
        {
            SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();

            SqlConnectionIPAddressPreference invalid = (SqlConnectionIPAddressPreference)Enum.GetValues(typeof(SqlConnectionIPAddressPreference)).Length + 1;
            ArgumentOutOfRangeException      ex      = Assert.Throws <ArgumentOutOfRangeException>(() => builder.IPAddressPreference = invalid);

            Assert.Contains("SqlConnectionIPAddressPreference", ex.Message, StringComparison.OrdinalIgnoreCase);
        }
Exemplo n.º 4
0
 private static uint SNIOpenWrapper(
     [In] ref Sni_Consumer_Info pConsumerInfo,
     [MarshalAs(UnmanagedType.LPWStr)] string szConnect,
     [In] SNIHandle pConn,
     out IntPtr ppConn,
     [MarshalAs(UnmanagedType.Bool)] bool fSync,
     SqlConnectionIPAddressPreference ipPreference,
     [In] ref SNI_DNSCache_Info pDNSCachedInfo)
 {
     return(s_is64bitProcess ?
            SNINativeManagedWrapperX64.SNIOpenWrapper(ref pConsumerInfo, szConnect, pConn, out ppConn, fSync, ipPreference, ref pDNSCachedInfo) :
            SNINativeManagedWrapperX86.SNIOpenWrapper(ref pConsumerInfo, szConnect, pConn, out ppConn, fSync, ipPreference, ref pDNSCachedInfo));
 }
 internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[][] spnBuffer, bool flushCache, bool async, bool parallel,
                                                SqlConnectionIPAddressPreference iPAddressPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo, bool isIntegratedSecurity)
 {
     _sessionHandle = SNIProxy.CreateConnectionHandle(serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, flushCache, async, parallel, isIntegratedSecurity,
                                                      iPAddressPreference, cachedFQDN, ref pendingDNSInfo);
     if (_sessionHandle == null)
     {
         _parser.ProcessSNIError(this);
     }
     else
     {
         SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObjectManaged.CreatePhysicalSNIHandle | Info | State Object Id {0}, Session Id {1}, ServerName {2}, Async = {3}", _objectID, _sessionHandle?.ConnectionId, serverName, async);
         if (async)
         {
             // Create call backs and allocate to the session handle
             _sessionHandle.SetAsyncCallbacks(ReadAsyncCallback, WriteAsyncCallback);
         }
     }
 }
Exemplo n.º 6
0
        internal override void CreatePhysicalSNIHandle(string serverName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[][] spnBuffer, bool flushCache, bool async, bool fParallel,
                                                       SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo, bool isIntegratedSecurity)
        {
            // We assume that the loadSSPILibrary has been called already. now allocate proper length of buffer
            spnBuffer = new byte[1][];
            if (isIntegratedSecurity)
            {
                // now allocate proper length of buffer
                spnBuffer[0] = 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[0], ignoreSniOpenTimeout, checked ((int)timeout), out instanceName, flushCache, !async, fParallel, ipPreference, cachedDNSInfo);
        }
        // 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);
            }
        }
Exemplo n.º 8
0
        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));
                }
            }
        }
Exemplo n.º 9
0
        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);
     }
 }
Exemplo n.º 11
0
        /// <summary>
        /// Creates an SNITCPHandle object
        /// </summary>
        /// <param name="details">Data source</param>
        /// <param name="timerExpire">Timer expiration</param>
        /// <param name="parallel">Should MultiSubnetFailover be used</param>
        /// <param name="ipPreference">IP address preference</param>
        /// <param name="cachedFQDN">Key for DNS Cache</param>
        /// <param name="pendingDNSInfo">Used for DNS Cache</param>
        /// <returns>SNITCPHandle</returns>
        private static SNITCPHandle CreateTcpHandle(DataSource details, long timerExpire, bool parallel, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
        {
            // TCP Format:
            // tcp:<host name>\<instance name>
            // tcp:<host name>,<TCP/IP port number>

            string hostName = details.ServerName;

            if (string.IsNullOrWhiteSpace(hostName))
            {
                SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, 0, SNICommon.InvalidConnStringError, Strings.SNI_ERROR_25);
                return(null);
            }

            int  port = -1;
            bool isAdminConnection = details._connectionProtocol == DataSource.Protocol.Admin;

            if (details.IsSsrpRequired)
            {
                try
                {
                    port = isAdminConnection ?
                           SSRP.GetDacPortByInstanceName(hostName, details.InstanceName) :
                           SSRP.GetPortByInstanceName(hostName, details.InstanceName);
                }
                catch (SocketException se)
                {
                    SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.TCP_PROV, SNICommon.InvalidConnStringError, se);
                    return(null);
                }
            }
            else if (details.Port != -1)
            {
                port = details.Port;
            }
            else
            {
                port = isAdminConnection ? DefaultSqlServerDacPort : DefaultSqlServerPort;
            }

            return(new SNITCPHandle(hostName, port, timerExpire, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo));
        }
Exemplo n.º 12
0
        /// <summary>
        /// Create a SNI connection handle
        /// </summary>
        /// <param name="fullServerName">Full server name from connection string</param>
        /// <param name="ignoreSniOpenTimeout">Ignore open timeout</param>
        /// <param name="timerExpire">Timer expiration</param>
        /// <param name="instanceName">Instance name</param>
        /// <param name="spnBuffer">SPN</param>
        /// <param name="flushCache">Flush packet cache</param>
        /// <param name="async">Asynchronous connection</param>
        /// <param name="parallel">Attempt parallel connects</param>
        /// <param name="isIntegratedSecurity"></param>
        /// <param name="ipPreference">IP address preference</param>
        /// <param name="cachedFQDN">Used for DNS Cache</param>
        /// <param name="pendingDNSInfo">Used for DNS Cache</param>
        /// <returns>SNI handle</returns>
        internal static SNIHandle CreateConnectionHandle(string fullServerName, bool ignoreSniOpenTimeout, long timerExpire, out byte[] instanceName, ref byte[][] spnBuffer,
                                                         bool flushCache, bool async, bool parallel, bool isIntegratedSecurity, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
        {
            instanceName = new byte[1];

            bool   errorWithLocalDBProcessing;
            string localDBDataSource = GetLocalDBDataSource(fullServerName, out errorWithLocalDBProcessing);

            if (errorWithLocalDBProcessing)
            {
                return(null);
            }

            // If a localDB Data source is available, we need to use it.
            fullServerName = localDBDataSource ?? fullServerName;

            DataSource details = DataSource.ParseServerName(fullServerName);

            if (details == null)
            {
                return(null);
            }

            SNIHandle sniHandle = null;

            switch (details._connectionProtocol)
            {
            case DataSource.Protocol.Admin:
            case DataSource.Protocol.None:     // default to using tcp if no protocol is provided
            case DataSource.Protocol.TCP:
                sniHandle = CreateTcpHandle(details, timerExpire, parallel, ipPreference, cachedFQDN, ref pendingDNSInfo);
                break;

            case DataSource.Protocol.NP:
                sniHandle = CreateNpHandle(details, timerExpire, parallel);
                break;

            default:
                Debug.Fail($"Unexpected connection protocol: {details._connectionProtocol}");
                break;
            }

            if (isIntegratedSecurity)
            {
                try
                {
                    spnBuffer = GetSqlServerSPNs(details);
                }
                catch (Exception e)
                {
                    SNILoadHandle.SingletonInstance.LastError = new SNIError(SNIProviders.INVALID_PROV, SNICommon.ErrorSpnLookup, e);
                }
            }

            SqlClientEventSource.Log.TryTraceEvent("SNIProxy.CreateConnectionHandle | Info | Session Id {0}, SNI Handle Type: {1}", sniHandle?.ConnectionId, sniHandle?.GetType());
            return(sniHandle);
        }
Exemplo n.º 13
0
        private readonly string _expandedAttachDBFilename; // expanded during construction so that CreatePermissionSet & Expand are consistent

        internal SqlConnectionString(string connectionString) : base(connectionString, GetParseSynonyms())
        {
            ThrowUnsupportedIfKeywordSet(KEY.Connection_Reset);
            ThrowUnsupportedIfKeywordSet(KEY.Context_Connection);

            // Network Library has its own special error message
            if (ContainsKey(KEY.Network_Library))
            {
                throw SQL.NetworkLibraryKeywordNotSupported();
            }

            _integratedSecurity = ConvertValueToIntegratedSecurity();
            _poolBlockingPeriod = ConvertValueToPoolBlockingPeriod();
            _encrypt            = ConvertValueToBoolean(KEY.Encrypt, DEFAULT.Encrypt);
            _enlist             = ConvertValueToBoolean(KEY.Enlist, DEFAULT.Enlist);
            _mars = ConvertValueToBoolean(KEY.MARS, DEFAULT.MARS);
            _persistSecurityInfo = ConvertValueToBoolean(KEY.Persist_Security_Info, DEFAULT.Persist_Security_Info);
            _pooling             = ConvertValueToBoolean(KEY.Pooling, DEFAULT.Pooling);
            _replication         = ConvertValueToBoolean(KEY.Replication, DEFAULT.Replication);
            _userInstance        = ConvertValueToBoolean(KEY.User_Instance, DEFAULT.User_Instance);
            _multiSubnetFailover = ConvertValueToBoolean(KEY.MultiSubnetFailover, DEFAULT.MultiSubnetFailover);

            _commandTimeout       = ConvertValueToInt32(KEY.Command_Timeout, DEFAULT.Command_Timeout);
            _connectTimeout       = ConvertValueToInt32(KEY.Connect_Timeout, DEFAULT.Connect_Timeout);
            _loadBalanceTimeout   = ConvertValueToInt32(KEY.Load_Balance_Timeout, DEFAULT.Load_Balance_Timeout);
            _maxPoolSize          = ConvertValueToInt32(KEY.Max_Pool_Size, DEFAULT.Max_Pool_Size);
            _minPoolSize          = ConvertValueToInt32(KEY.Min_Pool_Size, DEFAULT.Min_Pool_Size);
            _packetSize           = ConvertValueToInt32(KEY.Packet_Size, DEFAULT.Packet_Size);
            _connectRetryCount    = ConvertValueToInt32(KEY.Connect_Retry_Count, DEFAULT.Connect_Retry_Count);
            _connectRetryInterval = ConvertValueToInt32(KEY.Connect_Retry_Interval, DEFAULT.Connect_Retry_Interval);

            _applicationIntent       = ConvertValueToApplicationIntent();
            _applicationName         = ConvertValueToString(KEY.Application_Name, DEFAULT.Application_Name);
            _attachDBFileName        = ConvertValueToString(KEY.AttachDBFilename, DEFAULT.AttachDBFilename);
            _currentLanguage         = ConvertValueToString(KEY.Current_Language, DEFAULT.Current_Language);
            _dataSource              = ConvertValueToString(KEY.Data_Source, DEFAULT.Data_Source);
            _localDBInstance         = LocalDBAPI.GetLocalDbInstanceNameFromServerName(_dataSource);
            _failoverPartner         = ConvertValueToString(KEY.FailoverPartner, DEFAULT.FailoverPartner);
            _initialCatalog          = ConvertValueToString(KEY.Initial_Catalog, DEFAULT.Initial_Catalog);
            _password                = ConvertValueToString(KEY.Password, DEFAULT.Password);
            _trustServerCertificate  = ConvertValueToBoolean(KEY.TrustServerCertificate, DEFAULT.TrustServerCertificate);
            _authType                = ConvertValueToAuthenticationType();
            _columnEncryptionSetting = ConvertValueToColumnEncryptionSetting();
            _enclaveAttestationUrl   = ConvertValueToString(KEY.EnclaveAttestationUrl, DEFAULT.EnclaveAttestationUrl);
            _attestationProtocol     = ConvertValueToAttestationProtocol();
            _ipAddressPreference     = ConvertValueToIPAddressPreference();

            // Temporary string - this value is stored internally as an enum.
            string typeSystemVersionString  = ConvertValueToString(KEY.Type_System_Version, null);
            string transactionBindingString = ConvertValueToString(KEY.TransactionBinding, null);

            _userID        = ConvertValueToString(KEY.User_ID, DEFAULT.User_ID);
            _workstationId = ConvertValueToString(KEY.Workstation_Id, null);

            if (_loadBalanceTimeout < 0)
            {
                throw ADP.InvalidConnectionOptionValue(KEY.Load_Balance_Timeout);
            }

            if (_connectTimeout < 0)
            {
                throw ADP.InvalidConnectionOptionValue(KEY.Connect_Timeout);
            }

            if (_commandTimeout < 0)
            {
                throw ADP.InvalidConnectionOptionValue(KEY.Command_Timeout);
            }

            if (_maxPoolSize < 1)
            {
                throw ADP.InvalidConnectionOptionValue(KEY.Max_Pool_Size);
            }

            if (_minPoolSize < 0)
            {
                throw ADP.InvalidConnectionOptionValue(KEY.Min_Pool_Size);
            }
            if (_maxPoolSize < _minPoolSize)
            {
                throw ADP.InvalidMinMaxPoolSizeValues();
            }

            if ((_packetSize < TdsEnums.MIN_PACKET_SIZE) || (TdsEnums.MAX_PACKET_SIZE < _packetSize))
            {
                throw SQL.InvalidPacketSizeValue();
            }

            ValidateValueLength(_applicationName, TdsEnums.MAXLEN_APPNAME, KEY.Application_Name);
            ValidateValueLength(_currentLanguage, TdsEnums.MAXLEN_LANGUAGE, KEY.Current_Language);
            ValidateValueLength(_dataSource, TdsEnums.MAXLEN_SERVERNAME, KEY.Data_Source);
            ValidateValueLength(_failoverPartner, TdsEnums.MAXLEN_SERVERNAME, KEY.FailoverPartner);
            ValidateValueLength(_initialCatalog, TdsEnums.MAXLEN_DATABASE, KEY.Initial_Catalog);
            ValidateValueLength(_password, TdsEnums.MAXLEN_CLIENTSECRET, KEY.Password);
            ValidateValueLength(_userID, TdsEnums.MAXLEN_CLIENTID, KEY.User_ID);
            if (null != _workstationId)
            {
                ValidateValueLength(_workstationId, TdsEnums.MAXLEN_HOSTNAME, KEY.Workstation_Id);
            }

            if (!string.Equals(DEFAULT.FailoverPartner, _failoverPartner, StringComparison.OrdinalIgnoreCase))
            {
                // fail-over partner is set

                if (_multiSubnetFailover)
                {
                    throw SQL.MultiSubnetFailoverWithFailoverPartner(serverProvidedFailoverPartner: false, internalConnection: null);
                }

                if (string.Equals(DEFAULT.Initial_Catalog, _initialCatalog, StringComparison.OrdinalIgnoreCase))
                {
                    throw ADP.MissingConnectionOptionValue(KEY.FailoverPartner, KEY.Initial_Catalog);
                }
            }

            // expand during construction so that CreatePermissionSet and Expand are consistent
            _expandedAttachDBFilename = ExpandDataDirectory(KEY.AttachDBFilename, _attachDBFileName);
            if (null != _expandedAttachDBFilename)
            {
                if (0 <= _expandedAttachDBFilename.IndexOf('|'))
                {
                    throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename);
                }
                ValidateValueLength(_expandedAttachDBFilename, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename);
                if (_localDBInstance == null)
                {
                    // fail fast to verify LocalHost when using |DataDirectory|
                    // still must check again at connect time
                    string host = _dataSource;
                    VerifyLocalHostAndFixup(ref host, true, false /*don't fix-up*/);
                }
            }
            else if (0 <= _attachDBFileName.IndexOf('|'))
            {
                throw ADP.InvalidConnectionOptionValue(KEY.AttachDBFilename);
            }
            else
            {
                ValidateValueLength(_attachDBFileName, TdsEnums.MAXLEN_ATTACHDBFILE, KEY.AttachDBFilename);
            }
            _typeSystemAssemblyVersion = constTypeSystemAsmVersion10;

            if (true == _userInstance && !string.IsNullOrEmpty(_failoverPartner))
            {
                throw SQL.UserInstanceFailoverNotCompatible();
            }

            if (string.IsNullOrEmpty(typeSystemVersionString))
            {
                typeSystemVersionString = DbConnectionStringDefaults.TypeSystemVersion;
            }

            if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.Latest, StringComparison.OrdinalIgnoreCase))
            {
                _typeSystemVersion = TypeSystem.Latest;
            }
            else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2000, StringComparison.OrdinalIgnoreCase))
            {
                _typeSystemVersion = TypeSystem.SQLServer2000;
            }
            else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2005, StringComparison.OrdinalIgnoreCase))
            {
                _typeSystemVersion = TypeSystem.SQLServer2005;
            }
            else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2008, StringComparison.OrdinalIgnoreCase))
            {
                _typeSystemVersion = TypeSystem.SQLServer2008;
            }
            else if (typeSystemVersionString.Equals(TYPESYSTEMVERSION.SQL_Server_2012, StringComparison.OrdinalIgnoreCase))
            {
                _typeSystemVersion         = TypeSystem.SQLServer2012;
                _typeSystemAssemblyVersion = constTypeSystemAsmVersion11;
            }
            else
            {
                throw ADP.InvalidConnectionOptionValue(KEY.Type_System_Version);
            }

            if (string.IsNullOrEmpty(transactionBindingString))
            {
                transactionBindingString = DbConnectionStringDefaults.TransactionBinding;
            }

            if (transactionBindingString.Equals(TRANSACTIONBINDING.ImplicitUnbind, StringComparison.OrdinalIgnoreCase))
            {
                _transactionBinding = TransactionBindingEnum.ImplicitUnbind;
            }
            else if (transactionBindingString.Equals(TRANSACTIONBINDING.ExplicitUnbind, StringComparison.OrdinalIgnoreCase))
            {
                _transactionBinding = TransactionBindingEnum.ExplicitUnbind;
            }
            else
            {
                throw ADP.InvalidConnectionOptionValue(KEY.TransactionBinding);
            }

            if (_applicationIntent == ApplicationIntent.ReadOnly && !string.IsNullOrEmpty(_failoverPartner))
            {
                throw SQL.ROR_FailoverNotSupportedConnString();
            }

            if ((_connectRetryCount < 0) || (_connectRetryCount > 255))
            {
                throw ADP.InvalidConnectRetryCountValue();
            }

            if ((_connectRetryInterval < 1) || (_connectRetryInterval > 60))
            {
                throw ADP.InvalidConnectRetryIntervalValue();
            }

            if (Authentication != SqlAuthenticationMethod.NotSpecified && _integratedSecurity == true)
            {
                throw SQL.AuthenticationAndIntegratedSecurity();
            }

            if (Authentication == SqlClient.SqlAuthenticationMethod.ActiveDirectoryIntegrated && HasPasswordKeyword)
            {
                throw SQL.IntegratedWithPassword();
            }

            if (Authentication == SqlAuthenticationMethod.ActiveDirectoryInteractive && HasPasswordKeyword)
            {
                throw SQL.InteractiveWithPassword();
            }

            if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDeviceCodeFlow && (HasUserIdKeyword || HasPasswordKeyword))
            {
                throw SQL.DeviceFlowWithUsernamePassword();
            }

            if (Authentication == SqlAuthenticationMethod.ActiveDirectoryManagedIdentity && HasPasswordKeyword)
            {
                throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryManagedIdentityString);
            }

            if (Authentication == SqlAuthenticationMethod.ActiveDirectoryMSI && HasPasswordKeyword)
            {
                throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryMSIString);
            }

            if (Authentication == SqlAuthenticationMethod.ActiveDirectoryDefault && HasPasswordKeyword)
            {
                throw SQL.NonInteractiveWithPassword(DbConnectionStringBuilderUtil.ActiveDirectoryDefaultString);
            }
        }
Exemplo n.º 14
0
        // Connect to server with hostName and port.
        // The IP information will be collected temporarily as the pendingDNSInfo but is not stored in the DNS cache at this point.
        // Only write to the DNS cache when we receive IsSupported flag as true in the Feature Ext Ack from server.
        private static Socket Connect(string serverName, int port, TimeSpan timeout, bool isInfiniteTimeout, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
        {
            SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "IP preference : {0}", Enum.GetName(typeof(SqlConnectionIPAddressPreference), ipPreference));

            IPAddress[] ipAddresses = Dns.GetHostAddresses(serverName);

            string IPv4String = null;
            string IPv6String = null;

            // Returning null socket is handled by the caller function.
            if (ipAddresses == null || ipAddresses.Length == 0)
            {
                return(null);
            }

            Socket[]        sockets            = new Socket[ipAddresses.Length];
            AddressFamily[] preferedIPFamilies = new AddressFamily[2];

            if (ipPreference == SqlConnectionIPAddressPreference.IPv4First)
            {
                preferedIPFamilies[0] = AddressFamily.InterNetwork;
                preferedIPFamilies[1] = AddressFamily.InterNetworkV6;
            }
            else if (ipPreference == SqlConnectionIPAddressPreference.IPv6First)
            {
                preferedIPFamilies[0] = AddressFamily.InterNetworkV6;
                preferedIPFamilies[1] = AddressFamily.InterNetwork;
            }
            // else -> UsePlatformDefault

            CancellationTokenSource cts = null;

            if (!isInfiniteTimeout)
            {
                cts = new CancellationTokenSource(timeout);
                cts.Token.Register(Cancel);
            }

            Socket availableSocket = null;

            try
            {
                // We go through the IP list twice.
                // In the first traversal, we only try to connect with the preferedIPFamilies[0].
                // In the second traversal, we only try to connect with the preferedIPFamilies[1].
                // For UsePlatformDefault preference, we do traversal once.
                for (int i = 0; i < preferedIPFamilies.Length; ++i)
                {
                    for (int n = 0; n < ipAddresses.Length; n++)
                    {
                        IPAddress ipAddress = ipAddresses[n];
                        try
                        {
                            if (ipAddress != null)
                            {
                                if (ipAddress.AddressFamily != preferedIPFamilies[i] && ipPreference != SqlConnectionIPAddressPreference.UsePlatformDefault)
                                {
                                    continue;
                                }

                                sockets[n] = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

                                // enable keep-alive on socket
                                SetKeepAliveValues(ref sockets[n]);

                                SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "Connecting to IP address {0} and port {1} using {2} address family.",
                                                                          args0: ipAddress,
                                                                          args1: port,
                                                                          args2: ipAddress.AddressFamily);
                                sockets[n].Connect(ipAddress, port);
                                if (sockets[n] != null) // sockets[n] can be null if cancel callback is executed during connect()
                                {
                                    if (sockets[n].Connected)
                                    {
                                        availableSocket = sockets[n];
                                        if (ipAddress.AddressFamily == AddressFamily.InterNetwork)
                                        {
                                            IPv4String = ipAddress.ToString();
                                        }
                                        else if (ipAddress.AddressFamily == AddressFamily.InterNetworkV6)
                                        {
                                            IPv6String = ipAddress.ToString();
                                        }

                                        break;
                                    }
                                    else
                                    {
                                        sockets[n].Dispose();
                                        sockets[n] = null;
                                    }
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "THIS EXCEPTION IS BEING SWALLOWED: {0}", args0: e?.Message);
                            SqlClientEventSource.Log.TryAdvancedTraceEvent($"{s_className}.{System.Reflection.MethodBase.GetCurrentMethod().Name}{EventType.ERR}THIS EXCEPTION IS BEING SWALLOWED: {e}");
                        }
                    }

                    // If we have already got a valid Socket, or the platform default was prefered
                    // we won't do the second traversal.
                    if (availableSocket is not null || ipPreference == SqlConnectionIPAddressPreference.UsePlatformDefault)
                    {
                        break;
                    }
                }
            }
            finally
            {
                cts?.Dispose();
            }

            // we only record the ip we can connect with successfully.
            if (IPv4String != null || IPv6String != null)
            {
                pendingDNSInfo = new SQLDNSInfo(cachedFQDN, IPv4String, IPv6String, port.ToString());
            }

            return(availableSocket);

            void Cancel()
            {
                for (int i = 0; i < sockets.Length; ++i)
                {
                    try
                    {
                        if (sockets[i] != null && !sockets[i].Connected)
                        {
                            sockets[i].Dispose();
                            sockets[i] = null;
                        }
                    }
                    catch (Exception e)
                    {
                        SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.ERR, "THIS EXCEPTION IS BEING SWALLOWED: {0}", args0: e?.Message);
                    }
                }
            }
        }
Exemplo n.º 15
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="parallel">Parallel executions</param>
        /// <param name="ipPreference">IP address preference</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, SqlConnectionIPAddressPreference ipPreference, 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 cached IPs based on IPAddressPreference.
                    // 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, ipPreference, 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);

                                string firstCachedIP;
                                string secondCachedIP;

                                if (SqlConnectionIPAddressPreference.IPv6First == ipPreference)
                                {
                                    firstCachedIP  = cachedDNSInfo.AddrIPv6;
                                    secondCachedIP = cachedDNSInfo.AddrIPv4;
                                }
                                else
                                {
                                    firstCachedIP  = cachedDNSInfo.AddrIPv4;
                                    secondCachedIP = cachedDNSInfo.AddrIPv6;
                                }

                                try
                                {
                                    if (parallel)
                                    {
                                        _socket = TryConnectParallel(firstCachedIP, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo);
                                    }
                                    else
                                    {
                                        _socket = Connect(firstCachedIP, portRetry, ts, isInfiniteTimeOut, ipPreference, 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(secondCachedIP, portRetry, ts, isInfiniteTimeOut, ref reportError, cachedFQDN, ref pendingDNSInfo);
                                        }
                                        else
                                        {
                                            _socket = Connect(secondCachedIP, portRetry, ts, isInfiniteTimeOut, ipPreference, 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);
            }
        }