Skip to content

Commit b251e9e

Browse files
[NetworkLibrary/MultiSocks] - Implements auto IP negotiation + modernized DirtySocks client loop.
Allows to massively simplify the first user startup procedure. Also applies the new client loop in the DirtySocks server, this will avoid some issues with blocking clients and massively boost server performance.
1 parent 63eb509 commit b251e9e

File tree

18 files changed

+200
-87
lines changed

18 files changed

+200
-87
lines changed

BackendServices/NetworkLibrary/Extension/InternetProtocolUtils.cs

+88
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Net;
77
using System.Net.NetworkInformation;
88
using System.Net.Sockets;
9+
using System.Threading.Tasks;
910
#if NET7_0_OR_GREATER
1011
using System.Net.Http;
1112
#endif
@@ -17,6 +18,8 @@ namespace NetworkLibrary.Extension
1718
{
1819
public static class InternetProtocolUtils
1920
{
21+
private static object _InternalLock = new object();
22+
2023
public static void GetIPInfos(string ipAddress, byte? cidrPrefixLength, bool detailed = false)
2124
{
2225
if (cidrPrefixLength == null || cidrPrefixLength.Value > 32 || cidrPrefixLength.Value < 8)
@@ -139,6 +142,91 @@ public static IPAddress GetLocalIPAddress(bool allowipv6 = false)
139142
return IPAddress.Loopback;
140143
}
141144

145+
public static Task<bool> TryGetServerIP(out string extractedIP, bool allowipv6 = false)
146+
{
147+
const ushort testPort = ushort.MaxValue;
148+
149+
bool isPublic = false;
150+
string ServerIP;
151+
TcpListener listener = null;
152+
153+
lock (_InternalLock)
154+
{
155+
try
156+
{
157+
listener = new TcpListener(IPAddress.Any, testPort);
158+
listener.Start();
159+
160+
if (allowipv6)
161+
{
162+
// We want to check if the router allows external IPs first.
163+
ServerIP = GetPublicIPAddress(true);
164+
try
165+
{
166+
using (TcpClient client = new TcpClient(ServerIP, testPort))
167+
client.Close();
168+
isPublic = true;
169+
}
170+
catch // Failed to connect to public ip, so we fallback to IPV4 Public IP.
171+
{
172+
ServerIP = GetPublicIPAddress();
173+
try
174+
{
175+
using (TcpClient client = new TcpClient(ServerIP, testPort))
176+
client.Close();
177+
isPublic = true;
178+
}
179+
catch // Failed to connect to public ip, so we fallback to local IP.
180+
{
181+
ServerIP = GetLocalIPAddress(true).ToString();
182+
183+
try
184+
{
185+
using (TcpClient client = new TcpClient(ServerIP, testPort))
186+
client.Close();
187+
}
188+
catch // Failed to connect to local ip, trying IPV4 only as a last resort.
189+
{
190+
ServerIP = GetLocalIPAddress().ToString();
191+
}
192+
}
193+
}
194+
}
195+
else
196+
{
197+
// We want to check if the router allows external IPs first.
198+
ServerIP = GetPublicIPAddress();
199+
try
200+
{
201+
using (TcpClient client = new TcpClient(ServerIP, testPort))
202+
client.Close();
203+
isPublic = true;
204+
}
205+
catch // Failed to connect to public ip, so we fallback to local IP.
206+
{
207+
ServerIP = GetLocalIPAddress().ToString();
208+
}
209+
}
210+
}
211+
catch
212+
{
213+
ServerIP = "127.0.0.1";
214+
}
215+
finally
216+
{
217+
if (listener != null)
218+
listener.Stop();
219+
220+
if (listener != null)
221+
listener = null;
222+
}
223+
}
224+
225+
extractedIP = ServerIP;
226+
227+
return Task.FromResult(isPublic);
228+
}
229+
142230
/// <summary>
143231
/// Get the first active IP of a given domain.
144232
/// <para>Obtiens la première IP active disponible d'un domaine.</para>

Servers/ApacheNet/SecureDNSConfigProcessor.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,19 @@ public static partial class SecureDNSConfigProcessor
2020
public static Dictionary<string, DnsSettings> DicRules = new();
2121
public static Dictionary<string, DnsSettings> StarRules = new();
2222
public static bool Initiated = false;
23+
public static IPAddress? ServerIp;
2324

2425
public static void InitDNSSubsystem()
2526
{
2627
LoggerAccessor.LogWarn("[HTTPS_DNS] - DNS system configuration is initialising, endpoints will be available when initialized...");
2728

29+
InternetProtocolUtils.TryGetServerIP(out string ServerIpStr).Wait();
30+
ServerIp = IPAddress.Parse(ServerIpStr);
31+
2832
if (!string.IsNullOrEmpty(ApacheNetServerConfiguration.DNSOnlineConfig))
2933
{
3034
LoggerAccessor.LogInfo("[HTTPS_DNS] - Downloading Configuration File...");
31-
if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32S || Environment.OSVersion.Platform == PlatformID.Win32Windows) ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
35+
if (NetworkLibrary.Extension.Windows.Win32API.IsWindows) ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
3236
try
3337
{
3438
#if NET7_0_OR_GREATER
@@ -231,13 +235,13 @@ private static string GetIp(string ip)
231235
}
232236
catch
233237
{
234-
IP = IPAddress.Parse(InternetProtocolUtils.GetPublicIPAddress());
238+
IP = ServerIp!;
235239
}
236240
break;
237241
}
238242
default:
239243
{
240-
IP = IPAddress.Parse(InternetProtocolUtils.GetPublicIPAddress());
244+
IP = ServerIp!;
241245
LoggerAccessor.LogError($"Unhandled UriHostNameType {Uri.CheckHostName(ip)} from {ip} in SecureDNSConfigProcessor.GetIp()");
242246
break;
243247
}

Servers/Horizon/DME/Config/ServerSettings.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,15 +40,15 @@ public class ServerSettings
4040
/// <summary>
4141
/// IP of the DME.
4242
/// </summary>
43-
public string DMEIp { get; set; } = InternetProtocolUtils.GetLocalIPAddress().ToString();
43+
public string DMEIp { get; set; } = InternetProtocolUtils.TryGetServerIP(out _).Result ? InternetProtocolUtils.GetPublicIPAddress() : InternetProtocolUtils.GetLocalIPAddress().ToString();
4444
#endregion
4545

4646
#region PublicIp
4747
/// <summary>
4848
/// By default the server will grab its local ip.
4949
/// If this is set, it will use its public ip instead.
5050
/// </summary>
51-
public bool UsePublicIp { get; set; } = false;
51+
public bool UsePublicIp { get; set; } = InternetProtocolUtils.TryGetServerIP(out _).Result;
5252

5353
/// <summary>
5454
/// If UsePublicIp is set to true, allow overriding and skipping using dyndns's dynamic

Servers/Horizon/MUIS/Config/ServerSettings.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ public class ServerSettings
2121
/// <summary>
2222
/// IP of the MUIS.
2323
/// </summary>
24-
public string MUISIp { get; set; } = InternetProtocolUtils.GetLocalIPAddress().ToString();
24+
public string MUISIp { get; set; } = InternetProtocolUtils.TryGetServerIP(out _).Result ? InternetProtocolUtils.GetPublicIPAddress() : InternetProtocolUtils.GetLocalIPAddress().ToString();
2525
#endregion
2626

2727
#region PublicIp
2828
/// <summary>
2929
/// By default the server will grab its local ip.
3030
/// If this is set, it will use its public ip instead.
3131
/// </summary>
32-
public bool UsePublicIp { get; set; } = false;
32+
public bool UsePublicIp { get; set; } = InternetProtocolUtils.TryGetServerIP(out _).Result;
3333

3434
/// <summary>
3535
/// If UsePublicIp is set to true, allow overriding and skipping using dyndns's dynamic

Servers/Horizon/Program.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public static class HorizonServerConfiguration
3131
public static string? BWPSConfig { get; set; } = $"{Directory.GetCurrentDirectory()}/static/bwps.json";
3232
public static string? NATConfig { get; set; } = $"{Directory.GetCurrentDirectory()}/static/nat.json";
3333
public static string MediusAPIKey { get; set; } = NetworkLibrary.Crypto.WebCrypto.GenerateRandomBase64KeyAsync().Result;
34-
public static string SSFWUrl { get; set; } = $"http://{InternetProtocolUtils.GetLocalIPAddress().ToString()}:8080";
34+
public static string SSFWUrl { get; set; } = $"http://{(InternetProtocolUtils.TryGetServerIP(out _).Result ? InternetProtocolUtils.GetPublicIPAddress() : InternetProtocolUtils.GetLocalIPAddress().ToString())}:8080";
3535
public static string[]? HTTPSDNSList { get; set; }
3636

3737
public static DbController Database = new(DatabaseConfig);

Servers/Horizon/SERVER/Config/ServerSettings.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,15 @@ public class ServerSettings
1616
/// <summary>
1717
/// IP of the MEDIUS.
1818
/// </summary>
19-
public string MEDIUSIp { get; set; } = InternetProtocolUtils.GetLocalIPAddress().ToString();
19+
public string MEDIUSIp { get; set; } = InternetProtocolUtils.TryGetServerIP(out _).Result ? InternetProtocolUtils.GetPublicIPAddress() : InternetProtocolUtils.GetLocalIPAddress().ToString();
2020
#endregion
2121

2222
#region PublicIp
2323
/// <summary>
2424
/// By default the server will grab its local ip.
2525
/// If this is set, it will use its public ip instead.
2626
/// </summary>
27-
public bool UsePublicIp { get; set; } = false;
27+
public bool UsePublicIp { get; set; } = InternetProtocolUtils.TryGetServerIP(out _).Result;
2828

2929
/// <summary>
3030
/// If UsePublicIp is set to true, allow overriding and skipping using dyndns's dynamic

Servers/MitmDNS/DNSConfigProcessor.cs

+7-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using System.Net.Security;
1212
using System.Security.Cryptography.X509Certificates;
1313
using System.Text.RegularExpressions;
14-
using System.Threading;
1514
using System.Threading.Tasks;
1615

1716
namespace MitmDNS
@@ -21,15 +20,19 @@ public static partial class DNSConfigProcessor
2120
public static Dictionary<string, DnsSettings> DicRules = new();
2221
public static Dictionary<string, DnsSettings> StarRules = new();
2322
public static bool Initiated = false;
23+
public static IPAddress ServerIp;
2424

2525
public static void InitDNSSubsystem()
2626
{
2727
LoggerAccessor.LogWarn("[DNS] - DNS system configuration is initialising, endpoints will be available when initialized...");
2828

29+
InternetProtocolUtils.TryGetServerIP(out string ServerIpStr).Wait();
30+
ServerIp = IPAddress.Parse(ServerIpStr);
31+
2932
if (!string.IsNullOrEmpty(MitmDNSServerConfiguration.DNSOnlineConfig))
3033
{
3134
LoggerAccessor.LogInfo("[DNS] - Downloading Configuration File...");
32-
if (Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Platform == PlatformID.Win32S || Environment.OSVersion.Platform == PlatformID.Win32Windows) ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
35+
if (NetworkLibrary.Extension.Windows.Win32API.IsWindows) ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
3336
try
3437
{
3538
#if NET7_0_OR_GREATER
@@ -232,19 +235,13 @@ private static string GetIp(string ip)
232235
}
233236
catch
234237
{
235-
if (MitmDNSServerConfiguration.PublicIpFallback)
236-
IP = IPAddress.Parse(InternetProtocolUtils.GetPublicIPAddress());
237-
else
238-
IP = InternetProtocolUtils.GetLocalIPAddress();
238+
IP = ServerIp;
239239
}
240240
break;
241241
}
242242
default:
243243
{
244-
if (MitmDNSServerConfiguration.PublicIpFallback)
245-
IP = IPAddress.Parse(InternetProtocolUtils.GetPublicIPAddress());
246-
else
247-
IP = InternetProtocolUtils.GetLocalIPAddress();
244+
IP = ServerIp;
248245
LoggerAccessor.LogError($"Unhandled UriHostNameType {Uri.CheckHostName(ip)} from {ip} in MitmDNSClass.GetIp()");
249246
break;
250247
}

Servers/MitmDNS/Program.cs

+1-7
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ public static class MitmDNSServerConfiguration
1414
{
1515
public static string DNSConfig { get; set; } = $"{Directory.GetCurrentDirectory()}/static/routes.txt";
1616
public static string DNSOnlineConfig { get; set; } = string.Empty;
17-
public static bool PublicIpFallback { get; set; } = true;
1817
public static bool DNSAllowUnsafeRequests { get; set; } = true;
1918
public static bool EnableAdguardFiltering { get; set; } = false;
2019
public static bool EnableDanPollockHosts { get; set; } = false;
@@ -39,7 +38,6 @@ public static void RefreshVariables(string configPath)
3938
File.WriteAllText(configPath, new JObject(
4039
new JProperty("online_routes_config", DNSOnlineConfig),
4140
new JProperty("routes_config", DNSConfig),
42-
new JProperty("public_ip_fallback", PublicIpFallback),
4341
new JProperty("allow_unsafe_requests", DNSAllowUnsafeRequests),
4442
new JProperty("enable_adguard_filtering", EnableAdguardFiltering),
4543
new JProperty("enable_dan_pollock_hosts", EnableDanPollockHosts),
@@ -56,7 +54,6 @@ public static void RefreshVariables(string configPath)
5654

5755
DNSOnlineConfig = GetValueOrDefault(config, "online_routes_config", DNSOnlineConfig);
5856
DNSConfig = GetValueOrDefault(config, "routes_config", DNSConfig);
59-
PublicIpFallback = GetValueOrDefault(config, "public_ip_fallback", PublicIpFallback);
6057
DNSAllowUnsafeRequests = GetValueOrDefault(config, "allow_unsafe_requests", DNSAllowUnsafeRequests);
6158
EnableAdguardFiltering = GetValueOrDefault(config, "enable_adguard_filtering", EnableAdguardFiltering);
6259
EnableDanPollockHosts = GetValueOrDefault(config, "enable_dan_pollock_hosts", EnableDanPollockHosts);
@@ -183,10 +180,7 @@ private static void StartOrUpdateServer()
183180
}
184181
}
185182

186-
if (MitmDNSServerConfiguration.PublicIpFallback)
187-
DNSResolver.ServerIp = InternetProtocolUtils.GetPublicIPAddress();
188-
else
189-
DNSResolver.ServerIp = InternetProtocolUtils.GetLocalIPAddress().ToString();
183+
_ = InternetProtocolUtils.TryGetServerIP(out DNSResolver.ServerIp);
190184

191185
if (Server == null)
192186
Server = new(Environment.ProcessorCount * 4);

0 commit comments

Comments
 (0)