Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd3772fc

Browse files
authored
Fix | Increase routing attempt to 10 in netcore for LoginNoFailover and adding routing support to LoginWithFailover (#2873)
1 parentcab5422 commitd3772fc

File tree

6 files changed

+175
-63
lines changed

6 files changed

+175
-63
lines changed

‎src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs

Lines changed: 98 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,10 @@ internal sealed class SqlInternalConnectionTds : SqlInternalConnection, IDisposa
109109
// CONNECTION AND STATE VARIABLES
110110
privatereadonlySqlConnectionPoolGroupProviderInfo_poolGroupProviderInfo;// will only be null when called for ChangePassword, or creating SSE User Instance
111111
privateTdsParser_parser;
112+
113+
// Connection re-route limit
114+
internalconstint_maxNumberOfRedirectRoute=10;
115+
112116
privateSqlLoginAck_loginAck;
113117
privateSqlCredential_credential;
114118
privateFederatedAuthenticationFeatureExtensionData_fedAuthFeatureExtensionData;
@@ -130,7 +134,7 @@ internal sealed class SqlInternalConnectionTds : SqlInternalConnection, IDisposa
130134
// The Federated Authentication returned by TryGetFedAuthTokenLocked or GetFedAuthToken.
131135
SqlFedAuthToken_fedAuthToken=null;
132136
internalbyte[]_accessTokenInBytes;
133-
internalreadonlyFunc<SqlAuthenticationParameters,CancellationToken,Task<SqlAuthenticationToken>>_accessTokenCallback;
137+
internalreadonlyFunc<SqlAuthenticationParameters,CancellationToken,Task<SqlAuthenticationToken>>_accessTokenCallback;
134138

135139
privatereadonlyActiveDirectoryAuthenticationTimeoutRetryHelper_activeDirectoryAuthTimeoutRetryHelper;
136140

@@ -1363,6 +1367,12 @@ private void Login(ServerInfo server, TimeoutTimer timeout, string newPassword,
13631367
// The GLOBALTRANSACTIONS, DATACLASSIFICATION, TCE, and UTF8 support features are implicitly requested
13641368
requestedFeatures|=TdsEnums.FeatureExtension.GlobalTransactions|TdsEnums.FeatureExtension.DataClassification|TdsEnums.FeatureExtension.Tce|TdsEnums.FeatureExtension.UTF8Support;
13651369

1370+
// The AzureSQLSupport feature is implicitly set for ReadOnly login
1371+
if(ConnectionOptions.ApplicationIntent==ApplicationIntent.ReadOnly)
1372+
{
1373+
requestedFeatures|=TdsEnums.FeatureExtension.AzureSQLSupport;
1374+
}
1375+
13661376
// The SQLDNSCaching feature is implicitly set
13671377
requestedFeatures|=TdsEnums.FeatureExtension.SQLDNSCaching;
13681378
requestedFeatures|=TdsEnums.FeatureExtension.JsonSupport;
@@ -1440,6 +1450,23 @@ private void OpenLoginEnlist(TimeoutTimer timeout,
14401450
credential,
14411451
timeout);
14421452
}
1453+
1454+
if(!IsAzureSQLConnection)
1455+
{
1456+
// If not a connection to Azure SQL, Readonly with FailoverPartner is not supported
1457+
if(ConnectionOptions.ApplicationIntent==ApplicationIntent.ReadOnly)
1458+
{
1459+
if(!string.IsNullOrEmpty(ConnectionOptions.FailoverPartner))
1460+
{
1461+
throwSQL.ROR_FailoverNotSupportedConnString();
1462+
}
1463+
1464+
if(ServerProvidedFailOverPartner!=null)
1465+
{
1466+
throwSQL.ROR_FailoverNotSupportedServer(this);
1467+
}
1468+
}
1469+
}
14431470
_timeoutErrorInternal.EndPhase(SqlConnectionTimeoutErrorPhase.PostLogin);
14441471
}
14451472
catch(Exceptione)
@@ -1556,9 +1583,9 @@ private void LoginNoFailover(ServerInfo serverInfo,
15561583
if(RoutingInfo!=null)
15571584
{
15581585
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.LoginNoFailover> Routed to {0}",serverInfo.ExtendedServerName);
1559-
if(routingAttempts>0)
1586+
if(routingAttempts>_maxNumberOfRedirectRoute)
15601587
{
1561-
throwSQL.ROR_RecursiveRoutingNotSupported(this);
1588+
throwSQL.ROR_RecursiveRoutingNotSupported(this,_maxNumberOfRedirectRoute);
15621589
}
15631590

15641591
if(timeout.IsExpired)
@@ -1754,7 +1781,9 @@ TimeoutTimer timeout
17541781
// Re-allocate parser each time to make sure state is known
17551782
// RFC 50002652 - if parser was created by previous attempt, dispose it to properly close the socket, if created
17561783
if(_parser!=null)
1784+
{
17571785
_parser.Disconnect();
1786+
}
17581787

17591788
_parser=newTdsParser(ConnectionOptions.MARS,ConnectionOptions.Asynchronous);
17601789
Debug.Assert(SniContext.Undefined==Parser._physicalStateObj.SniContext,$"SniContext should be Undefined; actual Value:{Parser._physicalStateObj.SniContext}");
@@ -1787,15 +1816,44 @@ TimeoutTimer timeout
17871816
intervalTimer,
17881817
withFailover:true
17891818
);
1790-
1791-
if(RoutingInfo!=null)
1819+
introutingAttemps=0;
1820+
while(RoutingInfo!=null)
17921821
{
1793-
// We are in login with failover scenation and server sent routing information
1794-
// If it is read-only routing - we did not supply AppIntent=RO (it should be checked before)
1795-
// If it is something else, not known yet (future server) - this client is not designed to support this.
1796-
// In any case, server should not have sent the routing info.
1822+
if(routingAttemps>_maxNumberOfRedirectRoute)
1823+
{
1824+
throwSQL.ROR_RecursiveRoutingNotSupported(this,_maxNumberOfRedirectRoute);
1825+
}
1826+
routingAttemps++;
1827+
17971828
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.LoginWithFailover> Routed to {0}",RoutingInfo.ServerName);
1798-
throwSQL.ROR_UnexpectedRoutingInfo(this);
1829+
1830+
if(_parser!=null)
1831+
{
1832+
_parser.Disconnect();
1833+
}
1834+
1835+
_parser=newTdsParser(ConnectionOptions.MARS,connectionOptions.Asynchronous);
1836+
1837+
Debug.Assert(SniContext.Undefined==Parser._physicalStateObj.SniContext,$"SniContext should be Undefined; actual Value:{Parser._physicalStateObj.SniContext}");
1838+
1839+
currentServerInfo=newServerInfo(ConnectionOptions,RoutingInfo,currentServerInfo.ResolvedServerName,currentServerInfo.ServerSPN);
1840+
_timeoutErrorInternal.SetInternalSourceType(SqlConnectionInternalSourceType.RoutingDestination);
1841+
_originalClientConnectionId=_clientConnectionId;
1842+
_routingDestination=currentServerInfo.UserServerName;
1843+
1844+
// restore properties that could be changed by the environemnt tokens
1845+
_currentPacketSize=connectionOptions.PacketSize;
1846+
_currentLanguage=_originalLanguage=ConnectionOptions.CurrentLanguage;
1847+
CurrentDatabase=_originalDatabase=connectionOptions.InitialCatalog;
1848+
_currentFailoverPartner=null;
1849+
_instanceName=string.Empty;
1850+
1851+
AttemptOneLogin(
1852+
currentServerInfo,
1853+
newPassword,
1854+
newSecurePassword,
1855+
intervalTimer,
1856+
withFailover:true);
17991857
}
18001858
break;// leave the while loop -- we've successfully connected
18011859
}
@@ -1812,7 +1870,7 @@ TimeoutTimer timeout
18121870
throw;// Caller will call LoginFailure()
18131871
}
18141872

