@@ -1713,60 +1713,80 @@ await Dns.GetHostAddressesAsync(context.DnsEndPoint.Host, cancellationToken).Con
17131713 socket . SetSocketOption ( SocketOptionLevel . Tcp , SocketOptionName . TcpKeepAliveInterval , keepAlive . Interval ) ;
17141714 }
17151715
1716- BindHelper ( servicePoint , addresses , socket , context . DnsEndPoint . Port ) ;
1717- static void BindHelper ( ServicePoint servicePoint , IPAddress [ ] addresses , Socket socket , int port )
1718- {
1719- if ( servicePoint . BindIPEndPointDelegate is null )
1720- {
1721- return ;
1722- }
1716+ socket . NoDelay = ! servicePoint . UseNagleAlgorithm ;
17231717
1724- const int MaxRetries = 100 ;
1718+ if ( servicePoint . BindIPEndPointDelegate is not null )
1719+ {
17251720 foreach ( IPAddress address in addresses )
17261721 {
1727- int retryCount = 0 ;
1728- for ( ; retryCount < MaxRetries ; retryCount ++ )
1722+ IPEndPoint remoteEp = new IPEndPoint ( address , context . DnsEndPoint . Port ) ;
1723+ BindHelper ( servicePoint , remoteEp , socket ) ;
1724+ if ( parameters . Async )
1725+ {
1726+ await socket . ConnectAsync ( remoteEp , cancellationToken ) . ConfigureAwait ( false ) ;
1727+ }
1728+ else
17291729 {
1730- IPEndPoint ? endPoint = servicePoint . BindIPEndPointDelegate ( servicePoint , new IPEndPoint ( address , port ) , retryCount ) ;
1731- if ( endPoint is null ) // Get other address to try
1730+ using ( cancellationToken . UnsafeRegister ( s => ( ( Socket ) s ! ) . Dispose ( ) , socket ) )
17321731 {
1733- break ;
1732+ socket . Connect ( remoteEp ) ;
17341733 }
17351734
1736- try
1737- {
1738- socket . Bind ( endPoint ) ;
1739- return ; // Bind successful, exit loops.
1740- }
1741- catch
1742- {
1743- continue ;
1744- }
1735+ // Throw in case cancellation caused the socket to be disposed after the Connect completed
1736+ cancellationToken . ThrowIfCancellationRequested ( ) ;
1737+ }
1738+ }
1739+ }
1740+ static void BindHelper ( ServicePoint servicePoint , IPEndPoint remoteEp , Socket socket )
1741+ {
1742+ const int MaxRetries = 100 ;
1743+ int retryCount = 0 ;
1744+ for ( ; retryCount < MaxRetries ; retryCount ++ )
1745+ {
1746+ IPEndPoint ? endPoint = servicePoint . BindIPEndPointDelegate ! ( servicePoint , remoteEp , retryCount ) ;
1747+ if ( endPoint is null ) // Get other address to try
1748+ {
1749+ return ;
17451750 }
17461751
1747- if ( retryCount >= MaxRetries )
1752+ try
1753+ {
1754+ socket . Bind ( endPoint ) ;
1755+ return ;
1756+ }
1757+ catch
17481758 {
1749- throw new OverflowException ( SR . net_maximumbindretries ) ;
1759+ continue ;
17501760 }
17511761 }
1762+
1763+ if ( retryCount >= MaxRetries )
1764+ {
1765+ throw new OverflowException ( SR . net_maximumbindretries ) ;
1766+ }
17521767 }
17531768 }
1754-
1755- socket . NoDelay = ! ( parameters . ServicePoint ? . UseNagleAlgorithm ) ?? true ;
1756-
1757- if ( parameters . Async )
1769+ else
17581770 {
1759- await socket . ConnectAsync ( addresses , context . DnsEndPoint . Port , cancellationToken ) . ConfigureAwait ( false ) ;
1771+ socket . NoDelay = true ;
17601772 }
1761- else
1773+
1774+ if ( ! socket . Connected )
17621775 {
1763- using ( cancellationToken . UnsafeRegister ( s => ( ( Socket ) s ! ) . Dispose ( ) , socket ) )
1776+ if ( parameters . Async )
17641777 {
1765- socket . Connect ( addresses , context . DnsEndPoint . Port ) ;
1778+ await socket . ConnectAsync ( addresses , context . DnsEndPoint . Port , cancellationToken ) . ConfigureAwait ( false ) ;
17661779 }
1780+ else
1781+ {
1782+ using ( cancellationToken . UnsafeRegister ( s => ( ( Socket ) s ! ) . Dispose ( ) , socket ) )
1783+ {
1784+ socket . Connect ( addresses , context . DnsEndPoint . Port ) ;
1785+ }
17671786
1768- // Throw in case cancellation caused the socket to be disposed after the Connect completed
1769- cancellationToken . ThrowIfCancellationRequested ( ) ;
1787+ // Throw in case cancellation caused the socket to be disposed after the Connect completed
1788+ cancellationToken . ThrowIfCancellationRequested ( ) ;
1789+ }
17701790 }
17711791
17721792 if ( parameters . ReadWriteTimeout > 0 ) // default is 5 minutes, so this is generally going to be true
0 commit comments