@@ -324,36 +324,43 @@ private Socket TryConnectParallel(string hostName, int port, TimeSpan ts, bool i
324324 // Only write to the DNS cache when we receive IsSupported flag as true in the Feature Ext Ack from server.
325325 private static Socket Connect ( string serverName , int port , TimeSpan timeout , bool isInfiniteTimeout , SqlConnectionIPAddressPreference ipPreference , string cachedFQDN , ref SQLDNSInfo pendingDNSInfo )
326326 {
327- // keeping IEnumerable to enumerate entire array only if needed
328- IEnumerable < IPAddress > ipAddresses = Dns . GetHostAddresses ( serverName ) ;
329-
330- // First, we try to connect all AddressFamily.InterNetwork
331- // and then all AddressFamily.InterNetworkV6.
332- // Keeping address families inlined in entire method because parameter pendingDNSInfo is bound on them.
333- ipAddresses = ipAddresses
334- . Where ( address => address . AddressFamily == AddressFamily . InterNetwork )
335- . Concat ( ipAddresses . Where ( address => address . AddressFamily == AddressFamily . InterNetworkV6 ) ) ;
327+ SqlClientEventSource . Log . TrySNITraceEvent ( s_className , EventType . INFO , "IP preference : {0}" , Enum . GetName ( typeof ( SqlConnectionIPAddressPreference ) , ipPreference ) ) ;
336328
337329 Stopwatch timeTaken = Stopwatch . StartNew ( ) ;
338330
331+ IEnumerable < IPAddress > ipAddresses = Dns . GetHostAddresses ( serverName ) . Where ( address =>
332+ address . AddressFamily is AddressFamily . InterNetwork or AddressFamily . InterNetworkV6 ) ;
333+
334+ ipAddresses = ipPreference switch
335+ {
336+ SqlConnectionIPAddressPreference . IPv4First => ipAddresses . OrderByDescending ( address =>
337+ address . AddressFamily == AddressFamily . InterNetwork ) ,
338+ SqlConnectionIPAddressPreference . IPv6First => ipAddresses . OrderByDescending ( address =>
339+ address . AddressFamily == AddressFamily . InterNetworkV6 ) ,
340+ SqlConnectionIPAddressPreference . UsePlatformDefault => ipAddresses ,
341+ _ => throw new ArgumentOutOfRangeException ( nameof ( ipPreference ) , ipPreference , null )
342+ } ;
343+
339344 foreach ( IPAddress ipAddress in ipAddresses )
340345 {
341346 var socket =
342- new Socket ( ipAddress . AddressFamily , SocketType . Stream , ProtocolType . Tcp ) { Blocking = false } ;
347+ new Socket ( ipAddress . AddressFamily , SocketType . Stream , ProtocolType . Tcp ) { Blocking = false } ;
343348
344- bool thisSocketSelected = false ;
349+ bool isSocketSelected = false ;
345350
346351 // enable keep-alive on socket
347352 SetKeepAliveValues ( ref socket ) ;
348353
349354 SqlClientEventSource . Log . TrySNITraceEvent ( s_className , EventType . INFO ,
350- "Connecting to IP address {0} and port {1}" , ipAddress , port ) ;
355+ "Connecting to IP address {0} and port {1} using {2} address family." , ipAddress ,
356+ port , ipAddress . AddressFamily ) ;
351357
352358 try
353359 {
354360 socket . Connect ( ipAddress , port ) ;
355361 throw new InternalException (
356- $ "Call to { nameof ( Socket . Connect ) } must throw { nameof ( SocketException ) } with { SocketError . WouldBlock . ToString ( ) } error code") ;
362+ $ "Call to { nameof ( Socket . Connect ) } must throw { nameof ( SocketException ) } " +
363+ $ "with { SocketError . WouldBlock . ToString ( ) } error code") ;
357364 }
358365 catch ( SocketException socketException ) when ( socketException . SocketErrorCode ==
359366 SocketError . WouldBlock )
@@ -374,7 +381,7 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo
374381
375382 if ( socket . Connected )
376383 {
377- thisSocketSelected = true ;
384+ isSocketSelected = true ;
378385 socket . Blocking = true ;
379386 string iPv4String = null ;
380387 string iPv6String = null ;
@@ -388,7 +395,7 @@ private static Socket Connect(string serverName, int port, TimeSpan timeout, boo
388395 }
389396 finally
390397 {
391- if ( ! thisSocketSelected )
398+ if ( ! isSocketSelected )
392399 socket . Dispose ( ) ;
393400 }
394401 }
0 commit comments