1815-
if(IsConnectionDoomed)
1873+
if(!ADP.IsAzureSqlServerEndpoint(connectionOptions.DataSource)&&IsConnectionDoomed)
18161874
{
18171875
throw;
18181876
}
@@ -2743,23 +2801,33 @@ internal void OnFeatureExtAck(int featureId, byte[] data)
27432801
}
27442802
break;
27452803
}
2746-
2747-
caseTdsEnums.FEATUREEXT_UTF8SUPPORT:
2804+
caseTdsEnums.FEATUREEXT_AZURESQLSUPPORT:
27482805
{
2749-
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ADV> {0}, Received feature extension acknowledgement for UTF8 support",ObjectID);
2806+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ADV> {0}, Received feature extension acknowledgement for AzureSQLSupport",ObjectID);
2807+
27502808
if(data.Length<1)
27512809
{
2752-
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ERR> {0}, Unknown value for UTF8 support",ObjectID);
2753-
throwSQL.ParsingError();
2810+
throwSQL.ParsingError(ParsingErrorState.CorruptedTdsStream);
2811+
}
2812+
2813+
IsAzureSQLConnection=true;
2814+
2815+
// Bit 0 for RO/FP support
2816+
if((data[0]&1)==1&&SqlClientEventSource.Log.IsTraceEnabled())
2817+
{
2818+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ADV> {0}, FailoverPartner enabled with Readonly intent for AzureSQL DB",ObjectID);
2819+
27542820
}
27552821
break;
27562822
}
27572823
caseTdsEnums.FEATUREEXT_DATACLASSIFICATION:
27582824
{
27592825
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ADV> {0}, Received feature extension acknowledgement for DATACLASSIFICATION",ObjectID);
2826+
27602827
if(data.Length<1)
27612828
{
27622829
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ERR> {0}, Unknown token for DATACLASSIFICATION",ObjectID);
2830+
27632831
throwSQL.ParsingError(ParsingErrorState.CorruptedTdsStream);
27642832
}
27652833
bytesupportedDataClassificationVersion=data[0];
@@ -2772,12 +2840,25 @@ internal void OnFeatureExtAck(int featureId, byte[] data)
27722840
if(data.Length!=2)
27732841
{
27742842
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ERR> {0}, Unknown token for DATACLASSIFICATION",ObjectID);
2843+
27752844
throwSQL.ParsingError(ParsingErrorState.CorruptedTdsStream);
27762845
}
27772846
byteenabled=data[1];
27782847
_parser.DataClassificationVersion=(enabled==0)?TdsEnums.DATA_CLASSIFICATION_NOT_ENABLED:supportedDataClassificationVersion;
27792848
break;
27802849
}
2850+
caseTdsEnums.FEATUREEXT_UTF8SUPPORT:
2851+
{
2852+
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ADV> {0}, Received feature extension acknowledgement for UTF8 support",ObjectID);
2853+
2854+
if(data.Length<1)
2855+
{
2856+
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ERR> {0}, Unknown value for UTF8 support",ObjectID);
2857+
2858+
throwSQL.ParsingError();
2859+
}
2860+
break;
2861+
}
27812862

27822863
caseTdsEnums.FEATUREEXT_SQLDNSCACHING:
27832864
{
@@ -2822,7 +2903,7 @@ internal void OnFeatureExtAck(int featureId, byte[] data)
28222903
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ERR> {0}, Unknown token for JSONSUPPORT",ObjectID);
28232904
throwSQL.ParsingError(ParsingErrorState.CorruptedTdsStream);
28242905
}
2825-
bytejsonSupportVersion=data[0];
2906+
bytejsonSupportVersion=data[0];
28262907
if(jsonSupportVersion==0||jsonSupportVersion>TdsEnums.MAX_SUPPORTED_JSON_VERSION)
28272908
{
28282909
SqlClientEventSource.Log.TryTraceEvent("<sc.SqlInternalConnectionTds.OnFeatureExtAck|ERR> {0}, Invalid version number for JSONSUPPORT",ObjectID);

‎src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,10 @@ internal static void Assert(string message)
157157
// size of Guid (e.g. _clientConnectionId, ActivityId.Id)
158158
private const int GUID_SIZE = 16;
159159

160+
// now data length is 1 byte
161+
// First bit is 1 indicating client support failover partner with readonly intent
162+
private static readonly byte[] s_featureExtDataAzureSQLSupportFeatureRequest = { 0x01 };
163+
160164
// NOTE: You must take the internal connection's _parserLock before modifying this
161165
internal bool _asyncWrite = false;
162166

@@ -550,7 +554,6 @@ internal void Connect(
550554

551555
// On Instance failure re-connect and flush SNI named instance cache.
552556
_physicalStateObj.SniContext = SniContext.Snix_Connect;
553-
554557
_physicalStateObj.CreatePhysicalSNIHandle(
555558
serverInfo.ExtendedServerName,
556559
timeout, out instanceName,
@@ -8392,6 +8395,24 @@ internal int WriteFedAuthFeatureRequest(FederatedAuthenticationFeatureExtensionD
83928395
return len; // size of data written
83938396
}
83948397

8398+
internal int WriteAzureSQLSupportFeatureRequest(bool write /* if false just calculates the length */)
8399+
{
8400+
int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = featureData
8401+
8402+
if (write)
8403+
{
8404+
// Write Feature ID
8405+
_physicalStateObj.WriteByte(TdsEnums.FEATUREEXT_AZURESQLSUPPORT);
8406+
8407+
// Feature Data length
8408+
WriteInt(s_featureExtDataAzureSQLSupportFeatureRequest.Length, _physicalStateObj);
8409+
8410+
_physicalStateObj.WriteByteArray(s_featureExtDataAzureSQLSupportFeatureRequest, s_featureExtDataAzureSQLSupportFeatureRequest.Length, 0);
8411+
}
8412+
8413+
return len;
8414+
}
8415+
83958416
internal int WriteDataClassificationFeatureRequest(bool write /* if false just calculates the length */)
83968417
{
83978418
int len = 6; // 1byte = featureID, 4bytes = featureData length, 1 bytes = Version
@@ -8764,6 +8785,10 @@ private int ApplyFeatureExData(TdsEnums.FeatureExtension requestedFeatures,
87648785
{
87658786
length += WriteGlobalTransactionsFeatureRequest(write);
87668787
}
8788+
if ((requestedFeatures & TdsEnums.FeatureExtension.AzureSQLSupport) != 0)
8789+
{
8790+
length += WriteAzureSQLSupportFeatureRequest(write);
8791+
}
87678792
if ((requestedFeatures & TdsEnums.FeatureExtension.DataClassification) != 0)
87688793
{
87698794
length += WriteDataClassificationFeatureRequest(write);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp