Skip to content

Commit 7314307

Browse files
authored
Fix | Take out the ignoreSniOpenTimeout in open connection (#2067)
1 parent 9ac8cc8 commit 7314307

File tree

11 files changed

+105
-32
lines changed

11 files changed

+105
-32
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIProxy.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode)
130130
/// Create a SNI connection handle
131131
/// </summary>
132132
/// <param name="fullServerName">Full server name from connection string</param>
133-
/// <param name="ignoreSniOpenTimeout">Ignore open timeout</param>
134133
/// <param name="timerExpire">Timer expiration</param>
135134
/// <param name="instanceName">Instance name</param>
136135
/// <param name="spnBuffer">SPN</param>
@@ -148,7 +147,6 @@ private static bool IsErrorStatus(SecurityStatusPalErrorCode errorCode)
148147
/// <returns>SNI handle</returns>
149148
internal static SNIHandle CreateConnectionHandle(
150149
string fullServerName,
151-
bool ignoreSniOpenTimeout,
152150
long timerExpire,
153151
out byte[] instanceName,
154152
ref byte[][] spnBuffer,

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1543,7 +1543,6 @@ private void LoginNoFailover(ServerInfo serverInfo,
15431543
AttemptOneLogin(serverInfo,
15441544
newPassword,
15451545
newSecurePassword,
1546-
!connectionOptions.MultiSubnetFailover, // ignore timeout for SniOpen call unless MSF
15471546
connectionOptions.MultiSubnetFailover ? intervalTimer : timeout);
15481547

15491548
if (connectionOptions.MultiSubnetFailover && null != ServerProvidedFailOverPartner)
@@ -1782,7 +1781,6 @@ TimeoutTimer timeout
17821781
currentServerInfo,
17831782
newPassword,
17841783
newSecurePassword,
1785-
false, // Use timeout in SniOpen
17861784
intervalTimer,
17871785
withFailover: true
17881786
);
@@ -1910,7 +1908,6 @@ private void AttemptOneLogin(
19101908
ServerInfo serverInfo,
19111909
string newPassword,
19121910
SecureString newSecurePassword,
1913-
bool ignoreSniOpenTimeout,
19141911
TimeoutTimer timeout,
19151912
bool withFailover = false)
19161913
{
@@ -1921,7 +1918,6 @@ private void AttemptOneLogin(
19211918

19221919
_parser.Connect(serverInfo,
19231920
this,
1924-
ignoreSniOpenTimeout,
19251921
timeout.LegacyTimerExpire,
19261922
ConnectionOptions,
19271923
withFailover);

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

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,6 @@ internal void ProcessPendingAck(TdsParserStateObject stateObj)
361361
internal void Connect(
362362
ServerInfo serverInfo,
363363
SqlInternalConnectionTds connHandler,
364-
bool ignoreSniOpenTimeout,
365364
long timerExpire,
366365
SqlConnectionString connectionOptions,
367366
bool withFailover)
@@ -445,7 +444,6 @@ internal void Connect(
445444
// AD Integrated behaves like Windows integrated when connecting to a non-fedAuth server
446445
_physicalStateObj.CreatePhysicalSNIHandle(
447446
serverInfo.ExtendedServerName,
448-
ignoreSniOpenTimeout,
449447
timerExpire,
450448
out instanceName,
451449
ref _sniSpnBuffer,
@@ -544,7 +542,6 @@ internal void Connect(
544542

545543
_physicalStateObj.CreatePhysicalSNIHandle(
546544
serverInfo.ExtendedServerName,
547-
ignoreSniOpenTimeout,
548545
timerExpire, out instanceName,
549546
ref _sniSpnBuffer,
550547
true,

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,6 @@ private void ResetCancelAndProcessAttention()
198198

199199
internal abstract void CreatePhysicalSNIHandle(
200200
string serverName,
201-
bool ignoreSniOpenTimeout,
202201
long timerExpire,
203202
out byte[] instanceName,
204203
ref byte[][] spnBuffer,

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectManaged.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ protected override uint SNIPacketGetData(PacketHandle packet, byte[] inBuff, ref
8282

8383
internal override void CreatePhysicalSNIHandle(
8484
string serverName,
85-
bool ignoreSniOpenTimeout,
8685
long timerExpire,
8786
out byte[] instanceName,
8887
ref byte[][] spnBuffer,
@@ -98,7 +97,7 @@ internal override void CreatePhysicalSNIHandle(
9897
string hostNameInCertificate,
9998
string serverCertificateFilename)
10099
{
101-
SNIHandle? sessionHandle = SNIProxy.CreateConnectionHandle(serverName, ignoreSniOpenTimeout, timerExpire, out instanceName, ref spnBuffer, serverSPN,
100+
SNIHandle? sessionHandle = SNIProxy.CreateConnectionHandle(serverName, timerExpire, out instanceName, ref spnBuffer, serverSPN,
102101
flushCache, async, parallel, isIntegratedSecurity, iPAddressPreference, cachedFQDN, ref pendingDNSInfo, tlsFirst,
103102
hostNameInCertificate, serverCertificateFilename);
104103

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObjectNative.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,6 @@ private SNINativeMethodWrapper.ConsumerInfo CreateConsumerInfo(bool async)
140140

141141
internal override void CreatePhysicalSNIHandle(
142142
string serverName,
143-
bool ignoreSniOpenTimeout,
144143
long timerExpire,
145144
out byte[] instanceName,
146145
ref byte[][] spnBuffer,
@@ -199,7 +198,7 @@ internal override void CreatePhysicalSNIHandle(
199198
SQLDNSInfo cachedDNSInfo;
200199
bool ret = SQLFallbackDNSCache.Instance.GetDNSInfo(cachedFQDN, out cachedDNSInfo);
201200

202-
_sessionHandle = new SNIHandle(myInfo, serverName, spnBuffer[0], ignoreSniOpenTimeout, checked((int)timeout), out instanceName,
201+
_sessionHandle = new SNIHandle(myInfo, serverName, spnBuffer[0], checked((int)timeout), out instanceName,
203202
flushCache, !async, fParallel, ipPreference, cachedDNSInfo, hostNameInCertificate);
204203
}
205204

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlInternalConnectionTds.cs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,7 +1861,6 @@ private void LoginNoFailover(ServerInfo serverInfo, string newPassword, SecureSt
18611861
AttemptOneLogin(serverInfo,
18621862
newPassword,
18631863
newSecurePassword,
1864-
!isParallel, // ignore timeout for SniOpen call unless MSF , and TNIR
18651864
attemptOneLoginTimeout,
18661865
isFirstTransparentAttempt: isFirstTransparentAttempt,
18671866
disableTnir: disableTnir);
@@ -2137,7 +2136,6 @@ TimeoutTimer timeout
21372136
currentServerInfo,
21382137
newPassword,
21392138
newSecurePassword,
2140-
false, // Use timeout in SniOpen
21412139
intervalTimer,
21422140
withFailover: true
21432141
);
@@ -2175,7 +2173,6 @@ TimeoutTimer timeout
21752173
currentServerInfo,
21762174
newPassword,
21772175
newSecurePassword,
2178-
false, // Use timeout in SniOpen
21792176
intervalTimer,
21802177
withFailover: true
21812178
);
@@ -2293,7 +2290,7 @@ private void ResolveExtendedServerName(ServerInfo serverInfo, bool aliasLookup,
22932290
}
22942291

22952292
// Common code path for making one attempt to establish a connection and log in to server.
2296-
private void AttemptOneLogin(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, bool ignoreSniOpenTimeout, TimeoutTimer timeout, bool withFailover = false, bool isFirstTransparentAttempt = true, bool disableTnir = false)
2293+
private void AttemptOneLogin(ServerInfo serverInfo, string newPassword, SecureString newSecurePassword, TimeoutTimer timeout, bool withFailover = false, bool isFirstTransparentAttempt = true, bool disableTnir = false)
22972294
{
22982295
SqlClientEventSource.Log.TryAdvancedTraceEvent("<sc.SqlInternalConnectionTds.AttemptOneLogin|ADV> {0}, timout={1}[msec], server={2}", ObjectID, timeout.MillisecondsRemaining, serverInfo.ExtendedServerName);
22992296

@@ -2303,7 +2300,6 @@ private void AttemptOneLogin(ServerInfo serverInfo, string newPassword, SecureSt
23032300

23042301
_parser.Connect(serverInfo,
23052302
this,
2306-
ignoreSniOpenTimeout,
23072303
timeout.LegacyTimerExpire,
23082304
ConnectionOptions,
23092305
withFailover,

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParser.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,6 @@ internal void ProcessPendingAck(TdsParserStateObject stateObj)
494494

495495
internal void Connect(ServerInfo serverInfo,
496496
SqlInternalConnectionTds connHandler,
497-
bool ignoreSniOpenTimeout,
498497
long timerExpire,
499498
SqlConnectionString connectionOptions,
500499
bool withFailover,
@@ -640,7 +639,6 @@ internal void Connect(ServerInfo serverInfo,
640639

641640
_physicalStateObj.CreatePhysicalSNIHandle(
642641
serverInfo.ExtendedServerName,
643-
ignoreSniOpenTimeout,
644642
timerExpire,
645643
out instanceName,
646644
_sniSpnBuffer,
@@ -746,7 +744,6 @@ internal void Connect(ServerInfo serverInfo,
746744
_physicalStateObj.SniContext = SniContext.Snix_Connect;
747745
_physicalStateObj.CreatePhysicalSNIHandle(
748746
serverInfo.ExtendedServerName,
749-
ignoreSniOpenTimeout,
750747
timerExpire,
751748
out instanceName,
752749
_sniSpnBuffer,

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,6 @@ private SNINativeMethodWrapper.ConsumerInfo CreateConsumerInfo(bool async)
279279

280280
internal void CreatePhysicalSNIHandle(
281281
string serverName,
282-
bool ignoreSniOpenTimeout,
283282
long timerExpire,
284283
out byte[] instanceName,
285284
byte[] spnBuffer,
@@ -318,7 +317,7 @@ internal void CreatePhysicalSNIHandle(
318317

319318
_ = SQLFallbackDNSCache.Instance.GetDNSInfo(cachedFQDN, out SQLDNSInfo cachedDNSInfo);
320319

321-
_sessionHandle = new SNIHandle(myInfo, serverName, spnBuffer, ignoreSniOpenTimeout, checked((int)timeout),
320+
_sessionHandle = new SNIHandle(myInfo, serverName, spnBuffer, checked((int)timeout),
322321
out instanceName, flushCache, !async, fParallel, transparentNetworkResolutionState, totalTimeout,
323322
ipPreference, cachedDNSInfo, hostNameInCertificate);
324323
}

src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/TdsParserSafeHandles.Windows.cs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ internal SNIHandle(
150150
SNINativeMethodWrapper.ConsumerInfo myInfo,
151151
string serverName,
152152
byte[] spnBuffer,
153-
bool ignoreSniOpenTimeout,
154153
int timeout,
155154
out byte[] instanceName,
156155
bool flushCache,
@@ -174,13 +173,14 @@ internal SNIHandle(
174173
{
175174
_fSync = fSync;
176175
instanceName = new byte[256]; // Size as specified by netlibs.
177-
if (ignoreSniOpenTimeout)
178-
{
179-
// UNDONE: ITEM12001110 (DB Mirroring Reconnect) Old behavior of not truly honoring timeout presevered
180-
// for non-failover scenarios to avoid breaking changes as part of a QFE. Consider fixing timeout
181-
// handling in next full release and removing ignoreSniOpenTimeout parameter.
182-
timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE
183-
}
176+
// Option ignoreSniOpenTimeout is no longer available
177+
//if (ignoreSniOpenTimeout)
178+
//{
179+
// // UNDONE: ITEM12001110 (DB Mirroring Reconnect) Old behavior of not truly honoring timeout presevered
180+
// // for non-failover scenarios to avoid breaking changes as part of a QFE. Consider fixing timeout
181+
// // handling in next full release and removing ignoreSniOpenTimeout parameter.
182+
// timeout = Timeout.Infinite; // -1 == native SNIOPEN_TIMEOUT_VALUE / INFINITE
183+
//}
184184

185185
#if NETFRAMEWORK
186186
int transparentNetworkResolutionStateNo = (int)transparentNetworkResolutionState;

src/Microsoft.Data.SqlClient/tests/FunctionalTests/SqlConnectionBasicTests.cs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,99 @@ public void ConnectionTestValidCredentialCombination()
251251
Assert.Equal(sqlCredential, conn.Credential);
252252
}
253253

254+
255+
[Theory]
256+
[InlineData(60)]
257+
[InlineData(30)]
258+
[InlineData(15)]
259+
[InlineData(10)]
260+
[InlineData(5)]
261+
[InlineData(1)]
262+
public void ConnectionTimeoutTest(int timeout)
263+
{
264+
// Start a server with connection timeout from the inline data.
265+
using TestTdsServer server = TestTdsServer.StartTestServer(false, false, timeout);
266+
using SqlConnection connection = new SqlConnection(server.ConnectionString);
267+
268+
// Dispose the server to force connection timeout
269+
server.Dispose();
270+
271+
// Measure the actual time it took to timeout and compare it with configured timeout
272+
var start = DateTime.Now;
273+
var end = start;
274+
275+
// Open a connection with the server disposed.
276+
try
277+
{
278+
connection.Open();
279+
}
280+
catch (Exception)
281+
{
282+
end = DateTime.Now;
283+
}
284+
285+
// Calculate actual duration of timeout
286+
TimeSpan s = end - start;
287+
// Did not time out?
288+
if (s.TotalSeconds == 0)
289+
Assert.True(s.TotalSeconds == 0);
290+
291+
// Is actual time out the same as configured timeout or within an additional 3 second threshold because of overhead?
292+
if (s.TotalSeconds > 0)
293+
Assert.True(s.TotalSeconds <= timeout + 3);
294+
}
295+
296+
[Theory]
297+
[InlineData(60)]
298+
[InlineData(30)]
299+
[InlineData(15)]
300+
[InlineData(10)]
301+
[InlineData(5)]
302+
[InlineData(1)]
303+
public async void ConnectionTimeoutTestAsync(int timeout)
304+
{
305+
// Start a server with connection timeout from the inline data.
306+
using TestTdsServer server = TestTdsServer.StartTestServer(false, false, timeout);
307+
using SqlConnection connection = new SqlConnection(server.ConnectionString);
308+
309+
// Dispose the server to force connection timeout
310+
server.Dispose();
311+
312+
// Measure the actual time it took to timeout and compare it with configured timeout
313+
var start = DateTime.Now;
314+
var end = start;
315+
316+
// Open a connection with the server disposed.
317+
try
318+
{
319+
await connection.OpenAsync();
320+
}
321+
catch (Exception)
322+
{
323+
end = DateTime.Now;
324+
}
325+
326+
// Calculate actual duration of timeout
327+
TimeSpan s = end - start;
328+
// Did not time out?
329+
if (s.TotalSeconds == 0)
330+
Assert.True(s.TotalSeconds == 0);
331+
332+
// Is actual time out the same as configured timeout or within an additional 3 second threshold because of overhead?
333+
if (s.TotalSeconds > 0)
334+
Assert.True(s.TotalSeconds <= timeout + 3);
335+
}
336+
337+
[Fact]
338+
public void ConnectionInvalidTimeoutTest()
339+
{
340+
Assert.Throws<ArgumentException>(() =>
341+
{
342+
using TestTdsServer server = TestTdsServer.StartTestServer(false, false, -5);
343+
});
344+
345+
}
346+
254347
[Fact]
255348
public void ConnectionTestWithCultureTH()
256349
{

0 commit comments

Comments
 (0)