Compare commits

...

4 commits

Author SHA1 Message Date
DHR60
8441000a52
Merge ddc45ed443 into 49f65579aa 2026-04-11 19:47:16 +08:00
DHR60
49f65579aa
Replace protect-ss with protect-socks (#9052) 2026-04-11 19:45:23 +08:00
dependabot[bot]
a69e407bda
Bump actions/upload-artifact from 7.0.0 to 7.0.1 (#9073)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 7.0.0 to 7.0.1.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v7.0.0...v7.0.1)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-11 19:42:39 +08:00
taskmgr818
96e5c11fc7
Replace 100MB Cloudflare speedtest URL with 99MB (#9076) 2026-04-11 19:39:25 +08:00
10 changed files with 44 additions and 67 deletions

View file

@ -47,7 +47,7 @@ jobs:
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o "$OutputPathArm64" dotnet publish ./AmazTool/AmazTool.csproj -c Release -r linux-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o "$OutputPathArm64"
- name: Upload build artifacts - name: Upload build artifacts
uses: actions/upload-artifact@v7.0.0 uses: actions/upload-artifact@v7.0.1
with: with:
name: v2rayN-linux name: v2rayN-linux
path: | path: |
@ -116,7 +116,7 @@ jobs:
ls -R "$GITHUB_WORKSPACE/dist/deb" || true ls -R "$GITHUB_WORKSPACE/dist/deb" || true
- name: Upload DEB artifacts - name: Upload DEB artifacts
uses: actions/upload-artifact@v7.0.0 uses: actions/upload-artifact@v7.0.1
with: with:
name: v2rayN-deb name: v2rayN-deb
path: dist/deb/**/*.deb path: dist/deb/**/*.deb
@ -229,7 +229,7 @@ jobs:
ls -R "$GITHUB_WORKSPACE/dist/rpm" || true ls -R "$GITHUB_WORKSPACE/dist/rpm" || true
- name: Upload RPM artifacts - name: Upload RPM artifacts
uses: actions/upload-artifact@v7.0.0 uses: actions/upload-artifact@v7.0.1
with: with:
name: v2rayN-rpm name: v2rayN-rpm
path: dist/rpm/**/*.rpm path: dist/rpm/**/*.rpm

View file

@ -45,7 +45,7 @@ jobs:
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o $OutputPathArm64 dotnet publish ./AmazTool/AmazTool.csproj -c Release -r osx-arm64 -p:SelfContained=true -p:PublishTrimmed=true -o $OutputPathArm64
- name: Upload build artifacts - name: Upload build artifacts
uses: actions/upload-artifact@v7.0.0 uses: actions/upload-artifact@v7.0.1
with: with:
name: v2rayN-macos name: v2rayN-macos
path: | path: |

View file

@ -45,7 +45,7 @@ jobs:
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 -p:SelfContained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64 dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 -p:SelfContained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
- name: Upload build artifacts - name: Upload build artifacts
uses: actions/upload-artifact@v7.0.0 uses: actions/upload-artifact@v7.0.1
with: with:
name: v2rayN-windows-desktop name: v2rayN-windows-desktop
path: | path: |

View file

@ -42,7 +42,7 @@ jobs:
dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 -p:SelfContained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64 dotnet publish ./AmazTool/AmazTool.csproj -c Release -r win-arm64 -p:SelfContained=true -p:EnableWindowsTargeting=true -p:PublishTrimmed=true -o $OutputPathArm64
- name: Upload build artifacts - name: Upload build artifacts
uses: actions/upload-artifact@v7.0.0 uses: actions/upload-artifact@v7.0.1
with: with:
name: v2rayN-windows name: v2rayN-windows
path: | path: |

View file

@ -143,7 +143,7 @@ public class Global
@"https://cachefly.cachefly.net/50mb.test", @"https://cachefly.cachefly.net/50mb.test",
@"https://speed.cloudflare.com/__down?bytes=10000000", @"https://speed.cloudflare.com/__down?bytes=10000000",
@"https://speed.cloudflare.com/__down?bytes=50000000", @"https://speed.cloudflare.com/__down?bytes=50000000",
@"https://speed.cloudflare.com/__down?bytes=100000000", @"https://speed.cloudflare.com/__down?bytes=99999999",
]; ];
public static readonly List<string> SpeedPingTestUrls = public static readonly List<string> SpeedPingTestUrls =

View file

@ -25,14 +25,14 @@ public record CoreConfigContextBuilderAllResult(
[.. MainResult.ValidatorResult.Warnings, .. PreSocksResult?.ValidatorResult.Warnings ?? []]); [.. MainResult.ValidatorResult.Warnings, .. PreSocksResult?.ValidatorResult.Warnings ?? []]);
/// <summary> /// <summary>
/// The main context with TunProtectSsPort/ProxyRelaySsPort and ProtectDomainList merged in /// The main context with TunProtectSocksPort/ProxyRelaySocksPort and ProtectDomainList merged in
/// from the pre-socks result (if any). Pass this to the core runner. /// from the pre-socks result (if any). Pass this to the core runner.
/// </summary> /// </summary>
public CoreConfigContext ResolvedMainContext => PreSocksResult is not null public CoreConfigContext ResolvedMainContext => PreSocksResult is not null
? MainResult.Context with ? MainResult.Context with
{ {
TunProtectSsPort = PreSocksResult.Context.TunProtectSsPort, TunProtectSocksPort = PreSocksResult.Context.TunProtectSocksPort,
ProxyRelaySsPort = PreSocksResult.Context.ProxyRelaySsPort, ProxyRelaySocksPort = PreSocksResult.Context.ProxyRelaySocksPort,
ProtectDomainList = [.. MainResult.Context.ProtectDomainList ?? [], .. PreSocksResult.Context.ProtectDomainList ?? []], ProtectDomainList = [.. MainResult.Context.ProtectDomainList ?? [], .. PreSocksResult.Context.ProtectDomainList ?? []],
} }
: MainResult.Context; : MainResult.Context;
@ -58,8 +58,8 @@ public class CoreConfigContextBuilder
IsTunEnabled = config.TunModeItem.EnableTun, IsTunEnabled = config.TunModeItem.EnableTun,
SimpleDnsItem = config.SimpleDNSItem, SimpleDnsItem = config.SimpleDNSItem,
ProtectDomainList = [], ProtectDomainList = [],
TunProtectSsPort = 0, TunProtectSocksPort = 0,
ProxyRelaySsPort = 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),
}; };
@ -155,28 +155,23 @@ public class CoreConfigContextBuilder
return null; return null;
} }
var tunProtectSsPort = Utils.GetFreePort(); var tunProtectSocksPort = Utils.GetFreePort();
var proxyRelaySsPort = Utils.GetFreePort(); var proxyRelaySocksPort = Utils.GetFreePort();
var preItem = new ProfileItem() var preItem = new ProfileItem()
{ {
CoreType = ECoreType.sing_box, CoreType = ECoreType.sing_box,
ConfigType = EConfigType.Shadowsocks, ConfigType = EConfigType.SOCKS,
Address = Global.Loopback, Address = Global.Loopback,
Port = proxyRelaySsPort, Port = proxyRelaySocksPort,
Password = Global.None,
}; };
preItem.SetProtocolExtra(preItem.GetProtocolExtra() with
{
SsMethod = Global.None,
});
var preResult2 = await Build(nodeContext.AppConfig, preItem); var preResult2 = await Build(nodeContext.AppConfig, preItem);
return preResult2 with return preResult2 with
{ {
Context = preResult2.Context with Context = preResult2.Context with
{ {
ProtectDomainList = [.. nodeContext.ProtectDomainList ?? [], .. preResult2.Context.ProtectDomainList ?? []], ProtectDomainList = [.. nodeContext.ProtectDomainList ?? [], .. preResult2.Context.ProtectDomainList ?? []],
TunProtectSsPort = tunProtectSsPort, TunProtectSocksPort = tunProtectSocksPort,
ProxyRelaySsPort = proxyRelaySsPort, ProxyRelaySocksPort = proxyRelaySocksPort,
} }
}; };
} }

