Commit Graph

1125 Commits

Author SHA1 Message Date
youugiuhiuh f07e3dc415 fix(resx): restore HeaderContextMenu localization resources accidentally overwritten during merge (#10553) 2026-11-08 20:35:03 +08:00
youugiuhiuh 0f71c46d3b feat: support Xray XDRIVE object storage relay transport (#10546) 2026-11-08 20:02:40 +08:00
Lyu Bingrong 968beb4432 feat(core): support AUTO option and filter non-IP NDIS interfaces for BindInterface (#10519)
* feat(core): support AUTO detection and manual selection for BindInterface (#10519)

- Implements the 3-state design agreed in #10519:
  1. Empty: do not bind interface, preserve existing behavior.
  2. AUTO: automatically detect default active physical network interface and bind to it.
  3. Specific interface: prioritize user-selected network interface.
- Centralizes interface resolution in NetworkUtils.GetRealBindInterfaceName().
- Supports AUTO in CoreConfigContextBuilder, Singbox, and V2ray template services.
- Adds comprehensive unit tests covering AUTO detection, context validation, and config generation.

* refactor: optimize AUTO bindInterface resolution and add mock-based tests

- Resolve AUTO interface once in CoreConfigContextBuilder and store in CoreConfigContext.ResolvedBindInterface as single-source-of-truth
- Downstream sing-box and Xray outbound/TUN services consume ResolvedBindInterface directly
- Unify TrimEx and case-insensitive check via NetworkUtils.IsAuto to tolerate user input whitespace
- Log and issue validator warning when AUTO fails to resolve any physical adapter
- Extract pure SelectDefaultInterface function with NetworkInterfaceCandidate for deterministic, mock-based unit testing
- Add comprehensive unit tests covering Ethernet vs Wi-Fi preference, no-gateway fallback, and virtual adapter filtering

* refactor(network): filter non-IP NDIS interfaces and simplify AUTO bindInterface resolution

* fix(ui,network): align BindInterface ComboBox width and refine physical NIC matching

* Update CoreConfigContextBuilder.cs

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-11-08 16:53:06 +08:00
tt2563 1e167449ea Update ResUI.zh-Hant.resx (#10511)
* Update ResUI.zh-Hant.resx

Update ResUI.zh-Hant.resx

* Update ResUI.zh-Hant.resx
2026-11-08 16:35:03 +08:00
Aleksey Fedorov 73670c70d5 fix(singbox): keep the ws path query when removing ed (#10548)
Removing "?ed=2048" from a WebSocket path also removed the '?', so
"/ws?ed=2048&key=value" was sent to sing-box as "/ws&key=value".
Match "ed" without the separator in front of it and trim the
leftover '&' or '?' instead.
2026-11-08 16:34:30 +08:00
DHR60 5ca37027fd Fix udphop (#10550) 2026-11-08 16:02:49 +08:00
DHR60 54ecc045b5 Add HeaderContextMenu (#10547)
* Add HeaderContextMenu

* Up

* Up
2026-11-08 16:00:47 +08:00
DHR60 92a9da8b6b Refactor download (#10534)
* Refactor download

* webapi

* Fallback

* Fix Sub

* Life cycle

* Yet another way of the life cycle

* Shared CookieContainer

* Fix
2026-11-08 15:47:24 +08:00
Denis Elkhov 5211b9ce0e feat: add sing-box TUN dns_mode setting (#10336) 2026-11-07 14:44:37 +08:00
2dust 052f6f0fec Suggest local interfaces in bind setting 2026-11-06 15:19:31 +08:00
Wei-Lun Li 2010477f38 fix(fmt): keep a ':' in a Naive password through export and import (#10526)
NaiveFmt.ToUri percent-encodes the username and password, so a
password-only profile with the password a:b is exported as
naive+https://a%3Ab@host. Resolve decoded the user info before
looking for the ':' separator and imported it as username "a",
password "b". Split the raw user info first and decode each part.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-05 20:13:47 +08:00
DHR60 92aa3ba6dd Adjust Download Configuration (#10531) 2026-11-05 20:12:03 +08:00
DHR60 66546700b0 Fix UI (#10527)
* Revert "Cache selected views in SimpleViewLocator"

This reverts commit 8ebbd7f4f8.

* Fix UI

* Optimize Styles

* Code clean
2026-11-05 10:08:04 +08:00
Miheichev Aleksandr Sergeevich 9a029a3f7e fix: resolve JSON and SQLite trimming warnings (#10513)
Use generated JSON type metadata and propagate mapped SQLite types through CRUD and transactional bulk operations. Cover serialization options, affected counts, rollback and native test compatibility without changing UI models or persistence entities.
2026-11-04 17:56:43 +08:00
yc99-gif 2239982a63 feat(dns): support optional IPv6 FakeIP pools (#10464) 2026-11-04 09:51:43 +08:00
Wei-Lun Li 0d9e84556e fix(fmt): decode the SIP002 plain-text password only once (#10520)
For a SIP002 link whose user info is "method:password" rather than
base64 (the 2022-blake3 form), ResolveSip002 unescapes the whole user
info and then unescapes the password a second time. A password that
still holds a valid percent sequence after the first pass decays:
p%41ss is written as p%2541ss and imported as pAss.

Same double-decoding as #10027 fixed for query values.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 09:34:45 +08:00
Wei-Lun Li ff9fd7b988 fix(fmt): default the AnyTLS and Naive port to 443 when the link omits it (#10504)
The AnyTLS URI scheme makes the port optional and defaults it to 443,
and two of its three examples leave it out. The naive+https:// and
naive+quic:// link format does the same: the port is omitted when it is
443, and none of its examples carries one.

System.Uri answers -1 for an unregistered scheme with no port, so these
links were imported with Port = -1 and the profile failed IsValid().
Apply the same default Hysteria2Fmt already uses (#10026). An explicit
":0" is still kept as 0.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 19:44:03 +08:00
DHR60 fe54a73d74 Fix ipinfo copy functionality (#10515)
* Fix ipinfo copy functionality

* Code clean

* Code clean
2026-11-03 19:43:06 +08:00
Wei-Lun Li 522bca492c fix(fmt): import legacy base64 SOCKS links again (#10505)
SocksFmt.Resolve tries ResolveSocksNew first and only falls back to the
legacy socks://base64(user:pass@host:port) parser when System.Uri
rejects the link. System.Uri accepts most legacy links, though: it takes
the base64 as the host (lower-cased) and anything after a '/' as the
path. It only rejects a base64 that ends in '=' padding and has no '/',
so links without padding, or with a '/' or '_' in the base64, were
imported with the base64 as the address, port -1 and no credentials.

A legacy link has no port of its own, so let ResolveSocksNew give up
when the URI has none and leave the link to ResolveSocks.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-03 16:00:48 +08:00
DHR60 0f1f82af4e Fix (#10501) 2026-11-02 15:42:27 +08:00
DHR60 19850f92be Profile pre-resolver (#10220)
* Profile pre-resolver

* Try cname

* UI
2026-11-02 15:02:44 +08:00
Shubham Padkonde 4c4449e74d fix: match proxy group types without case sensitivity (#10472) 2026-11-02 09:53:18 +08:00
DHR60 59487dca75 Add MASQUE warp support (#10498) 2026-11-02 09:30:09 +08:00
DHR60 d4880dbe02 Fix policy group (#10495) 2026-11-02 09:29:45 +08:00
DHR60 0856ffd7d8 Try fix dns (#10485) 2026-11-02 09:27:59 +08:00
Shubham Padkonde c436b998b4 fix: persist repeated profile test results (#10466) 2026-11-02 09:26:34 +08:00
DHR60 8c02b5f2f6 Update cert workflow (#10497)
* Update cert workflow

* Update certificate
2026-11-02 09:24:18 +08:00
Miheichev Aleksandr Sergeevich 756916978d fix(xray): stop emitting obsolete echForceQuery (#10480) 2026-11-01 21:11:17 +08:00
DHR60 70ab27e436 Fix udp test (#10484) 2026-11-01 20:58:58 +08:00
DHR60 9593b289b9 Fix (#10460) 2026-11-01 20:54:43 +08:00
DHR60 5664270be7 Update cert (#10450) 2026-11-01 20:54:27 +08:00
Lukas 926790b071 fix(speedtest): clear the last speed when a speed test starts (#10449)
A speed test only stored a speed above zero, so a node that was skipped
because its delay test failed, or whose download failed, kept the speed
of the previous run. The list showed the skip or error text until it was
sorted or refreshed; then the old speed came back and the node sorted as
if it had been measured. Clear the stored speed when a speed or mixed
test starts.
2026-11-01 20:53:45 +08:00
Ekko82 e1c9633535 fix: keep the PAC listener running after a client reset (#10447)
* fix: keep the PAC listener running after a client reset

* Update PacManager.cs

* Update PacManager.cs

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-11-01 20:50:32 +08:00
UnrealTale 36184045bb Fix (#10431) (#10432) 2026-11-01 20:44:44 +08:00
Wu Shuwen 7e14cf9773 Preserve subscription profiles on failed import (#10429) 2026-11-01 20:43:48 +08:00
Wu Shuwen ad3e24b6b5 Fix fragment packet selection for REALITY (#10428) 2026-11-01 20:39:08 +08:00
DHR60 8b93d35766 Add ProDataGrid (#10347)
* Bump Avalonia.Desktop from 12.1.2 to 12.1.4

---
updated-dependencies:
- dependency-name: Avalonia.Desktop
  dependency-version: 12.1.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* Remove Avalonia.Controls.DataGrid

* Add ProDataGrid Feature

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-11-01 20:34:24 +08:00
DHR60 78b0b2224b Native Aot (#10295)
* Protect models

* Json Context

* YAML AOT-friendly optimization

* Run the Test in AOT mode

* Remove TaskScheduler

* Clean build output

* Workflows
2026-11-01 20:29:06 +08:00
DHR60 e2f4292321 ReactiveUI 26 (#10249)
* ReactiveUI 25

* Fix

* Up

* ReactiveUI 26
2026-11-01 20:00:02 +08:00
Nozilla-X 57f17d5939 fix(profile-ex): make ProfileExItem creation atomic per IndexId (#10420)
ConcurrentBag only makes individual operations safe. GetProfileExItem performed FirstOrDefault and AddProfileEx as separate operations, so concurrent speed tests could both miss and create duplicate entries for the same IndexId. Recheck under a dedicated lock before creating, and replace the bag under the same lock in InitData/ClearAll so creation cannot target a bag that is being swapped. Existing reads and item updates stay lock-free.
2026-10-20 16:58:12 +08:00
DHR60 5e0ea3275d Fix (#10404) 2026-10-18 19:23:03 +08:00
Dmitry 673283da4b Fix data race in ProfileExManager (#10388)
* Fix data race in ProfileExManager

Parallel speed tests over many profiles corrupt the save queue of test results: IndexIdEnqueue touches a plain Queue<string> from every test thread, so Contains plus Enqueue race - the same profile gets queued twice, and Queue.Contains can even throw ArgumentOutOfRangeException out of SetTestDelay, losing the result. SaveQueueIndexIds has the same class of bug: it snapshots Count and then dequeues in a loop, so concurrent enqueues throw or lose entries. GetProfileExItem could create duplicate rows for the same index the same way.

Guard the queue and the profile lookup with a lock and drain a snapshot instead of a stale count. No behavior change besides correctness.

* Fix data race in ProfileExManager

Parallel speed tests over many profiles corrupt the save queue of test results: IndexIdEnqueue touches a plain Queue<string> from every test thread, so Contains plus Enqueue race - the same profile gets queued twice, and Queue.Contains can even throw ArgumentOutOfRangeException out of SetTestDelay, losing the result. SaveQueueIndexIds has the same class of bug: it snapshots Count and then dequeues in a loop, so concurrent enqueues throw or lose entries.

Switch the queue to ConcurrentQueue and drain it with TryDequeue. As suggested in review, duplicates are not filtered anymore: this is a helper, and the save loop just writes the same row more than once.
2026-10-17 19:37:43 +08:00
DHR60 f1023e08e1 Fix (#10344)
* chore. update core urls

* Fix clash delay
2026-10-13 20:36:41 +08:00
Ali Ahmadi 2407d44f4f Fix empty latency tests and Linux startup errors (#10335)
* Fix overflow when speed tests have no eligible profiles

* Preserve core executable permissions in Debian packages

* Avoid requesting an icon refresh before view initialization
2026-10-11 11:06:46 +08:00
liu-xindi 4869a6cbba Route IPv6 into the Xray TUN when EnableIPv6Address is on (#10329)
* Route IPv6 into the Xray TUN on NAT66 hosts and when IPv6 is enabled

#10080 dropped ::/0 from autoSystemRoutingTable whenever the host held no
address inside 2000::/3. A host behind NAT66 holds only unique local
addresses, yet it reaches the IPv6 internet through its IPv6 default
gateway. With ::/0 gone, its IPv6 follows the system default route,
bypasses the tunnel and exposes the real IPv6 address (#10327).

The check also overrode EnableIPv6Address. Before #9930, enabling it
always added ::/0; since #10080 the option only assigned the interface
address, so users who had enabled it were affected as well.

Route ::/0 when EnableIPv6Address is on, and otherwise when the host has
IPv6 connectivity: a global IPv6 address or an IPv6 default gateway.
Routes whose next hop is ::, such as the one the tunnel installs, do not
count. A host with neither, as in #10051, still skips ::/0. The
RouteExcludeAddress branch uses the same decision.

Reproduced in network namespaces with Xray 26.7.28: on a NAT66 client the
7.25.4 TUN inbound let curl -6 reach the echo server from the NAT66
address, while the inbound generated by this change sends it through the
proxy, with EnableIPv6Address on or off.

Fixes #10327

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* Simplify: route ::/0 when EnableIPv6Address is on

Drop the rename and the gateway detection; keep HasGlobalIPv6Address
and let EnableIPv6Address override it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0142Bna7M2GhesX7P7d4CSrt

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 10:55:39 +08:00
DHR60 b501efbc45 Fix (#10326) 2026-10-10 09:14:30 +08:00
DHR60 771ef3192a Update cert (#10308) 2026-10-07 11:04:58 +08:00
ariansharifi d099e44ff6 Fix subscription custom configs ignoring custom config socks port (#10296)
* Fix subscription custom configs ignoring custom config socks port

Full Xray/sing-box configs imported from a subscription no longer got the
subscription's "Custom config socks port" (SubItem.PreSocksPort) after
eff5845 and 9638b4c. 7.24.4 and earlier copied it onto every imported
config, and the Clash, Hysteria2 and raw-file paths still do.

Without it, GetPreSocksItem builds no pre-socks core for these profiles,
so they cannot be used in TUN mode. Setting the port on the profile is
not a workaround, because every subscription update re-creates the
profiles.

* Add regression test for subscription custom config socks port
2026-10-05 16:36:52 +08:00
2dust 3187eeef79 Code clean 2026-10-04 11:41:34 +08:00
Miheichev Aleksandr Sergeevich 3364ec0e57 i18n(ru): translate the update dialog buttons in full (#10291)
Add the Russian string for menuCheckAndUpdate, which #10282 added to
ResUI.resx, as "Проверить и обновить". Restore the full Russian text
of menuCheckOnly ("Только проверить") and menuCheckUpdate ("Проверить
обновления"), which were shortened only to fit the fixed 100 px
buttons of the update dialog; they fit once the buttons are sized by
their labels.
2026-10-04 11:08:10 +08:00