public SNITCPHandle(string serverName, int port, long timerExpire, object callbackObject, bool parallel)
{
_writeScheduler = new ConcurrentExclusiveSchedulerPair().ExclusiveScheduler;
_writeTaskFactory = new TaskFactory(_writeScheduler);
_callbackObject = callbackObject;
_targetServer = serverName;
try
{
TimeSpan ts;
// In case the Timeout is Infinite, we will receive the max value of Int64 as the tick count
// The infinite Timeout is a function of ConnectionString Timeout=0
bool isInfiniteTimeOut = long.MaxValue == timerExpire;
if (!isInfiniteTimeOut)
{
ts = DateTime.FromFileTime(timerExpire) - DateTime.Now;
ts = ts.Ticks < 0 ? TimeSpan.FromTicks(0) : ts;
}
Task<Socket> connectTask;
if (parallel)
{
Task<IPAddress[]> serverAddrTask = Dns.GetHostAddressesAsync(serverName);
serverAddrTask.Wait(ts);
IPAddress[] serverAddresses = serverAddrTask.Result;
if (serverAddresses.Length > MaxParallelIpAddresses)
{
// Fail if above 64 to match legacy behavior
ReportTcpSNIError(0, SNICommon.MultiSubnetFailoverWithMoreThan64IPs, string.Empty);
return;
}
connectTask = ConnectAsync(serverAddresses, port);
}
else
{
connectTask = ConnectAsync(serverName, port);
}
if (!(isInfiniteTimeOut ? connectTask.Wait(-1) : connectTask.Wait(ts)))
{
ReportTcpSNIError(0, SNICommon.ConnOpenFailedError, string.Empty);
return;
}
_socket = connectTask.Result;
_socket.NoDelay = true;
_tcpStream = new NetworkStream(_socket, true);
_sslOverTdsStream = new SslOverTdsStream(_tcpStream);
_sslStream = new SslStream(_sslOverTdsStream, true, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
}
catch (SocketException se)
{
ReportTcpSNIError(se);
return;
}
catch (Exception e)
{
ReportTcpSNIError(e);
return;
}
_stream = _tcpStream;
_status = TdsEnums.SNI_SUCCESS;
}