Skip to content

Commit

Permalink
Fix | Fixing issue for SQL named Instances in Managed SNI using named…
Browse files Browse the repository at this point in the history
… pipes. (#2142)
  • Loading branch information
arellegue authored Oct 31, 2023
1 parent 5a4feed commit d5df671
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public SNINpHandle(string serverName, string pipeName, TimeoutTimer timeout, boo
{
int timeoutMilliseconds = timeout.MillisecondsRemainingInt;
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINpHandle), EventType.INFO,
"Connection Id {0}, Setting server name = {1}, pipe name = {2}. Connecting within the {3} sepecified milliseconds.",
"Connection Id {0}, Setting server name = {1}, pipe name = {2}. Connecting within the {3} specified milliseconds.",
args0: _connectionId,
args1: serverName,
args2: pipeName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,8 @@ internal class DataSource
private const string LocalDbHost_NP = @"np:\\.\pipe\LOCALDB#";
private const string NamedPipeInstanceNameHeader = "mssql$";
private const string DefaultPipeName = "sql\\query";
private const string InstancePrefix = "MSSQL$";
private const string PathSeparator = "\\";

internal enum Protocol { TCP, NP, None, Admin };

Expand Down Expand Up @@ -683,12 +685,35 @@ private bool InferNamedPipesInformation()
// If we have a datasource beginning with a pipe or we have already determined that the protocol is Named Pipe
if (_dataSourceAfterTrimmingProtocol.StartsWith(PipeBeginning, StringComparison.Ordinal) || _connectionProtocol == Protocol.NP)
{
// If the data source is "np:servername"
// If the data source starts with "np:servername"
if (!_dataSourceAfterTrimmingProtocol.Contains(PipeBeginning))
{
PipeHostName = ServerName = _dataSourceAfterTrimmingProtocol;
// Assuming that user did not change default NamedPipe name, if the datasource is in the format servername\instance,
// separate servername and instance and prepend instance with MSSQL$ and append default pipe path
// https://learn.microsoft.com/en-us/sql/tools/configuration-manager/named-pipes-properties?view=sql-server-ver16
if (_dataSourceAfterTrimmingProtocol.Contains(PathSeparator) && _connectionProtocol == Protocol.NP)
{
string[] tokensByBackSlash = _dataSourceAfterTrimmingProtocol.Split(BackSlashCharacter);
if (tokensByBackSlash.Length == 2)
{
// NamedPipeClientStream object will create the network path using PipeHostName and PipeName
// and can be seen in its _normalizedPipePath variable in the format \\servername\pipe\MSSQL$<instancename>\sql\query
PipeHostName = ServerName = tokensByBackSlash[0];
PipeName = $"{InstancePrefix}{tokensByBackSlash[1]}{PathSeparator}{DefaultPipeName}";
}
else
{
ReportSNIError(SNIProviders.NP_PROV);
return false;
}
}
else
{
PipeHostName = ServerName = _dataSourceAfterTrimmingProtocol;
PipeName = SNINpHandle.DefaultPipePath;
}

InferLocalServerName();
PipeName = SNINpHandle.DefaultPipePath;
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public static void ConnectManagedWithInstanceNameTest(bool useMultiSubnetFailove
if (!IsValidInstance(hostname, instanceName))
{
builder.DataSource = hostname + "\\" + instanceName;

using SqlConnection connection = new(builder.ConnectionString);
SqlException ex = Assert.Throws<SqlException>(() => connection.Open());
Assert.Contains("Error Locating Server/Instance Specified", ex.Message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ namespace Microsoft.Data.SqlClient.ManualTesting.Tests
{
public static class SqlCredentialTest
{

[ConditionalFact(typeof(DataTestUtility), nameof(DataTestUtility.AreConnStringsSetup), nameof(DataTestUtility.IsNotAzureServer))]
public static void CreateSqlConnectionWithCredential()
{
Expand Down

0 comments on commit d5df671

Please sign in to comment.