View file

@ -20,6 +20,6 @@ public record CoreConfigContext
// -> tun inbound --(if routing proxy)--> relay outbound // -> tun inbound --(if routing proxy)--> relay outbound
// -> proxy core (relay inbound --> proxy outbound --(dialerProxy)--> protect outbound) // -> proxy core (relay inbound --> proxy outbound --(dialerProxy)--> protect outbound)
// -> protect inbound -> direct proxy outbound data -> internet // -> protect inbound -> direct proxy outbound data -> internet
public int TunProtectSsPort { get; init; } = 0; public int TunProtectSocksPort { get; init; } = 0;
public int ProxyRelaySsPort { get; init; } = 0; public int ProxyRelaySocksPort { get; init; } = 0;
} }

View file

@ -62,16 +62,23 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
ret.Data = ApplyFullConfigTemplate(); ret.Data = ApplyFullConfigTemplate();
if (!context.AppConfig.TunModeItem.EnableLegacyProtect if (!context.AppConfig.TunModeItem.EnableLegacyProtect
&& context.TunProtectSsPort is > 0 and <= 65535) && 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 var ssInbound = new
{ {
type = "shadowsocks", type = "socks",
tag = "tun-protect-ss", tag = "tun-protect-socks",
listen = Global.Loopback, listen = Global.Loopback,
listen_port = context.TunProtectSsPort, listen_port = context.TunProtectSocksPort,
method = "none",
password = "none",
}; };
var directRule = new Rule4Sbox() var directRule = new Rule4Sbox()
{ {

View file

@ -345,14 +345,6 @@ public partial class CoreConfigSingboxService
{ {
try try
{ {
// The synthetic TUN relay outbound talks to the local Xray shadowsocks relay.
// Xray cannot terminate sing-box h2mux, so muxing here turns local relay traffic
// into sp.mux.sing-box.arpa pseudo-destinations and breaks DNS over TUN.
if (IsTunRelayProxyOutbound())
{
return;
}
var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled; var muxEnabled = _node.MuxEnabled ?? _config.CoreBasicItem.MuxEnabled;
if (muxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty()) if (muxEnabled && _config.Mux4SboxItem.Protocol.IsNotEmpty())
{ {
@ -372,21 +364,6 @@ public partial class CoreConfigSingboxService
} }
} }
private bool IsTunRelayProxyOutbound()
{
if (!context.IsTunEnabled
|| _node.ConfigType != EConfigType.Shadowsocks
|| _node.Address != Global.Loopback
|| _node.Port != context.ProxyRelaySsPort
|| _node.Password != Global.None)
{
return false;
}
var protocolExtra = _node.GetProtocolExtra();
return protocolExtra.SsMethod == Global.None;
}
private void FillOutboundTls(Outbound4Sbox outbound) private void FillOutboundTls(Outbound4Sbox outbound)
{ {
try try

View file

@ -17,8 +17,8 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{ {
if (!context.AppConfig.TunModeItem.EnableLegacyProtect if (!context.AppConfig.TunModeItem.EnableLegacyProtect
&& context.IsTunEnabled && context.IsTunEnabled
&& context.TunProtectSsPort is > 0 and <= 65535 && context.TunProtectSocksPort is > 0 and <= 65535
&& context.ProxyRelaySsPort is > 0 and <= 65535) && context.ProxyRelaySocksPort is > 0 and <= 65535)
{ {
return GenerateClientProxyRelayConfig(); return GenerateClientProxyRelayConfig();
} }
@ -309,17 +309,16 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
var protectNode = new ProfileItem() var protectNode = new ProfileItem()
{ {
CoreType = ECoreType.Xray, CoreType = ECoreType.Xray,
ConfigType = EConfigType.Shadowsocks, ConfigType = EConfigType.SOCKS,
Address = Global.Loopback, Address = Global.Loopback,
Port = context.TunProtectSsPort, Port = context.TunProtectSocksPort,
Password = Global.None,
}; };
protectNode.SetProtocolExtra(protectNode.GetProtocolExtra() with protectNode.SetProtocolExtra(protectNode.GetProtocolExtra() with
{ {
SsMethod = Global.None, SsMethod = Global.None,
}); });
const string protectTag = "tun-protect-ss"; const string protectTag = "tun-protect-socks";
foreach (var outbound in _coreConfig.outbounds foreach (var outbound in _coreConfig.outbounds
.Where(o => o.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true)) .Where(o => o.streamSettings?.sockopt?.dialerProxy?.IsNullOrEmpty() ?? true))
{ {
@ -368,7 +367,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 }; var hasBalancer = _coreConfig.routing.balancers is { Count: > 0 };
_coreConfig.routing.rules.Add(new() _coreConfig.routing.rules.Add(new()
{ {
inboundTag = ["proxy-relay-ss"], inboundTag = ["proxy-relay-socks"],
outboundTag = hasBalancer ? null : Global.ProxyTag, outboundTag = hasBalancer ? null : Global.ProxyTag,
balancerTag = hasBalancer ? Global.ProxyTag + Global.BalancerTagSuffix : null, balancerTag = hasBalancer ? Global.ProxyTag + Global.BalancerTagSuffix : null,
type = "field" type = "field"
@ -380,15 +379,14 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
configNode["inbounds"]!.AsArray().Add(new configNode["inbounds"]!.AsArray().Add(new
{ {
listen = Global.Loopback, listen = Global.Loopback,
port = context.ProxyRelaySsPort, port = context.ProxyRelaySocksPort,
protocol = "shadowsocks", protocol = "socks",
settings = new settings = new
{ {
network = "tcp,udp", auth = "noauth",
method = Global.None, udp = true,
password = Global.None,
}, },
tag = "proxy-relay-ss", tag = "proxy-relay-socks",
}); });
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, ""); ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");