Commit Graph

2946 Commits

Author SHA1 Message Date
DHR60
7870ae89cf Move "GLOBAL" to the end (#10064) 2026-08-31 18:00:44 +08:00
2dust
521230c40d up 7.24.9 7.24.9 2026-08-29 10:46:53 +08:00
Miheichev Aleksandr Sergeevich
426d5d5a21 ci: run the test job on pushes to master (#10054)
The Code Test workflow only has a pull_request trigger, so the suite
never runs against master itself: a direct push is untested, and a
merge can break tests even when the pull request's own check was
green, because checks run on the PR head rather than on the merged
result. Add a push trigger for master with the same paths filter.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-29 09:42:40 +08:00
2dust
3f14c86a04 Trigger routing migration when rules exist 2026-08-28 15:00:19 +08:00
dependabot[bot]
70b8ecd3c8 Bump TUnit from 1.65.63 to 1.65.68 (#10052)
---
updated-dependencies:
- dependency-name: TUnit
  dependency-version: 1.65.68
  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-08-28 14:38:57 +08:00
DHR60
0d452328a2 Add wireguard remote dns support (#10036) 2026-08-28 14:38:43 +08:00
Miheichev Aleksandr Sergeevich
2a65e5ac80 fix(fmt): stop share-URI query values from being decoded twice or dropped (#10027)
`Utils.ParseQueryString` already unescapes every value, and
`BaseFmt.GetQueryDecoded` unescaped it again. A value that still held a
valid percent sequence after the first pass decayed on the second: an
obfuscation password of `ob%41fs` is exported as `ob%2541fs` and imported
back as `obAfs`. Only well-formed sequences are affected, which is why the
damage is silent - `100%` and `66%ff` survive untouched.

The same function also split each pair on every `=`, and skipped the pair
unless exactly two halves came out. RFC 3986 lists `=` among the
sub-delimiters a query value may carry, so only the first one separates the
key from the value, and `HttpUtility.ParseQueryString` reads a query string
the same way. Splitting on all of them discarded a syntactically valid
pair: `?ech=AAj+DQAEAAAAAA==` was lost entirely, and so was a `plugin`
value in the non-canonical SIP002 spelling, since those are `;` separated
`key=value` lists.

v2rayN percent-encodes both on export, so its own links were never
affected; what changes is that the parser now follows the grammar instead
of discarding a pair it cannot split in two.

Splitting on the first `=` only, and reading the value the parser already
decoded, fixes both. `ParseQueryString` keeps decoding because
`ConfigHandler` reads its result directly.

`GetQueryDecoded` and `GetQueryValue` are now equivalent; they are left
separate to keep this change small, and can be collapsed if you prefer.
2026-08-28 14:38:02 +08:00
Miheichev Aleksandr Sergeevich
f332caf507 fix(hysteria2): default the port to 443 when the share URI omits it (#10026)
The Hysteria2 URI scheme makes the port optional: "The hostname and
optional port of the server. If the port is omitted, it defaults to 443."
`Hysteria2Fmt.Resolve` assigned `url.Port` straight through, and
`System.Uri` answers -1 for an unregistered scheme that carries no port,
so `hysteria2://password@hy2.example/` imported as a profile with
`Port = -1`. `ProfileItem.IsValid` rejects any port outside 1..65535, so
such a link produced a profile that could never be used, and nothing said
why.

-1 is the only value that means "the port was omitted"; a ':' with no
digits after it maps to -1 as well. An explicit ":0" parses as 0 and
keeps the fate it has today - rejected by `IsValid` - rather than being
redirected to a server the link never named.

`ResolveRealm` takes its port from `HyRealm.RendezvousPort` instead of
the URI, so it is unaffected.

The added tests cover both spellings of the scheme, with and without a
trailing slash, a bare ':', and the resulting profile's validity. Two of
them are controls: an explicit port is still preserved, and an explicit
":0" still does not turn into 443.
2026-08-28 14:33:05 +08:00
Miheichev Aleksandr Sergeevich
4b412e246f test: cover the share-URI round trip for the remaining protocols (#10017)
`FmtHandlerTests` round-tripped VMess, VLESS, Shadowsocks and SOCKS.
`FmtHandler.GetShareUri` dispatches ten protocols, so Trojan, Hysteria2,
TUIC, Anytls, WireGuard and Naive were exported and re-imported untested,
and `WireguardFmt` was covered in the `Resolve` direction only.

Each new test exports a profile, imports the result and asserts the fields
that protocol carries in its URI: the flow for Trojan, the uuid/password
pair and the congestion control for TUIC, the obfuscation password and the
port range for Hysteria2, the peer keys, reserved bytes, interface address
and MTU for WireGuard, and the credentials plus the insecure concurrency
for Naive.

`ShareUriSuite_ShouldCoverAndRoundTripEveryExportableProtocol` compares the
profile-factory map against `Global.ProtocolShares` and round-trips every
entry, so a newly exportable protocol cannot be added without a case here.

Three things a round trip alone cannot prove are asserted on the wire form
instead. The allow-insecure flag is spelled per protocol since #9888 -
`allowInsecure` and `insecure` for Trojan, `allow_insecure` for TUIC,
`insecure` for Anytls and Hysteria2 - so an exporter and an importer that
agreed on the wrong name would otherwise round-trip cleanly. The WireGuard
test pins the percent-encoding of the base64 keys and the brackets around
the IPv6 literal. Hysteria2 keeps `CertSha` unset on purpose: the importer
turns `AllowInsecure` on by itself when a `pinSHA256` is present, which
would mask an exporter that stopped emitting `insecure=1`.

Fixtures are deterministic and no longer plain ASCII: a fixed uuid for
TUIC, real 32-byte base64 keys and an IPv6 address for WireGuard, and
reserved and non-Latin characters in passwords and remarks.

`ExportThenImport` derives the expected scheme, because `NaiveFmt` emits
`naive+https://` or `naive+quic://` and never the `naive://` prefix that
`Global.ProtocolShares` records for that type - that entry is only read
when importing.
2026-08-28 14:27:50 +08:00
Miheichev Aleksandr Sergeevich
09ac4d181a ci: run the test job on its own inputs and trim its checkout (#10016)
Follow-ups to #10007, none of which change what the test command does.

The `paths:` filter listed individual source folders rather than the
projects the suite builds, so a change anywhere else in that build
produced no check at all. Of the last 40 merged pull requests, 31 touch
the test build and 15 of those ran no tests. #9976 and #9932 edit
`ServiceLib/Common/`, which every test depends on, and neither shows a
single check. `Directory.Build.props` is the sharpest case: it sets
`TargetFramework` and the Release options for every project, so an edit
there can break the test build without producing a workflow run at all.

The filter now follows the project graph instead. `ServiceLib.Tests`
references `ServiceLib`, which references `ServiceLib.UdpTest`, and
`Directory.Build.*`, `Directory.Packages.props` and `global.json`
configure that build. It is shorter than the list it replaces, needs no
edit when a test is added or a class moves, and still skips UI and
documentation work: of those same 40 pull requests, 9 stay filtered out.

`global.json` belongs there for a different reason: it does not affect a
single line of the code under test, but it decides whether the tests run
at all, so a bad edit there silently reproduces the failure #10007 fixed.

The Checkout step needs neither `submodules: 'recursive'` nor
`fetch-depth: '0'`. `GlobalHotKeys` is pulled in by `v2rayN.Desktop`
only, and nothing in this job reads git history.

`global.json` also gained the final newline `.editorconfig` asks for with
`insert_final_newline = true` under `[*]`.
2026-08-28 14:27:11 +08:00
Miheichev Aleksandr Sergeevich
c575527725 i18n(ru): translate newly added UI strings (#10015)
* i18n(ru): translate newly added UI strings

Translate the 3 strings missing from ResUI.ru.resx after the DNS
"Block AAAA Queries" toggle and the Xray-only certificate pinning
hint were introduced:

- TbXrayOnly, TbBlockAAAAQueries, TbBlockAAAAQueriesTips

Translated from the zh-Hans source and cross-checked against the
English resource. Russian regains full key parity with ResUI.resx
(583/583), and key ordering mirrors the English resource file.
Xray and the AAAA record type stay untranslated, matching the
established glossary; the phrasing follows the neighbouring
TbBlockSVCBHTTPSQueries label and the existing "При включении" tip pattern.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

* i18n(ru): translate TbBlockSVCBHTTPSQueriesTips left in English

The key existed in ResUI.ru.resx but its value was the untranslated
English text, so the DNS settings window mixed Russian and English
in the row right above the newly translated "Block AAAA Queries".

Translated from the zh-Hans source, which says "availability
queries" (可用性查询); the Russian follows that wording rather than
the English "checks". ECH, HTTP/3 and Xray stay untranslated,
matching the established glossary, and the tip keeps the
"При включении …" pattern used by the surrounding tips.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-28 14:26:02 +08:00
2dust
589ccc6e06 Bug fix
https://github.com/2dust/v2rayN/issues/10043
2026-08-28 14:24:12 +08:00
DHR60
0a2f3e4f22 Fix hy2 fmt (#10044) 2026-08-27 15:31:39 +08:00
dependabot[bot]
007adb6403 Bump TUnit from 1.65.38 to 1.65.63 (#10037)
---
updated-dependencies:
- dependency-name: TUnit
  dependency-version: 1.65.63
  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-08-26 19:42:53 +08:00
DHR60
e50c0a9170 Fix (#10035)
* Fix

* Fix

* Use HashSet instead of List

* Use HashSet instead of List for sing-box
2026-08-26 19:41:52 +08:00
2dust
af0eb9ed14 Code clean 7.24.8 2026-08-22 17:32:26 +08:00
DHR60
0436081436 Revert "fix(tun): automatically exclude proxy node IPs and resolved domains from TUN routing to prevent loops (#9974) (#10012)" (#10013)
This reverts commit 2be63d1655.
2026-08-22 15:02:24 +08:00
2dust
2a89a2e597 up 7.24.8 2026-08-22 15:01:25 +08:00
Mangoo
2be63d1655 fix(tun): automatically exclude proxy node IPs and resolved domains from TUN routing to prevent loops (#9974) (#10012) 2026-08-22 14:49:27 +08:00
DHR60
74bd28bbd0 Fix test (#10007) 2026-08-22 10:25:57 +08:00
DHR60
be501cbd2a Fix dependabot path (#10008) 2026-08-22 10:20:41 +08:00
Miheichev Aleksandr Sergeevich
e20b4dbfab chore(deps): update CliWrap and TUnit, drop unused test pins (#10005)
* chore(deps): update CliWrap and TUnit

- CliWrap                  3.10.4      -> 3.10.5
- TUnit                    1.65.0      -> 1.65.38
- TUnit.Assertions.Should  1.65.0-beta -> 1.65.38-beta

TUnit.Assertions.Should is versioned in lockstep with TUnit and published with
a -beta suffix. Its 1.65.0-beta package depends on TUnit.Assertions 1.65.0-beta,
so it has to move together with TUnit to keep the whole TUnit stack resolved on
a single version (TUnit.Assertions 1.65.38 after this change).

* chore(deps): drop unused AwesomeAssertions and xunit.v3 pins

Since the migration to TUnit (c9e843aa) no project references AwesomeAssertions
or xunit.v3 any more, so these two PackageVersion entries no longer pin
anything: neither package appears in any project.assets.json, directly or
transitively.

Verified by restoring, building and publishing the whole solution with and
without the two entries: the resolved package graph (769 entries across all
projects) and the published output of every CI target - v2rayN win-x64,
v2rayN.Desktop win-x64 and linux-x64, AmazTool win-x64, all self-contained -
are byte-identical, and ServiceLib.Tests stays at 69/69.
2026-08-22 10:19:29 +08:00
DHR60
728cbe70f2 Add block AAAA query support (#10004) 2026-08-22 10:18:48 +08:00
DHR60
26a86f9bd2 Fix (#10002) 2026-08-22 10:17:09 +08:00
DHR60
c66c55b05e Fix dnd (#10003)
* Fix dnd

* Fix
2026-08-22 10:13:21 +08:00
DHR60
ebb4bd5daa Optimize file download (#9952)
* Optimize file download

* Optimize func call
2026-08-21 14:15:54 +08:00
dayepao
14e27f3d23 fix: preserve Mihomo Reality short-id as YAML string (#9964) 2026-08-20 10:47:24 +08:00
DHR60
2d514ff480 Fix (#9991) 2026-08-19 13:48:59 +08:00
DHR60
11bd52b6a5 Fix (#9987) 2026-08-19 09:56:38 +08:00
JieXu
3b3fe8def3 Update build.yml (#9986)
* Update build.yml

* Update build-windows-x86.yml
2026-08-19 09:56:21 +08:00
DHR60
c9e843aa3b TUnit (#9981) 2026-08-19 09:54:51 +08:00
DHR60
7be264c65c Log with caller (#9976) 2026-08-17 14:33:33 +08:00
Miheichev Aleksandr Sergeevich
5e6660aeee chore(deps): update xunit.v3 and NLog, and drop the VSTest packages xunit replaces (#9975)
* chore(deps): update xunit.v3 to 4.0.0 and drop the VSTest packages

xunit.v3 4.0.0 moves from Microsoft.Testing.Platform v1 to v2, and MTP v2 drops the VSTest bridge on the .NET 10 SDK, so anything routed through VSTest now fails before a single test runs.

Rather than bridging back to VSTest, the two VSTest-era packages are removed. The test project is already an executable carrying xunit's own in-process runner, so Microsoft.NET.Test.Sdk and xunit.runner.visualstudio have nothing left to contribute, and without them no opt-in file is needed anywhere.

No source or test changes are required: every 4.0.0 breaking change is in the extensibility and runner APIs, and the suite uses only [Fact], [Theory] and [InlineData].

* ci: run the tests directly and let versions float on their major

test.yml requested the 8.0.x SDK while every project targets net10.0, which an 8.0 SDK cannot build (NETSDK1045), and it invoked dotnet test, which needs the VSTest bridge that MTP v2 has dropped. It now runs the test executable, which needs no adapter and no test SDK.

All three setup-dotnet steps ask for 10.x with quality ga, so a new .NET 10 patch or feature band is picked up automatically while previews and release candidates stay out of builds. setup-dotnet and upload-artifact were the only actions pinned to an exact patch; they now track their major tag like the other seven.

* chore(deps): update NLog to 6.2.0

A minor release with no API change on the surface this project uses. Verified beyond compilation: Logging.Setup builds its FileTarget, and both SaveLog overloads write through it at runtime with the expected layout.
2026-08-17 14:33:18 +08:00
JieXu
5b27f4836f Update package-rhel-riscv.sh (#9971)
* Update package-rhel-riscv.sh

* Update package-rhel-loong.sh

* Update package-debian-riscv.sh

* Update package-debian-loong.sh
2026-08-16 10:08:08 +08:00
2dust
e0ad2c46e6 up 7.24.7 7.24.7 2026-08-15 10:14:52 +08:00
2dust
230a2f6773 Bug fix
https://github.com/2dust/v2rayN/issues/9936
2026-08-14 12:08:43 +08:00
白龙
e7cc4c832e Fix tray server selection being cleared after refresh (#9927) (#9928)
* Fix tray server selection after refresh (#9927)

* Update StatusBarViewModel.cs

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-08-14 10:38:27 +08:00
DHR60
fb7033aab5 Add hy2 ech support (#9954) 2026-08-14 10:22:31 +08:00
DHR60
b6cc3913ac Perf hy2 fmt (#9953) 2026-08-14 10:22:10 +08:00
DHR60
bc06a5dc21 Fix (#9951)
* Fix

* Fix

* Add HandleSafe
2026-08-14 10:20:58 +08:00
Chen, Ting-An
9c1951178c fix(i18n): polish Traditional Chinese DNS settings (#9947)
Replace Simplified Chinese and ambiguous translations in the DNS and full configuration template settings with natural Taiwan terminology. Clarify related descriptions without changing resource keys or application behavior.
2026-08-14 10:20:16 +08:00
DHR60
b3df42b9ba Sync finalmask order (#9943) 2026-08-14 10:19:56 +08:00
liuclare
e01717d832 Narrow the TUN self-address drop rule to single addresses (#9935)
The rule added in #9897 takes the TUN inbound's `address` verbatim as `ip_cidr`,
so a /30 or /126 interface prefix becomes the match range.

sing-tun derives the TUN's DNS entry from the address right after the interface's
own and hands it to the system resolver: Windows through luid.SetDNS in
tun_windows.go, Linux through systemd-resolved in tun_linux.go, both guarded only
by AutoRoute && !EXP_DisableDNSHijack. HasNextAddress keeps that address inside
the interface prefix, every preset in Global.TunIPv4Address is a /30 and every
IPv6 preset a /126, and the sing-box system stack rejects single-address
prefixes, so there is no configuration where it falls outside.

Queries from the system resolver then hit the drop rule and time out with no
response and no ICMP. Name resolution fails for the whole system while the proxy
path itself stays healthy, which makes it read as a DNS outage rather than a
routing rule. Reported in #9934 and #9926.

Matching each address on its own keeps what #9897 set out to block - the loop it
diagnosed was addressed to the interface address itself - and leaves the DNS
entry to sing-box.

Also restores the two regression tests #9897 came with, removed by eff58459
(#9817) while its implementation and template fix stayed in place.
ShouldRejectTrafficToTunOwnAddresses now asserts the single-address form and
additionally pins the prefix length, so it covers both the loop it was written
for and the resolver address it must not cover.

Verified on Linux by running sing-box directly from a generated config, changing
only this rule's prefix length between runs:

  ip_cidr ["172.18.0.1/30"]   getent hosts www.google.com -> empty, 3/3
  ip_cidr ["172.18.0.1/32"]   getent hosts www.google.com -> resolved, 3/3

dig against a public resolver, naked-IP HTTPS and the local mixed port were
unaffected in both runs. End to end, a build of this branch emits
drop ip_cidr ["172.18.0.1/32"] and system resolution works while its TUN is up.

Co-authored-by: liuclare <177657698+liuclare@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 15:09:04 +08:00
DHR60
8b4063b44b Set tun "route only" to true (#9933) 2026-08-09 20:53:00 +08:00
DHR60
3136f573dd Revert "Fix Windows TUN restart issue (#9925)" (#9932)
This reverts commit f347fe1c03.
2026-08-09 20:52:36 +08:00
liuclare
e101b1d7b0 Always route IPv6 into Xray TUN regardless of EnableIPv6Address (#9930)
* Always route IPv6 into Xray TUN regardless of EnableIPv6Address

EnableIPv6Address controls whether the TUN interface is assigned an IPv6
address, but it also gated whether ::/0 was added to autoSystemRoutingTable.
With the default (false), IPv6 had no route pointing at the TUN device and
followed the system default route instead, leaving the tunnel unproxied and
exposing the host's real IPv6 address.

The embedded template SampleTunInbound already declares both families; the
generated config discarded it. #9843 restored ::/0 only inside the
EnableIPv6Address == true branch, so the false branch still leaks.

Route both families unconditionally and let the option control only the
interface address. The same conditional existed a second time in the
RouteExcludeAddress branch and is fixed as well.

Fixes #9929

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Add regression tests for IPv6 routing in the Xray TUN inbound

Both assertions fail on 31044f44 and pass with the fix:

  Tun_ShouldRouteIPv6IntoTunnel(enableIPv6Address: False)
    Expected collection {"0.0.0.0/0"} to contain "::/0".

  TunRouteExcludeAddress_ShouldIncludeIPv6Ranges
    Expected collection {...44 IPv4 ranges...} to have an item matching x.Contains(:).

The theory also covers enableIPv6Address: true, which passes on both revisions,
so the tests only fail while the defect is present. The gateway count assertion
pins the intended split of responsibilities: EnableIPv6Address governs the
interface address, never the routing table.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: liuclare <177657698+liuclare@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-09 20:15:18 +08:00
2dust
31044f449d up 7.24.6 7.24.6 2026-08-08 20:38:18 +08:00
2dust
eacf8b0784 Reuse inbound config and fix tun sniffing flag
https://github.com/2dust/v2rayN/issues/9921
2026-08-08 20:36:18 +08:00
Mangoo
f347fe1c03 Fix Windows TUN restart issue (#9925) 2026-08-08 20:20:41 +08:00
JieXu
71208eb711 Update build-windows-x86.yml (#9924) 2026-08-08 20:01:13 +08:00