mirror of
https://github.com/2dust/v2rayN.git
synced 2026-10-26 15:15:04 +03:00
@@ -63,59 +63,6 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
|
||||
ret.Success = true;
|
||||
|
||||
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;
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -24,7 +24,7 @@ public partial class CoreConfigSingboxService
|
||||
strategy = directDnsStrategy
|
||||
};
|
||||
|
||||
if (_config.TunModeItem.EnableTun)
|
||||
if (context.IsTunEnabled)
|
||||
{
|
||||
_coreConfig.route.auto_detect_interface = true;
|
||||
|
||||
|
||||
@@ -15,13 +15,6 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
|
||||
var ret = new RetResult();
|
||||
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
|
||||
|| !_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
|
||||
}
|
||||
|
||||
@@ -7,36 +7,61 @@ public partial class CoreConfigV2rayService
|
||||
try
|
||||
{
|
||||
var listen = "0.0.0.0";
|
||||
var listenPort = AppManager.Instance.GetLocalPort(EInboundProtocol.socks);
|
||||
_coreConfig.inbounds = [];
|
||||
|
||||
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(inbound2);
|
||||
}
|
||||
_coreConfig.inbounds.Add(inbound);
|
||||
|
||||
if (_config.Inbound.First().AllowLANConn)
|
||||
{
|
||||
if (_config.Inbound.First().NewPort4LAN)
|
||||
if (_config.Inbound.First().SecondLocalPortEnabled)
|
||||
{
|
||||
var inbound3 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks3, true);
|
||||
inbound3.listen = listen;
|
||||
_coreConfig.inbounds.Add(inbound3);
|
||||
var inbound2 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks2, true);
|
||||
_coreConfig.inbounds.Add(inbound2);
|
||||
}
|
||||
|
||||
//auth
|
||||
if (_config.Inbound.First().User.IsNotEmpty() && _config.Inbound.First().Pass.IsNotEmpty())
|
||||
if (_config.Inbound.First().AllowLANConn)
|
||||
{
|
||||
if (_config.Inbound.First().NewPort4LAN)
|
||||
{
|
||||
inbound3.settings.auth = "password";
|
||||
inbound3.settings.accounts = new List<AccountsItem4Ray> { new() { user = _config.Inbound.First().User, pass = _config.Inbound.First().Pass } };
|
||||
var inbound3 = BuildInbound(_config.Inbound.First(), EInboundProtocol.socks3, true);
|
||||
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)
|
||||
|
||||
@@ -12,6 +12,10 @@ public partial class CoreConfigV2rayService
|
||||
GenObservatory(multipleLoad);
|
||||
GenBalancer(multipleLoad);
|
||||
}
|
||||
if (context.IsTunEnabled)
|
||||
{
|
||||
_coreConfig.outbounds.Add(BuildDnsOutbound());
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
_coreConfig.routing.domainStrategy = _config.RoutingBasicItem.DomainStrategy;
|
||||
@@ -205,4 +230,37 @@ public partial class CoreConfigV2rayService
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user