@@ -288,7 +288,7 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
288288 {
289289 // deny connection to proxy end points to avoid infinite connection loop.
290290 if ( Server . ProxyEndPoints . Any ( x => x . Port == remotePort )
291- && NetworkHelper . IsLocalIpAddress ( remoteHostName ) )
291+ && NetworkHelper . IsLocalIpAddress ( remoteHostName ) )
292292 {
293293 throw new Exception ( $ "A client is making HTTP request to one of the listening ports of this proxy { remoteHostName } :{ remotePort } ") ;
294294 }
@@ -334,14 +334,14 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
334334 bool retry = true ;
335335 var enabledSslProtocols = sslProtocol ;
336336
337- retry :
337+ retry :
338338 try
339339 {
340340 bool socks = externalProxy != null && externalProxy . ProxyType != ExternalProxyType . Http ;
341341 string hostname = remoteHostName ;
342342 int port = remotePort ;
343343
344- if ( externalProxy != null && externalProxy . ProxyType == ExternalProxyType . Http )
344+ if ( externalProxy != null )
345345 {
346346 hostname = externalProxy . HostName ;
347347 port = externalProxy . Port ;
@@ -375,8 +375,7 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
375375 ? ProxyTypes . Socks4
376376 : ProxyTypes . Socks5 ;
377377
378- var proxyIpAddresses = await Dns . GetHostAddressesAsync ( externalProxy . HostName ) ;
379- proxySocket . ProxyEndPoint = new IPEndPoint ( proxyIpAddresses [ 0 ] , externalProxy . Port ) ;
378+ proxySocket . ProxyEndPoint = new IPEndPoint ( ipAddresses [ 0 ] , port ) ;
380379 if ( ! string . IsNullOrEmpty ( externalProxy . UserName ) && externalProxy . Password != null )
381380 {
382381 proxySocket . ProxyUser = externalProxy . UserName ;
@@ -405,9 +404,31 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
405404 tcpServerSocket . SetSocketOption ( SocketOptionLevel . Socket , SocketOptionName . ReuseAddress , true ) ;
406405 }
407406
408- var connectTask = socks
409- ? ProxySocketConnectionTaskFactory . CreateTask ( ( ProxySocket . ProxySocket ) tcpServerSocket , ipAddress , port )
410- : SocketConnectionTaskFactory . CreateTask ( tcpServerSocket , ipAddress , port ) ;
407+ Task connectTask ;
408+
409+ if ( socks )
410+ {
411+ if ( externalProxy ! . ProxyDnsRequests )
412+ {
413+ connectTask = ProxySocketConnectionTaskFactory . CreateTask ( ( ProxySocket . ProxySocket ) tcpServerSocket , remoteHostName , remotePort ) ;
414+ }
415+ else
416+ {
417+ // todo: resolve only once when the SOCKS proxy has multiple addresses (and the first address fails)
418+ var remoteIpAddresses = await Dns . GetHostAddressesAsync ( remoteHostName ) ;
419+ if ( remoteIpAddresses == null || remoteIpAddresses . Length == 0 )
420+ {
421+ throw new Exception ( $ "Could not resolve the SOCKS remote hostname { remoteHostName } ") ;
422+ }
423+
424+ // todo: use the 2nd, 3rd... remote addresses when first fails
425+ connectTask = ProxySocketConnectionTaskFactory . CreateTask ( ( ProxySocket . ProxySocket ) tcpServerSocket , remoteIpAddresses [ 0 ] , remotePort ) ;
426+ }
427+ }
428+ else
429+ {
430+ connectTask = SocketConnectionTaskFactory . CreateTask ( tcpServerSocket , ipAddress , port ) ;
431+ }
411432
412433 await Task . WhenAny ( connectTask , Task . Delay ( proxyServer . ConnectTimeOutSeconds * 1000 , cancellationToken ) ) ;
413434 if ( ! connectTask . IsCompleted || ! tcpServerSocket . Connected )
@@ -423,6 +444,7 @@ private async Task<TcpServerConnection> createServerConnection(string remoteHost
423444 {
424445 // ignore
425446 }
447+
426448 try
427449 {
428450#if NET45
@@ -741,6 +763,7 @@ public void Dispose()
741763 }
742764 }
743765 }
766+
744767 cache . Clear ( ) ;
745768 }
746769 finally
@@ -784,6 +807,12 @@ static IAsyncResult beginConnect(IPAddress address, int port, AsyncCallback requ
784807 return ( ( ProxySocket . ProxySocket ) state ) . BeginConnect ( address , port , requestCallback , state ) ;
785808 }
786809
810+ static IAsyncResult beginConnect ( string hostName , int port , AsyncCallback requestCallback ,
811+ object state )
812+ {
813+ return ( ( ProxySocket . ProxySocket ) state ) . BeginConnect ( hostName , port , requestCallback , state ) ;
814+ }
815+
787816 static void endConnect ( IAsyncResult asyncResult )
788817 {
789818 ( ( ProxySocket . ProxySocket ) asyncResult . AsyncState ) . EndConnect ( asyncResult ) ;
@@ -793,6 +822,11 @@ public static Task CreateTask(ProxySocket.ProxySocket socket, IPAddress ipAddres
793822 {
794823 return Task . Factory . FromAsync ( beginConnect , endConnect , ipAddress , port , state : socket ) ;
795824 }
825+
826+ public static Task CreateTask ( ProxySocket . ProxySocket socket , string hostName , int port )
827+ {
828+ return Task . Factory . FromAsync ( beginConnect , endConnect , hostName , port , state : socket ) ;
829+ }
796830 }
797831 }
798832}
0 commit comments