Skip to content

Commit

Permalink
Merge from main branch:
Browse files Browse the repository at this point in the history
* address family is choosen by preferences
* ipAdress enumeration returned back to n^2 for readability
* variable renamed to isSocketSelected
  • Loading branch information
Evgeny Gorbovoy authored and Evgeny Gorbovoy committed Jun 28, 2021
1 parent e3e64d3 commit 0dcd8ca
Showing 1 changed file with 22 additions and 15 deletions.
Expand Up @@ -324,36 +324,43 @@ private Socket TryConnectParallel(string hostName, int port, TimeSpan ts, bool i
// Only write to the DNS cache when we receive IsSupported flag as true in the Feature Ext Ack from server.
private static Socket Connect(string serverName, int port, TimeSpan timeout, bool isInfiniteTimeout, SqlConnectionIPAddressPreference ipPreference, string cachedFQDN, ref SQLDNSInfo pendingDNSInfo)
{
// keeping IEnumerable to enumerate entire array only if needed
IEnumerable<IPAddress> ipAddresses = Dns.GetHostAddresses(serverName);

// First, we try to connect all AddressFamily.InterNetwork
// and then all AddressFamily.InterNetworkV6.
// Keeping address families inlined in entire method because parameter pendingDNSInfo is bound on them.
ipAddresses = ipAddresses
.Where (address => address.AddressFamily==AddressFamily.InterNetwork)
.Concat(ipAddresses.Where(address => address.AddressFamily==AddressFamily.InterNetworkV6));
SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO, "IP preference : {0}", Enum.GetName(typeof(SqlConnectionIPAddressPreference), ipPreference));

Stopwatch timeTaken = Stopwatch.StartNew();

IEnumerable<IPAddress> ipAddresses = Dns.GetHostAddresses(serverName).Where(address =>
address.AddressFamily is AddressFamily.InterNetwork or AddressFamily.InterNetworkV6);

ipAddresses = ipPreference switch
{
SqlConnectionIPAddressPreference.IPv4First => ipAddresses.OrderByDescending(address =>
address.AddressFamily == AddressFamily.InterNetwork),
SqlConnectionIPAddressPreference.IPv6First => ipAddresses.OrderByDescending(address =>
address.AddressFamily == AddressFamily.InterNetworkV6),
SqlConnectionIPAddressPreference.UsePlatformDefault => ipAddresses,
_ => throw new ArgumentOutOfRangeException(nameof(ipPreference), ipPreference, null)
};

foreach (IPAddress ipAddress in ipAddresses)
{
var socket =
new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp) {Blocking = false};
new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp) { Blocking = false };

bool thisSocketSelected = false;
bool isSocketSelected = false;

// enable keep-alive on socket
SetKeepAliveValues(ref socket);

SqlClientEventSource.Log.TrySNITraceEvent(s_className, EventType.INFO,
"Connecting to IP address {0} and port {1}", ipAddress, port);
"Connecting to IP address {0} and port {1} using {2} address family.", ipAddress,
port, ipAddress.AddressFamily);

try
{
socket.Connect(ipAddress, port);
throw new InternalException(
$"Call to {nameof(Socket.Connect)} must throw {nameof(SocketException)} with {SocketError.WouldBlock.ToString()} error code");
$"Call to {nameof(Socket.Connect)} must throw {nameof(SocketException)} " +
$"with {SocketError.WouldBlock.ToString()} error code");
}
catch (SocketException socketException) when (socketException.SocketErrorCode ==
SocketError.WouldBlock)
Expand All @@ -374,7 +381,7 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo

if (socket.Connected)
{
thisSocketSelected = true;
isSocketSelected = true;
socket.Blocking = true;
string iPv4String = null;
string iPv6String = null;
Expand All @@ -388,7 +395,7 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo
}
finally
{
if (!thisSocketSelected)
if (!isSocketSelected)
socket.Dispose();
}
}
Expand Down

0 comments on commit 0dcd8ca

Please sign in to comment.