mirror of
https://github.com/2dust/v2rayN.git
synced 2026-04-16 12:35:46 +00:00
Merge c37ad5f156 into 3bda022574
This commit is contained in:
commit
aacc588b3f
17 changed files with 208 additions and 284 deletions
|
|
@ -75,9 +75,7 @@ public class CoreConfigV2rayServiceTests
|
||||||
var service = new CoreConfigV2rayService(CreateContext(
|
var service = new CoreConfigV2rayService(CreateContext(
|
||||||
node,
|
node,
|
||||||
config,
|
config,
|
||||||
isTunEnabled: true,
|
isTunEnabled: true));
|
||||||
tunProtectSsPort: 10811,
|
|
||||||
proxyRelaySsPort: 10812));
|
|
||||||
|
|
||||||
var result = service.GenerateClientConfigContent();
|
var result = service.GenerateClientConfigContent();
|
||||||
|
|
||||||
|
|
@ -91,9 +89,7 @@ public class CoreConfigV2rayServiceTests
|
||||||
ProfileItem node,
|
ProfileItem node,
|
||||||
Config? config = null,
|
Config? config = null,
|
||||||
Dictionary<string, ProfileItem>? allProxiesMap = null,
|
Dictionary<string, ProfileItem>? allProxiesMap = null,
|
||||||
bool isTunEnabled = false,
|
bool isTunEnabled = false)
|
||||||
int tunProtectSsPort = 0,
|
|
||||||
int proxyRelaySsPort = 0)
|
|
||||||
{
|
{
|
||||||
return new CoreConfigContext
|
return new CoreConfigContext
|
||||||
{
|
{
|
||||||
|
|
@ -103,8 +99,6 @@ public class CoreConfigV2rayServiceTests
|
||||||
AllProxiesMap = allProxiesMap ?? new(),
|
AllProxiesMap = allProxiesMap ?? new(),
|
||||||
SimpleDnsItem = new SimpleDNSItem(),
|
SimpleDnsItem = new SimpleDNSItem(),
|
||||||
IsTunEnabled = isTunEnabled,
|
IsTunEnabled = isTunEnabled,
|
||||||
TunProtectSocksPort = tunProtectSsPort,
|
|
||||||
ProxyRelaySocksPort = proxyRelaySsPort,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -53,19 +53,23 @@ internal static class WindowsUtils
|
||||||
|
|
||||||
public static async Task RemoveTunDevice()
|
public static async Task RemoveTunDevice()
|
||||||
{
|
{
|
||||||
try
|
var tunNameList = new List<string> { "singbox_tun", "xray_tun" };
|
||||||
|
foreach (var tunName in tunNameList)
|
||||||
{
|
{
|
||||||
var sum = MD5.HashData(Encoding.UTF8.GetBytes("wintunsingbox_tun"));
|
try
|
||||||
var guid = new Guid(sum);
|
{
|
||||||
var pnpUtilPath = @"C:\Windows\System32\pnputil.exe";
|
var sum = MD5.HashData(Encoding.UTF8.GetBytes($"wintun{tunName}"));
|
||||||
var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
|
var guid = new Guid(sum);
|
||||||
|
var pnpUtilPath = @"C:\Windows\System32\pnputil.exe";
|
||||||
|
var arg = $$""" /remove-device "SWD\Wintun\{{{guid}}}" """;
|
||||||
|
|
||||||
// Try to remove the device
|
// Try to remove the device
|
||||||
_ = await Utils.GetCliWrapOutput(pnpUtilPath, arg);
|
_ = await Utils.GetCliWrapOutput(pnpUtilPath, arg);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Logging.SaveLog(_tag, ex);
|
Logging.SaveLog(_tag, ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,8 @@ public class Global
|
||||||
public const string V2raySampleHttpResponseFileName = NamespaceSample + "SampleHttpResponse";
|
public const string V2raySampleHttpResponseFileName = NamespaceSample + "SampleHttpResponse";
|
||||||
public const string V2raySampleInbound = NamespaceSample + "SampleInbound";
|
public const string V2raySampleInbound = NamespaceSample + "SampleInbound";
|
||||||
public const string V2raySampleOutbound = NamespaceSample + "SampleOutbound";
|
public const string V2raySampleOutbound = NamespaceSample + "SampleOutbound";
|
||||||
|
public const string V2raySampleTunInbound = NamespaceSample + "SampleTunInbound";
|
||||||
|
public const string V2raySampleTunRules = NamespaceSample + "SampleTunRules";
|
||||||
public const string SingboxSampleOutbound = NamespaceSample + "SingboxSampleOutbound";
|
public const string SingboxSampleOutbound = NamespaceSample + "SingboxSampleOutbound";
|
||||||
public const string CustomRoutingFileName = NamespaceSample + "custom_routing_";
|
public const string CustomRoutingFileName = NamespaceSample + "custom_routing_";
|
||||||
public const string TunSingboxDNSFileName = NamespaceSample + "tun_singbox_dns";
|
public const string TunSingboxDNSFileName = NamespaceSample + "tun_singbox_dns";
|
||||||
|
|
@ -48,6 +50,7 @@ public class Global
|
||||||
public const string ProxyTag = "proxy";
|
public const string ProxyTag = "proxy";
|
||||||
public const string DirectTag = "direct";
|
public const string DirectTag = "direct";
|
||||||
public const string BlockTag = "block";
|
public const string BlockTag = "block";
|
||||||
|
public const string DnsOutboundTag = "dns";
|
||||||
public const string DnsTag = "dns-module";
|
public const string DnsTag = "dns-module";
|
||||||
public const string DirectDnsTag = "direct-dns";
|
public const string DirectDnsTag = "direct-dns";
|
||||||
public const string BalancerTagSuffix = "-round";
|
public const string BalancerTagSuffix = "-round";
|
||||||
|
|
|
||||||
|
|
@ -23,19 +23,6 @@ public record CoreConfigContextBuilderAllResult(
|
||||||
public NodeValidatorResult CombinedValidatorResult => new(
|
public NodeValidatorResult CombinedValidatorResult => new(
|
||||||
[.. MainResult.ValidatorResult.Errors, .. PreSocksResult?.ValidatorResult.Errors ?? []],
|
[.. MainResult.ValidatorResult.Errors, .. PreSocksResult?.ValidatorResult.Errors ?? []],
|
||||||
[.. MainResult.ValidatorResult.Warnings, .. PreSocksResult?.ValidatorResult.Warnings ?? []]);
|
[.. MainResult.ValidatorResult.Warnings, .. PreSocksResult?.ValidatorResult.Warnings ?? []]);
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The main context with TunProtectSocksPort/ProxyRelaySocksPort and ProtectDomainList merged in
|
|
||||||
/// from the pre-socks result (if any). Pass this to the core runner.
|
|
||||||
/// </summary>
|
|
||||||
public CoreConfigContext ResolvedMainContext => PreSocksResult is not null
|
|
||||||
? MainResult.Context with
|
|
||||||
{
|
|
||||||
TunProtectSocksPort = PreSocksResult.Context.TunProtectSocksPort,
|
|
||||||
ProxyRelaySocksPort = PreSocksResult.Context.ProxyRelaySocksPort,
|
|
||||||
ProtectDomainList = [.. MainResult.Context.ProtectDomainList ?? [], .. PreSocksResult.Context.ProtectDomainList ?? []],
|
|
||||||
}
|
|
||||||
: MainResult.Context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CoreConfigContextBuilder
|
public class CoreConfigContextBuilder
|
||||||
|
|
@ -58,8 +45,6 @@ public class CoreConfigContextBuilder
|
||||||
IsTunEnabled = config.TunModeItem.EnableTun,
|
IsTunEnabled = config.TunModeItem.EnableTun,
|
||||||
SimpleDnsItem = config.SimpleDNSItem,
|
SimpleDnsItem = config.SimpleDNSItem,
|
||||||
ProtectDomainList = [],
|
ProtectDomainList = [],
|
||||||
TunProtectSocksPort = 0,
|
|
||||||
ProxyRelaySocksPort = 0,
|
|
||||||
RawDnsItem = await AppManager.Instance.GetDNSItem(coreType),
|
RawDnsItem = await AppManager.Instance.GetDNSItem(coreType),
|
||||||
RoutingItem = await ConfigHandler.GetDefaultRouting(config),
|
RoutingItem = await ConfigHandler.GetDefaultRouting(config),
|
||||||
};
|
};
|
||||||
|
|
@ -122,7 +107,20 @@ public class CoreConfigContextBuilder
|
||||||
}
|
}
|
||||||
|
|
||||||
var preResult = await BuildPreSocksIfNeeded(mainResult.Context);
|
var preResult = await BuildPreSocksIfNeeded(mainResult.Context);
|
||||||
return new CoreConfigContextBuilderAllResult(mainResult, preResult);
|
if (preResult is null)
|
||||||
|
{
|
||||||
|
return new CoreConfigContextBuilderAllResult(mainResult, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
var resolvedMainResult = mainResult with
|
||||||
|
{
|
||||||
|
Context = mainResult.Context with
|
||||||
|
{
|
||||||
|
IsTunEnabled = false, // main core doesn't handle tun directly when pre-socks is used
|
||||||
|
ProtectDomainList = [.. mainResult.Context.ProtectDomainList, .. preResult.Context.ProtectDomainList],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new CoreConfigContextBuilderAllResult(resolvedMainResult, preResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -148,32 +146,7 @@ public class CoreConfigContextBuilder
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nodeContext.IsTunEnabled
|
return null;
|
||||||
|| coreType != ECoreType.Xray
|
|
||||||
|| node.ConfigType == EConfigType.Custom)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tunProtectSocksPort = Utils.GetFreePort();
|
|
||||||
var proxyRelaySocksPort = Utils.GetFreePort();
|
|
||||||
var preItem = new ProfileItem()
|
|
||||||
{
|
|
||||||
CoreType = ECoreType.sing_box,
|
|
||||||
ConfigType = EConfigType.SOCKS,
|
|
||||||
Address = Global.Loopback,
|
|
||||||
Port = proxyRelaySocksPort,
|
|
||||||
};
|
|
||||||
var preResult2 = await Build(nodeContext.AppConfig, preItem);
|
|
||||||
return preResult2 with
|
|
||||||
{
|
|
||||||
Context = preResult2.Context with
|
|
||||||
{
|
|
||||||
ProtectDomainList = [.. nodeContext.ProtectDomainList ?? [], .. preResult2.Context.ProtectDomainList ?? []],
|
|
||||||
TunProtectSocksPort = tunProtectSocksPort,
|
|
||||||
ProxyRelaySocksPort = proxyRelaySocksPort,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1417,10 +1417,12 @@ public static class ConfigHandler
|
||||||
public static ProfileItem? GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType)
|
public static ProfileItem? GetPreSocksItem(Config config, ProfileItem node, ECoreType coreType)
|
||||||
{
|
{
|
||||||
ProfileItem? itemSocks = null;
|
ProfileItem? itemSocks = null;
|
||||||
|
var enableLegacyProtect = config.TunModeItem.EnableLegacyProtect
|
||||||
|
|| Utils.IsNonWindows();
|
||||||
if (node.ConfigType != EConfigType.Custom
|
if (node.ConfigType != EConfigType.Custom
|
||||||
&& coreType != ECoreType.sing_box
|
&& coreType != ECoreType.sing_box
|
||||||
&& config.TunModeItem.EnableTun
|
&& config.TunModeItem.EnableTun
|
||||||
&& config.TunModeItem.EnableLegacyProtect)
|
&& enableLegacyProtect)
|
||||||
{
|
{
|
||||||
itemSocks = new ProfileItem()
|
itemSocks = new ProfileItem()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,5 @@ public record CoreConfigContext
|
||||||
|
|
||||||
// TUN Compatibility
|
// TUN Compatibility
|
||||||
public bool IsTunEnabled { get; init; } = false;
|
public bool IsTunEnabled { get; init; } = false;
|
||||||
public HashSet<string> ProtectDomainList { get; init; } = new();
|
public HashSet<string> ProtectDomainList { get; init; } = [];
|
||||||
// -> tun inbound --(if routing proxy)--> relay outbound
|
|
||||||
// -> proxy core (relay inbound --> proxy outbound --(dialerProxy)--> protect outbound)
|
|
||||||
// -> protect inbound -> direct proxy outbound data -> internet
|
|
||||||
public int TunProtectSocksPort { get; init; } = 0;
|
|
||||||
public int ProxyRelaySocksPort { get; init; } = 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@ public class Inbounds4Ray
|
||||||
{
|
{
|
||||||
public string tag { get; set; }
|
public string tag { get; set; }
|
||||||
|
|
||||||
public int port { get; set; }
|
public int? port { get; set; }
|
||||||
|
|
||||||
public string listen { get; set; }
|
public string? listen { get; set; }
|
||||||
|
|
||||||
public string protocol { get; set; }
|
public string protocol { get; set; }
|
||||||
|
|
||||||
|
|
@ -75,6 +75,18 @@ public class Inboundsettings4Ray
|
||||||
public bool? allowTransparent { get; set; }
|
public bool? allowTransparent { get; set; }
|
||||||
|
|
||||||
public List<AccountsItem4Ray>? accounts { get; set; }
|
public List<AccountsItem4Ray>? accounts { get; set; }
|
||||||
|
|
||||||
|
public string? name { get; set; }
|
||||||
|
|
||||||
|
public int? MTU { get; set; }
|
||||||
|
|
||||||
|
public List<string>? gateway { get; set; }
|
||||||
|
|
||||||
|
public List<string>? autoSystemRoutingTable { get; set; }
|
||||||
|
|
||||||
|
public string? autoOutboundsInterface { get; set; }
|
||||||
|
|
||||||
|
// public List<string>? dns { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class UsersItem4Ray
|
public class UsersItem4Ray
|
||||||
|
|
@ -511,6 +523,8 @@ public class AccountsItem4Ray
|
||||||
public class Sockopt4Ray
|
public class Sockopt4Ray
|
||||||
{
|
{
|
||||||
public string? dialerProxy { get; set; }
|
public string? dialerProxy { get; set; }
|
||||||
|
[JsonPropertyName("interface")]
|
||||||
|
public string? Interface { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FragmentItem4Ray
|
public class FragmentItem4Ray
|
||||||
|
|
|
||||||
24
v2rayN/ServiceLib/Sample/SampleTunInbound
Normal file
24
v2rayN/ServiceLib/Sample/SampleTunInbound
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"tag": "tun",
|
||||||
|
"protocol": "tun",
|
||||||
|
"settings": {
|
||||||
|
"name": "xray_tun",
|
||||||
|
"MTU": 9000,
|
||||||
|
"gateway": [
|
||||||
|
"172.18.0.1/30",
|
||||||
|
"fdfe:dcba:9876::1/126"
|
||||||
|
],
|
||||||
|
"autoSystemRoutingTable": [
|
||||||
|
"0.0.0.0/0",
|
||||||
|
"::/0"
|
||||||
|
],
|
||||||
|
"autoOutboundsInterface": "auto"
|
||||||
|
},
|
||||||
|
"sniffing": {
|
||||||
|
"enabled": true,
|
||||||
|
"destOverride": [
|
||||||
|
"http",
|
||||||
|
"tls"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
14
v2rayN/ServiceLib/Sample/SampleTunRules
Normal file
14
v2rayN/ServiceLib/Sample/SampleTunRules
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"network": "udp",
|
||||||
|
"port": "135,137-139,5353",
|
||||||
|
"outboundTag": "block"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ip": [
|
||||||
|
"224.0.0.0/3",
|
||||||
|
"ff00::/8"
|
||||||
|
],
|
||||||
|
"outboundTag": "block"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -38,6 +38,8 @@
|
||||||
<EmbeddedResource Include="Sample\SampleHttpResponse" />
|
<EmbeddedResource Include="Sample\SampleHttpResponse" />
|
||||||
<EmbeddedResource Include="Sample\SampleInbound" />
|
<EmbeddedResource Include="Sample\SampleInbound" />
|
||||||
<EmbeddedResource Include="Sample\SampleOutbound" />
|
<EmbeddedResource Include="Sample\SampleOutbound" />
|
||||||
|
<EmbeddedResource Include="Sample\SampleTunInbound" />
|
||||||
|
<EmbeddedResource Include="Sample\SampleTunRules" />
|
||||||
<EmbeddedResource Include="Sample\SingboxSampleClientConfig" />
|
<EmbeddedResource Include="Sample\SingboxSampleClientConfig" />
|
||||||
<EmbeddedResource Include="Sample\SingboxSampleOutbound" />
|
<EmbeddedResource Include="Sample\SingboxSampleOutbound" />
|
||||||
<EmbeddedResource Include="Sample\tun_singbox_dns" />
|
<EmbeddedResource Include="Sample\tun_singbox_dns" />
|
||||||
|
|
|
||||||
|
|
@ -63,59 +63,6 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
||||||
ret.Success = true;
|
ret.Success = true;
|
||||||
|
|
||||||
ret.Data = ApplyFullConfigTemplate();
|
ret.Data = ApplyFullConfigTemplate();
|
||||||
if (!context.AppConfig.TunModeItem.EnableLegacyProtect
|
|
||||||
&& context.TunProtectSocksPort is > 0 and <= 65535)
|
|
||||||
{
|
|
||||||
// Replace relay proxy outbound, avoid mux or other feature cause issue, and add a socks inbound for tun protect
|
|
||||||
var relayProxyIndex = _coreConfig.outbounds.FindIndex(o => o.tag == Global.ProxyTag);
|
|
||||||
_coreConfig.outbounds[relayProxyIndex] = new Outbound4Sbox()
|
|
||||||
{
|
|
||||||
type = Global.ProtocolTypes[EConfigType.SOCKS],
|
|
||||||
tag = Global.ProxyTag,
|
|
||||||
server = Global.Loopback,
|
|
||||||
server_port = context.ProxyRelaySocksPort,
|
|
||||||
};
|
|
||||||
var ssInbound = new
|
|
||||||
{
|
|
||||||
type = "socks",
|
|
||||||
tag = "tun-protect-socks",
|
|
||||||
listen = Global.Loopback,
|
|
||||||
listen_port = context.TunProtectSocksPort,
|
|
||||||
};
|
|
||||||
var directRule = new Rule4Sbox()
|
|
||||||
{
|
|
||||||
inbound = new List<string> { ssInbound.tag },
|
|
||||||
outbound = Global.DirectTag,
|
|
||||||
};
|
|
||||||
var singboxConfigNode = JsonUtils.ParseJson(ret.Data.ToString())!.AsObject();
|
|
||||||
var inboundsNode = singboxConfigNode["inbounds"]!.AsArray();
|
|
||||||
inboundsNode.Add(JsonUtils.SerializeToNode(ssInbound, new JsonSerializerOptions
|
|
||||||
{
|
|
||||||
DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull
|
|
||||||
}));
|
|
||||||
var routeNode = singboxConfigNode["route"]?.AsObject();
|
|
||||||
var rulesNode = routeNode?["rules"]?.AsArray();
|
|
||||||
var protectRuleNode = JsonUtils.SerializeToNode(directRule,
|
|
||||||
new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull });
|
|
||||||
if (rulesNode != null)
|
|
||||||
{
|
|
||||||
rulesNode.Insert(0, protectRuleNode);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var newRulesNode = new JsonArray() { protectRuleNode };
|
|
||||||
if (routeNode is null)
|
|
||||||
{
|
|
||||||
var newRouteNode = new JsonObject() { ["rules"] = newRulesNode };
|
|
||||||
singboxConfigNode["route"] = newRouteNode;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
routeNode["rules"] = newRulesNode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret.Data = JsonUtils.Serialize(singboxConfigNode);
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ public partial class CoreConfigSingboxService
|
||||||
strategy = directDnsStrategy
|
strategy = directDnsStrategy
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_config.TunModeItem.EnableTun)
|
if (context.IsTunEnabled)
|
||||||
{
|
{
|
||||||
_coreConfig.route.auto_detect_interface = true;
|
_coreConfig.route.auto_detect_interface = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,6 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
var ret = new RetResult();
|
var ret = new RetResult();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!context.AppConfig.TunModeItem.EnableLegacyProtect
|
|
||||||
&& context.IsTunEnabled
|
|
||||||
&& context.TunProtectSocksPort is > 0 and <= 65535
|
|
||||||
&& context.ProxyRelaySocksPort is > 0 and <= 65535)
|
|
||||||
{
|
|
||||||
return GenerateClientProxyRelayConfig();
|
|
||||||
}
|
|
||||||
if (_node == null
|
if (_node == null
|
||||||
|| !_node.IsValid())
|
|| !_node.IsValid())
|
||||||
{
|
{
|
||||||
|
|
@ -272,139 +265,5 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public RetResult GenerateClientProxyRelayConfig()
|
|
||||||
{
|
|
||||||
var ret = new RetResult();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_node == null
|
|
||||||
|| !_node.IsValid())
|
|
||||||
{
|
|
||||||
ret.Msg = ResUI.CheckServerSettings;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_node.GetNetwork() is nameof(ETransport.quic))
|
|
||||||
{
|
|
||||||
ret.Msg = ResUI.Incorrectconfiguration + $" - {_node.GetNetwork()}";
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = EmbedUtils.GetEmbedText(Global.V2raySampleClient);
|
|
||||||
if (result.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
ret.Msg = ResUI.FailedGetDefaultConfiguration;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
_coreConfig = JsonUtils.Deserialize<V2rayConfig>(result);
|
|
||||||
if (_coreConfig == null)
|
|
||||||
{
|
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
GenLog();
|
|
||||||
_coreConfig.outbounds.Clear();
|
|
||||||
GenOutbounds();
|
|
||||||
GenStatistic();
|
|
||||||
|
|
||||||
var protectNode = new ProfileItem()
|
|
||||||
{
|
|
||||||
CoreType = ECoreType.Xray,
|
|
||||||
ConfigType = EConfigType.SOCKS,
|
|
||||||
Address = Global.Loopback,
|
|
||||||
Port = context.TunProtectSocksPort,
|
|
||||||
};
|
|
||||||
protectNode.SetProtocolExtra(protectNode.GetProtocolExtra() with
|
|
||||||
{
|
|
||||||
SsMethod = Global.None,
|
|
||||||
});
|
|
||||||
|
|
||||||
const string protectTag = "tun-protect-socks";
|
|
||||||
foreach (var outbound in _coreConfig.outbounds
|
|
||||||
.Where(o => o.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true))
|
|
||||||
{
|
|
||||||
outbound.streamSettings ??= new();
|
|
||||||
outbound.streamSettings.sockopt ??= new();
|
|
||||||
outbound.streamSettings.sockopt.dialerProxy = protectTag;
|
|
||||||
}
|
|
||||||
// ech protected
|
|
||||||
foreach (var outbound in _coreConfig.outbounds
|
|
||||||
.Where(outbound => outbound.streamSettings?.tlsSettings?.echConfigList?.IsNullOrEmpty() == false))
|
|
||||||
{
|
|
||||||
outbound.streamSettings!.tlsSettings!.echSockopt ??= new();
|
|
||||||
outbound.streamSettings.tlsSettings.echSockopt.dialerProxy = protectTag;
|
|
||||||
}
|
|
||||||
// xhttp download protected
|
|
||||||
foreach (var outbound in _coreConfig.outbounds
|
|
||||||
.Where(o => o.streamSettings?.xhttpSettings?.extra is not null))
|
|
||||||
{
|
|
||||||
var xhttpExtra = JsonUtils.ParseJson(JsonUtils.Serialize(outbound.streamSettings.xhttpSettings!.extra));
|
|
||||||
if (xhttpExtra is not JsonObject xhttpExtraObject
|
|
||||||
|| xhttpExtraObject["downloadSettings"] is not JsonObject downloadSettings)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// dialerProxy
|
|
||||||
var sockopt = downloadSettings["sockopt"] as JsonObject ?? new JsonObject();
|
|
||||||
sockopt["dialerProxy"] = protectTag;
|
|
||||||
downloadSettings["sockopt"] = sockopt;
|
|
||||||
// ech protected
|
|
||||||
if (downloadSettings["tlsSettings"] is JsonObject tlsSettings
|
|
||||||
&& tlsSettings["echConfigList"] is not null)
|
|
||||||
{
|
|
||||||
tlsSettings["echSockopt"] = new JsonObject
|
|
||||||
{
|
|
||||||
["dialerProxy"] = protectTag
|
|
||||||
};
|
|
||||||
}
|
|
||||||
outbound.streamSettings.xhttpSettings.extra = xhttpExtraObject;
|
|
||||||
}
|
|
||||||
_coreConfig.outbounds.Add(new CoreConfigV2rayService(context with
|
|
||||||
{
|
|
||||||
Node = protectNode,
|
|
||||||
}).BuildProxyOutbound(protectTag));
|
|
||||||
|
|
||||||
_coreConfig.routing.rules ??= [];
|
|
||||||
var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 };
|
|
||||||
_coreConfig.routing.rules.Add(new()
|
|
||||||
{
|
|
||||||
inboundTag = ["proxy-relay-socks"],
|
|
||||||
outboundTag = hasBalancer ? null : Global.ProxyTag,
|
|
||||||
balancerTag = hasBalancer ? Global.ProxyTag + Global.BalancerTagSuffix : null,
|
|
||||||
type = "field"
|
|
||||||
});
|
|
||||||
|
|
||||||
//_coreConfig.inbounds.Clear();
|
|
||||||
|
|
||||||
ApplyOutboundSendThrough();
|
|
||||||
var configNode = JsonUtils.ParseJson(JsonUtils.Serialize(_coreConfig))!;
|
|
||||||
configNode["inbounds"]!.AsArray().Add(new
|
|
||||||
{
|
|
||||||
listen = Global.Loopback,
|
|
||||||
port = context.ProxyRelaySocksPort,
|
|
||||||
protocol = "socks",
|
|
||||||
settings = new
|
|
||||||
{
|
|
||||||
auth = "noauth",
|
|
||||||
udp = true,
|
|
||||||
},
|
|
||||||
tag = "proxy-relay-socks",
|
|
||||||
});
|
|
||||||
|
|
||||||
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
|
|
||||||
ret.Success = true;
|
|
||||||
ret.Data = JsonUtils.Serialize(configNode);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Logging.SaveLog(_tag, ex);
|
|
||||||
ret.Msg = ResUI.FailedGenDefaultConfiguration;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion public gen function
|
#endregion public gen function
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,36 +7,61 @@ public partial class CoreConfigV2rayService
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var listen = "0.0.0.0";
|
var listen = "0.0.0.0";
|
||||||
|
var listenPort = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||||
_coreConfig.inbounds = [];
|
_coreConfig.inbounds = [];
|
||||||
|
|
||||||
var inbound = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks, true);
|
var inbound = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks, true);
|
||||||
_coreConfig.inbounds.Add(inbound);
|
|
||||||
|
|
||||||
if (_config.Inbound.First().SecondLocalPortEnabled)
|
if (!context.IsTunEnabled
|
||||||
|
|| (context.IsTunEnabled && _node.Address != Global.Loopback && _node.Port != listenPort))
|
||||||
{
|
{
|
||||||
var inbound2 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks2, true);
|
_coreConfig.inbounds.Add(inbound);
|
||||||
_coreConfig.inbounds.Add(inbound2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_config.Inbound.First().AllowLANConn)
|
if (_config.Inbound.First().SecondLocalPortEnabled)
|
||||||
{
|
|
||||||
if (_config.Inbound.First().NewPort4LAN)
|
|
||||||
{
|
{
|
||||||
var inbound3 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks3, true);
|
var inbound2 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks2, true);
|
||||||
inbound3.listen = listen;
|
_coreConfig.inbounds.Add(inbound2);
|
||||||
_coreConfig.inbounds.Add(inbound3);
|
}
|
||||||
|
|
||||||
//auth
|
if (_config.Inbound.First().AllowLANConn)
|
||||||
if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty())
|
{
|
||||||
|
if (_config.Inbound.First().NewPort4LAN)
|
||||||
{
|
{
|
||||||
inbound3.settings.auth = "password";
|
var inbound3 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks3, true);
|
||||||
inbound3.settings.accounts = new List<AccountsItem4Ray> { new() { user = _config.Inbound.First().User, pass = _config.Inbound.First().Pass } };
|
inbound3.listen = listen;
|
||||||
|
_coreConfig.inbounds.Add(inbound3);
|
||||||
|
|
||||||
|
//auth
|
||||||
|
if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty())
|
||||||
|
{
|
||||||
|
inbound3.settings.auth = "password";
|
||||||
|
inbound3.settings.accounts = new List<AccountsItem4Ray>
|
||||||
|
{
|
||||||
|
new() { user = _config.Inbound.First().User, pass = _config.Inbound.First().Pass }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
inbound.listen = listen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (context.IsTunEnabled)
|
||||||
|
{
|
||||||
|
if (_config.TunModeItem.Mtu <= 0)
|
||||||
{
|
{
|
||||||
inbound.listen = listen;
|
_config.TunModeItem.Mtu = Global.TunMtus.First();
|
||||||
}
|
}
|
||||||
|
var tunInbound = JsonUtils.Deserialize<Inbounds4Ray>(EmbedUtils.GetEmbedText(Global.V2raySampleTunInbound)) ?? new Inbounds4Ray { };
|
||||||
|
tunInbound.settings.name = Utils.IsMacOS() ? $"utun{new Random().Next(99)}" : "xray_tun";
|
||||||
|
tunInbound.settings.MTU = _config.TunModeItem.Mtu;
|
||||||
|
if (_config.TunModeItem.EnableIPv6Address == false)
|
||||||
|
{
|
||||||
|
tunInbound.settings.gateway = ["172.18.0.1/30"];
|
||||||
|
}
|
||||||
|
tunInbound.sniffing = inbound.sniffing;
|
||||||
|
_coreConfig.inbounds.Add(tunInbound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,10 @@ public partial class CoreConfigV2rayService
|
||||||
GenObservatory(multipleLoad);
|
GenObservatory(multipleLoad);
|
||||||
GenBalancer(multipleLoad);
|
GenBalancer(multipleLoad);
|
||||||
}
|
}
|
||||||
|
if (context.IsTunEnabled)
|
||||||
|
{
|
||||||
|
_coreConfig.outbounds.Add(BuildDnsOutbound());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Outbounds4Ray> BuildAllProxyOutbounds(string baseTagName = Global.ProxyTag)
|
private List<Outbounds4Ray> BuildAllProxyOutbounds(string baseTagName = Global.ProxyTag)
|
||||||
|
|
@ -825,4 +829,10 @@ public partial class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Outbounds4Ray BuildDnsOutbound()
|
||||||
|
{
|
||||||
|
var outbound = new Outbounds4Ray { tag = Global.DnsOutboundTag, protocol = "dns", };
|
||||||
|
return outbound;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,31 @@ public partial class CoreConfigV2rayService
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (context.IsTunEnabled)
|
||||||
|
{
|
||||||
|
var tunRules = JsonUtils.Deserialize<List<RulesItem4Ray>>(EmbedUtils.GetEmbedText(Global.V2raySampleTunRules));
|
||||||
|
if (tunRules != null)
|
||||||
|
{
|
||||||
|
_coreConfig.routing.rules.AddRange(tunRules);
|
||||||
|
}
|
||||||
|
var (lstDnsExe, lstDirectExe) = BuildRoutingDirectExe();
|
||||||
|
_coreConfig.routing.rules.Add(new()
|
||||||
|
{
|
||||||
|
port = "53",
|
||||||
|
process = lstDnsExe,
|
||||||
|
outboundTag = Global.DnsOutboundTag,
|
||||||
|
});
|
||||||
|
_coreConfig.routing.rules.Add(new()
|
||||||
|
{
|
||||||
|
process = lstDirectExe,
|
||||||
|
outboundTag = Global.DirectTag,
|
||||||
|
});
|
||||||
|
_coreConfig.routing.rules.Add(new()
|
||||||
|
{
|
||||||
|
port = "53",
|
||||||
|
outboundTag = Global.DnsOutboundTag,
|
||||||
|
});
|
||||||
|
}
|
||||||
if (_coreConfig.routing?.rules != null)
|
if (_coreConfig.routing?.rules != null)
|
||||||
{
|
{
|
||||||
_coreConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
|
_coreConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
|
||||||
|
|
@ -205,4 +230,37 @@ public partial class CoreConfigV2rayService
|
||||||
}
|
}
|
||||||
return finalRule;
|
return finalRule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static (List<string> lstDnsExe, List<string> lstDirectExe) BuildRoutingDirectExe()
|
||||||
|
{
|
||||||
|
var dnsExeSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
var directExeSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
var coreInfoResult = CoreInfoManager.Instance.GetCoreInfo();
|
||||||
|
|
||||||
|
foreach (var coreConfig in coreInfoResult)
|
||||||
|
{
|
||||||
|
if (coreConfig.CoreType == ECoreType.v2rayN)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var baseExeName in coreConfig.CoreExes)
|
||||||
|
{
|
||||||
|
if (coreConfig.CoreType != ECoreType.Xray)
|
||||||
|
{
|
||||||
|
dnsExeSet.Add(Utils.GetExeName(baseExeName));
|
||||||
|
}
|
||||||
|
directExeSet.Add(Utils.GetExeName(baseExeName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
directExeSet.Add("xray/");
|
||||||
|
directExeSet.Add("self/");
|
||||||
|
|
||||||
|
var lstDnsExe = new List<string>(dnsExeSet);
|
||||||
|
var lstDirectExe = new List<string>(directExeSet);
|
||||||
|
|
||||||
|
return (lstDnsExe, lstDirectExe);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -559,7 +559,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
|
|
||||||
await Task.Run(async () =>
|
await Task.Run(async () =>
|
||||||
{
|
{
|
||||||
await LoadCore(allResult.ResolvedMainContext, allResult.PreSocksResult?.Context);
|
await LoadCore(allResult.MainResult.Context, allResult.PreSocksResult?.Context);
|
||||||
await SysProxyHandler.UpdateSysProxy(_config, false);
|
await SysProxyHandler.UpdateSysProxy(_config, false);
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue