From 68f19d4bc094bae0e05ebe7b267c785f8f09f5c4 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 10:53:15 -0700 Subject: [PATCH 01/11] Enable use of Managed SNI on Windows, with optional Environment Variable. --- .../Data/SqlClient/TdsParserStateObjectFactory.Windows.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs index 2e145c4bd8..f859f01299 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs @@ -14,20 +14,15 @@ internal sealed class TdsParserStateObjectFactory public static readonly TdsParserStateObjectFactory Singleton = new TdsParserStateObjectFactory(); - // Temporary disabling App Context switching for managed SNI. // If the appcontext switch is set then Use Managed SNI based on the value. Otherwise Managed SNI should always be used. //private static bool shouldUseLegacyNetorking; //public static bool UseManagedSNI { get; } = AppContext.TryGetSwitch(UseLegacyNetworkingOnWindows, out shouldUseLegacyNetorking) ? !shouldUseLegacyNetorking : true; -#if DEBUG private static Lazy useManagedSNIOnWindows = new Lazy( () => bool.TrueString.Equals(Environment.GetEnvironmentVariable("Microsoft.Data.SqlClient.UseManagedSNIOnWindows"), StringComparison.InvariantCultureIgnoreCase) ); public static bool UseManagedSNI => useManagedSNIOnWindows.Value; -#else - public static bool UseManagedSNI { get; } = false; -#endif public EncryptionOptions EncryptionOptions { From cfc547ca599ecdcc0394b723cb0c66e8eb2ab615 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 11:24:19 -0700 Subject: [PATCH 02/11] Support for Azure Pipelines --- .../TdsParserStateObjectFactory.Windows.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs index f859f01299..bd6daa8b0f 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs @@ -9,18 +9,17 @@ namespace Microsoft.Data.SqlClient { internal sealed class TdsParserStateObjectFactory { - - private const string UseLegacyNetworkingOnWindows = "Microsoft.Data.SqlClient.UseLegacyNetworkingOnWindows"; - public static readonly TdsParserStateObjectFactory Singleton = new TdsParserStateObjectFactory(); - // Temporary disabling App Context switching for managed SNI. - // If the appcontext switch is set then Use Managed SNI based on the value. Otherwise Managed SNI should always be used. - //private static bool shouldUseLegacyNetorking; - //public static bool UseManagedSNI { get; } = AppContext.TryGetSwitch(UseLegacyNetworkingOnWindows, out shouldUseLegacyNetorking) ? !shouldUseLegacyNetorking : true; - + /* Managed SNI can be enabled on Windows by setting any of the below two environment variables to 'True': + * Microsoft.Data.SqlClient.UseManagedSNIOnWindows (Supported to respect namespace format) + * Microsoft_Data_SqlClient_UseManagedSNIOnWindows (Supported for Azure Pipelines) + **/ private static Lazy useManagedSNIOnWindows = new Lazy( - () => bool.TrueString.Equals(Environment.GetEnvironmentVariable("Microsoft.Data.SqlClient.UseManagedSNIOnWindows"), StringComparison.InvariantCultureIgnoreCase) + () => bool.TrueString.Equals(Environment.GetEnvironmentVariable("Microsoft.Data.SqlClient.UseManagedSNIOnWindows"), + StringComparison.InvariantCultureIgnoreCase) || + bool.TrueString.Equals(Environment.GetEnvironmentVariable("Microsoft_Data_SqlClient_UseManagedSNIOnWindows"), + StringComparison.InvariantCultureIgnoreCase) ); public static bool UseManagedSNI => useManagedSNIOnWindows.Value; From cf194e55196f117138c082af7e18b64d7ed5b058 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 11:47:22 -0700 Subject: [PATCH 03/11] Disable IntegratedAuth tests with Managed SNI --- .../IntegratedAuthenticationTest.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs index 05fe3ab782..91d71e20be 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs @@ -8,7 +8,9 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public static class IntegratedAuthenticationTest { - private static bool IsIntegratedSecurityEnvironmentSet() => DataTestUtility.IsIntegratedSecuritySetup(); + // Managed SNI does not support Windows Integrated Authentication, hence tests disabled for the same. + private static bool IsIntegratedSecurityEnvironmentSet() => DataTestUtility.IsIntegratedSecuritySetup() && DataTestUtility.IsUsingNativeSNI(); + private static bool AreConnectionStringsSetup() => DataTestUtility.AreConnStringsSetup(); From 71282d6bd82115ae3f3cdf816994f270589e9dfe Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 12:22:30 -0700 Subject: [PATCH 04/11] Document developer notes --- BUILDGUIDE.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index 9adcf0717f..e3de6e3afd 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -160,6 +160,7 @@ Tests can be built and run with custom Target Frameworks. See the below examples # Build the tests for custom TargetFramework (.NET Core) # Applicable values: netcoreapp2.1 | netcoreapp2.2 | netcoreapp3.0 ``` + ### Running Tests: ```bash @@ -171,3 +172,10 @@ Tests can be built and run with custom Target Frameworks. See the below examples # Use above property to run Functional Tests with custom TargetFramework (.NET Core) # Applicable values: netcoreapp2.1 | netcoreapp2.2 | netcoreapp3.0 ``` + +## Using Managed SNI on Windows + +Managed SNI can be enabled on Windows by setting any of the below two environment variables to 'True': + +- **Microsoft.Data.SqlClient.UseManagedSNIOnWindows** (Supported to respect namespace format) +- **Microsoft_Data_SqlClient_UseManagedSNIOnWindows** (Supported for Azure Pipelines) From 4a127d4ba7f0977ce93155dff5c594b9e9d12ef3 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 12:38:24 -0700 Subject: [PATCH 05/11] Nit: extra line --- .../IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs index 91d71e20be..63f0c34d97 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs @@ -13,7 +13,6 @@ public static class IntegratedAuthenticationTest private static bool AreConnectionStringsSetup() => DataTestUtility.AreConnStringsSetup(); - [ConditionalFact(nameof(IsIntegratedSecurityEnvironmentSet), nameof(AreConnectionStringsSetup))] public static void IntegratedAuthenticationTestWithConnectionPooling() { From 7750596eeb3bcf951e5c8362850d34be32e5fe18 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 13:34:18 -0700 Subject: [PATCH 06/11] Re-enable tests --- .../IntegratedAuthenticationTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs index 63f0c34d97..b766502833 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/IntegratedAuthenticationTest/IntegratedAuthenticationTest.cs @@ -8,8 +8,7 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests { public static class IntegratedAuthenticationTest { - // Managed SNI does not support Windows Integrated Authentication, hence tests disabled for the same. - private static bool IsIntegratedSecurityEnvironmentSet() => DataTestUtility.IsIntegratedSecuritySetup() && DataTestUtility.IsUsingNativeSNI(); + private static bool IsIntegratedSecurityEnvironmentSet() => DataTestUtility.IsIntegratedSecuritySetup(); private static bool AreConnectionStringsSetup() => DataTestUtility.AreConnStringsSetup(); From 047a27b2f32390700f0ad634cb5dc8c741eb0790 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 15:45:34 -0700 Subject: [PATCH 07/11] Enable Managed SNI with AppContext switch --- .../TdsParserStateObjectFactory.Windows.cs | 18 +++++++----------- .../ManualTests/DataCommon/DataTestUtility.cs | 14 ++++++++++---- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs index bd6daa8b0f..ba0a399a37 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs @@ -11,17 +11,13 @@ internal sealed class TdsParserStateObjectFactory { public static readonly TdsParserStateObjectFactory Singleton = new TdsParserStateObjectFactory(); - /* Managed SNI can be enabled on Windows by setting any of the below two environment variables to 'True': - * Microsoft.Data.SqlClient.UseManagedSNIOnWindows (Supported to respect namespace format) - * Microsoft_Data_SqlClient_UseManagedSNIOnWindows (Supported for Azure Pipelines) - **/ - private static Lazy useManagedSNIOnWindows = new Lazy( - () => bool.TrueString.Equals(Environment.GetEnvironmentVariable("Microsoft.Data.SqlClient.UseManagedSNIOnWindows"), - StringComparison.InvariantCultureIgnoreCase) || - bool.TrueString.Equals(Environment.GetEnvironmentVariable("Microsoft_Data_SqlClient_UseManagedSNIOnWindows"), - StringComparison.InvariantCultureIgnoreCase) - ); - public static bool UseManagedSNI => useManagedSNIOnWindows.Value; + private const string UseManagedNetworkingOnWindows = "Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"; + + private static bool shouldUseManagedSNI; + + // If the appcontext switch is set then Use Managed SNI based on the value. Otherwise Native SNI.dll will be used by default. + public static bool UseManagedSNI { get; } = + AppContext.TryGetSwitch(UseManagedNetworkingOnWindows, out shouldUseManagedSNI) ? shouldUseManagedSNI : false; public EncryptionOptions EncryptionOptions { diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index ea3def41a0..3ada58ba37 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -45,9 +45,10 @@ public static class DataTestUtility public const string UdtTestDbName = "UdtTestDb"; public const string AKVKeyName = "TestSqlClientAzureKeyVaultProvider"; - private static readonly Assembly MdsAssembly = typeof(Microsoft.Data.SqlClient.SqlConnection).GetTypeInfo().Assembly; - private static readonly Type TdsParserStateObjectFactoryInstance = MdsAssembly?.GetType("Microsoft.Data.SqlClient.TdsParserStateObjectFactory"); - private static readonly PropertyInfo UseManagedSni = TdsParserStateObjectFactoryInstance?.GetProperty("UseManagedSNI", BindingFlags.Static | BindingFlags.Public); + private const string ManagedNetworkingAppContextSwitch = "Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"; + + private static bool UseManagedSNI = + bool.TryParse(Environment.GetEnvironmentVariable("Microsoft_Data_SqlClient_UseManagedSniOnWindows"), out UseManagedSNI) ? UseManagedSNI : false; private static readonly string[] AzureSqlServerEndpoints = {".database.windows.net", ".database.cloudapi.de", @@ -76,6 +77,11 @@ private class Config static DataTestUtility() { + if (UseManagedSNI) + { + AppContext.SetSwitch(ManagedNetworkingAppContextSwitch, true); + } + using (StreamReader r = new StreamReader("config.json")) { string json = r.ReadToEnd(); @@ -231,7 +237,7 @@ public static bool IsAKVSetupAvailable() return !string.IsNullOrEmpty(AKVUrl) && !string.IsNullOrEmpty(AKVClientId) && !string.IsNullOrEmpty(AKVClientSecret); } - public static bool IsUsingManagedSNI() => (bool)(UseManagedSni?.GetValue(null) ?? false); + public static bool IsUsingManagedSNI() => UseManagedSNI; public static bool IsUsingNativeSNI() => !IsUsingManagedSNI(); From 9163a5a071408fd19c156d03f23a17c1f019c122 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 16:10:44 -0700 Subject: [PATCH 08/11] Log switch enabled --- .../tests/ManualTests/DataCommon/DataTestUtility.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs index 3ada58ba37..2a73c38487 100644 --- a/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs +++ b/src/Microsoft.Data.SqlClient/tests/ManualTests/DataCommon/DataTestUtility.cs @@ -80,6 +80,7 @@ static DataTestUtility() if (UseManagedSNI) { AppContext.SetSwitch(ManagedNetworkingAppContextSwitch, true); + Console.WriteLine($"App Context switch {ManagedNetworkingAppContextSwitch} enabled on {Environment.OSVersion}"); } using (StreamReader r = new StreamReader("config.json")) From da3a0c3a77374af24279b01d512876c672264927 Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Fri, 20 Mar 2020 16:18:15 -0700 Subject: [PATCH 09/11] Update Buildguide --- BUILDGUIDE.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index e3de6e3afd..ad61628b08 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -175,7 +175,6 @@ Tests can be built and run with custom Target Frameworks. See the below examples ## Using Managed SNI on Windows -Managed SNI can be enabled on Windows by setting any of the below two environment variables to 'True': +Managed SNI can be enabled on Windows by enabling below AppContext switch: -- **Microsoft.Data.SqlClient.UseManagedSNIOnWindows** (Supported to respect namespace format) -- **Microsoft_Data_SqlClient_UseManagedSNIOnWindows** (Supported for Azure Pipelines) +**"Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"** From 0556a48d78e2c50f6938f4b398c7e44cdd4770ae Mon Sep 17 00:00:00 2001 From: Cheena Malhotra Date: Mon, 23 Mar 2020 07:45:02 -0700 Subject: [PATCH 10/11] Log --- .../Data/SqlClient/TdsParserStateObjectFactory.Windows.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs index ba0a399a37..2f609b5d91 100644 --- a/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs +++ b/src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectFactory.Windows.cs @@ -39,10 +39,14 @@ public TdsParserStateObject CreateTdsParserStateObject(TdsParser parser) { if (UseManagedSNI) { + SqlClientEventSource.Log.TraceEvent(" Found AppContext switch '{0}#' enabled, managed networking implementation will be used." + , UseManagedNetworkingOnWindows); return new TdsParserStateObjectManaged(parser); } else { + SqlClientEventSource.Log.TraceEvent(" AppContext switch '{0}#' not enabled, native networking implementation will be used." + , UseManagedNetworkingOnWindows); return new TdsParserStateObjectNative(parser); } } From 24be41fc725e29152d8cf8fc3eb984d21634c58f Mon Sep 17 00:00:00 2001 From: David Engel Date: Mon, 23 Mar 2020 11:02:20 -0700 Subject: [PATCH 11/11] Update BUILDGUIDE.md --- BUILDGUIDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDGUIDE.md b/BUILDGUIDE.md index b2b1b1b33e..9f4da39069 100644 --- a/BUILDGUIDE.md +++ b/BUILDGUIDE.md @@ -175,6 +175,6 @@ Tests can be built and run with custom Target Frameworks. See the below examples ## Using Managed SNI on Windows -Managed SNI can be enabled on Windows by enabling below AppContext switch: +Managed SNI can be enabled on Windows by enabling the below AppContext switch: **"Microsoft.Data.SqlClient.UseManagedNetworkingOnWindows"**