Skip to content
This repository was archived by the owner on Jul 9, 2023. It is now read-only.

Commit 4843bce

Browse files
committed
proxy dns request for socks
1 parent a628c99 commit 4843bce

File tree

3 files changed

+46
-8
lines changed

3 files changed

+46
-8
lines changed

src/Titanium.Web.Proxy/Models/ExternalProxy.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ public class ExternalProxy : IExternalProxy
2727

2828
public ExternalProxyType ProxyType { get; set; }
2929

30+
public bool ProxyDnsRequests { get; set; }
31+
3032
/// <summary>
3133
/// Username.
3234
/// </summary>

src/Titanium.Web.Proxy/Models/IExternalProxy.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ public interface IExternalProxy
1414

1515
ExternalProxyType ProxyType { get; set; }
1616

17+
bool ProxyDnsRequests { get; set; }
18+
1719
/// <summary>
1820
/// Username.
1921
/// </summary>

src/Titanium.Web.Proxy/Network/Tcp/TcpConnectionFactory.cs

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)