From 85d123181521328740480d937480b1a93cfc22f2 Mon Sep 17 00:00:00 2001 From: Karina Zhou Date: Fri, 29 Nov 2019 15:54:26 -0800 Subject: [PATCH 1/4] Fix zero connection timeout issue --- .../src/System/Data/SqlClient/SNI/SNITcpHandle.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs index d2f7b516556d76..ce388fa04de86b 100644 --- a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs @@ -142,7 +142,7 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba } else { - _socket = Connect(serverName, port, ts); + _socket = Connect(serverName, port, ts, isInfiniteTimeOut); } if (_socket == null || !_socket.Connected) @@ -177,7 +177,7 @@ public SNITCPHandle(string serverName, int port, long timerExpire, object callba _status = TdsEnums.SNI_SUCCESS; } - private static Socket Connect(string serverName, int port, TimeSpan timeout) + private static Socket Connect(string serverName, int port, TimeSpan timeout, bool isInfiniteTimeout) { IPAddress[] ipAddresses = Dns.GetHostAddresses(serverName); IPAddress serverIPv4 = null; @@ -197,7 +197,15 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout) Socket[] sockets = new Socket[2]; CancellationTokenSource cts = new CancellationTokenSource(); - cts.CancelAfter(timeout); + if (isInfiniteTimeout) + { + cts.CancelAfter(-1); + } + else + { + cts.CancelAfter(timeout); + } + void Cancel() { for (int i = 0; i < sockets.Length; ++i) From 27123bd5eff53fc8ff1f180c9e3220e999f0f704 Mon Sep 17 00:00:00 2001 From: Karina Zhou Date: Mon, 2 Dec 2019 14:04:59 -0800 Subject: [PATCH 2/4] Update based on comments --- .../System/Data/SqlClient/SNI/SNITcpHandle.cs | 60 ++++++++++--------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs index ce388fa04de86b..94bd773a4f1b69 100644 --- a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs @@ -196,15 +196,7 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo ipAddresses = new IPAddress[] { serverIPv4, serverIPv6 }; Socket[] sockets = new Socket[2]; - CancellationTokenSource cts = new CancellationTokenSource(); - if (isInfiniteTimeout) - { - cts.CancelAfter(-1); - } - else - { - cts.CancelAfter(timeout); - } + CancellationTokenSource cts = null; void Cancel() { @@ -221,35 +213,49 @@ void Cancel() catch { } } } - cts.Token.Register(Cancel); + + if (!isInfiniteTimeout) + { + cts = new CancellationTokenSource(); + cts.CancelAfter(timeout); + cts.Token.Register(Cancel); + } + Socket availableSocket = null; - for (int i = 0; i < sockets.Length; ++i) + try { - try + for (int i = 0; i < sockets.Length; ++i) { - if (ipAddresses[i] != null) + try { - sockets[i] = new Socket(ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); - // enable keep-alive on socket - SNITcpHandle.SetKeepAliveValues(ref sockets[i]); - sockets[i].Connect(ipAddresses[i], port); - if (sockets[i] != null) // sockets[i] can be null if cancel callback is executed during connect() + if (ipAddresses[i] != null) { - if (sockets[i].Connected) - { - availableSocket = sockets[i]; - break; - } - else + sockets[i] = new Socket(ipAddresses[i].AddressFamily, SocketType.Stream, ProtocolType.Tcp); + // enable keep-alive on socket + SNITcpHandle.SetKeepAliveValues(ref sockets[i]); + sockets[i].Connect(ipAddresses[i], port); + if (sockets[i] != null) // sockets[i] can be null if cancel callback is executed during connect() { - sockets[i].Dispose(); - sockets[i] = null; + if (sockets[i].Connected) + { + availableSocket = sockets[i]; + break; + } + else + { + sockets[i].Dispose(); + sockets[i] = null; + } } } } + catch { } } - catch { } + } + finally + { + cts?.Dispose(); } return availableSocket; From 02f77850f50ad78dc671e97eb2ef7718085fc12f Mon Sep 17 00:00:00 2001 From: Karina Zhou Date: Mon, 2 Dec 2019 14:39:26 -0800 Subject: [PATCH 3/4] remove trailing whitespace --- .../src/System/Data/SqlClient/SNI/SNITcpHandle.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs index 94bd773a4f1b69..461d0e39698d45 100644 --- a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs @@ -220,7 +220,6 @@ void Cancel() cts.CancelAfter(timeout); cts.Token.Register(Cancel); } - Socket availableSocket = null; try From 7f4fc2baaa359c0e92eeeed3ce99ce2bf8b8f55f Mon Sep 17 00:00:00 2001 From: Karina Zhou Date: Mon, 2 Dec 2019 16:19:54 -0800 Subject: [PATCH 4/4] minor change to ctor --- .../src/System/Data/SqlClient/SNI/SNITcpHandle.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs index 461d0e39698d45..219809bd315bc7 100644 --- a/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs +++ b/src/libraries/System.Data.SqlClient/src/System/Data/SqlClient/SNI/SNITcpHandle.cs @@ -216,8 +216,7 @@ void Cancel() if (!isInfiniteTimeout) { - cts = new CancellationTokenSource(); - cts.CancelAfter(timeout); + cts = new CancellationTokenSource(timeout); cts.Token.Register(Cancel); }