264 Commits
Author SHA1 Message Date
DHR60 fa1e201c76 Fix sing-box dns (#10234) 2026-09-26 10:39:29 +08:00
DHR60 143ada1358 Remove vnext (#10132) 2026-09-09 13:59:52 +08:00
DHR60 093b8d4c34 Adjust Clash API (#10088) 2026-09-03 20:21:46 +08:00
DHR60 f62eaab8c5 Support sing-box 1.14 (#9736)
* Support sing-box 1.14

* Unified format

* Support parallel dns

* Add `optimistic DNS caching` support

* Try fix serial multi DNS

* Add HttpClient support
2026-09-02 11:54:06 +08:00
64aad8027a Skip the TUN IPv6 route when the host has no global IPv6 address (#10080)
#9930 made the Xray TUN inbound always request ::/0 in autoSystemRoutingTable
so that IPv6 stops bypassing the tunnel. That only helps a host which actually
holds a globally routable IPv6 address. On any other host it does harm.

With IPv6 disabled the TUN device gets no IPv6 address at all, the kernel
rejects the route with EACCES and the whole inbound fails to start:

  Failed to start: app/proxyman/inbound: failed to start proxy > proxy/tun:
  failed to add system route ::/0 > permission denied

With IPv6 enabled but no global address the route is accepted and the host
gains an IPv6 default route it cannot use. The TUN completes the TCP handshake
locally before dialing the outbound, so IPv6 destinations start to look
reachable and get picked, and the connection then dies at the outbound instead
of failing fast (#10051).

Neither host has IPv6 traffic that could bypass the tunnel, so ::/0 buys them
nothing. Detect a global IPv6 address once while building the config context
and drop ::/0 when there is none. Link-local and unique local addresses do not
count: they never reach the IPv6 internet.

Co-authored-by: liuclare <177657698+liuclare@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-09-02 11:17:27 +08:00
DHR60 0d452328a2 Add wireguard remote dns support (#10036) 2026-08-28 14:38:43 +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
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
dayepao 14e27f3d23 fix: preserve Mihomo Reality short-id as YAML string (#9964) 2026-08-20 10:47:24 +08:00
DHR60 b3df42b9ba Sync finalmask order (#9943) 2026-08-14 10:19:56 +08:00
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
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 eacf8b0784 Reuse inbound config and fix tun sniffing flag
https://github.com/2dust/v2rayN/issues/9921
2026-08-08 20:36:18 +08:00
2dust e8cdd1cc02 Remove allowInsecure from the Xray Core
https://github.com/2dust/v2rayN/issues/9893
2026-08-05 18:48:39 +08:00
DHR60and2dust eff584597f Add custom outbound support (#9817)
* Add custom outbound support

* Add test

* Add inner fmt support

* Full config to outbounds

* Rename to `Outbound`

* AI optimized

* Fix

* Add bind interface placeholder

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-08-05 14:25:16 +08:00
Tylerrrkd e1e6c5ddb0 Fix infinite TUN routing loop on traffic to the TUN's own addresses (#9897)
* Restore the silently dropped embedded TUN routing rules

tun_singbox_rules declares "network": "udp" as a bare string, but
Rule4Sbox.network is a List<string>. System.Text.Json therefore throws on
the very first rule, and JsonUtils.Deserialize swallows it and returns
default. GenRouting only checks for null before AddRange, so the whole
embedded rule set is dropped without a trace.

Both rules it carries have thus never reached a generated config: the
NetBIOS/mDNS reject and the multicast reject. The mismatch predates the
sing-box 1.12 migration - the template has used the string form since the
rules file was introduced.

- declare network as an array so the template matches Rule4Sbox

* Drop traffic addressed to the TUN's own addresses

With auto_route the TUN steals the default route, so a packet whose
destination is the TUN interface's own address is handed to sing-box instead
of being looped back by the kernel. Routing then matches ip_is_private and
sends it to `direct`, whose interface is auto-detected as the TUN again, so
the packet is written straight back into the TUN and re-enters routing. The
loop never terminates and pins a CPU core.

Seen in the wild on macOS: a WebRTC client offered the TUN's own
fc00::172:18:0:1 ULA as an ICE candidate and the resulting STUN
connectivity checks sustained ~8k packets/s out of the interface at 800%
CPU, 21 GB written to the TUN over five hours - against 3 GB read, the
asymmetry that gives the loop away.

Nothing legitimate is addressed to those addresses, so reject them before
any outbound rule can match. Use method "drop" rather than the default
ICMP unreachable, whose destination would be the looping address itself.

- reject the TUN inbound's own addresses, taken from the generated inbound
  so the two cannot drift apart
2026-08-05 10:35:37 +08:00
XXcipherXand2dust 074ce5de04 Fix missing IPv6 default route for Xray TUN (#9843)
* Fix IPv6 route for Xray TUN

* Update V2rayInboundService.cs

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-07-28 10:11:20 +08:00
hyjhyj111 02df430172 Use the TUN context snapshot in remaining launch-path reads (#9831)
Follow-up to #9830: audit of all TunModeItem.EnableTun usages found
three more launch-path reads of the live mutable config where the
behavior must agree with the context snapshot that generated the
config:

- CoreConfigClashService (mihomo custom config): the tun section was
  decided from the live config while the mihomo launch elevation uses
  the snapshot; a mid-reload toggle could produce a config containing
  tun launched without sudo, the same failure fixed in #9830. The tun
  state is now passed in as a snapshot.
- CoreManager.LoadCore: the Windows RemoveTunDevice cleanup now checks
  the main/pre context snapshots.
- CoreManager.WaitForProxyPort: preContext.AppConfig is a shared live
  reference; use preContext.IsTunEnabled instead.

Reads that intentionally stay live: StatusBarViewModel (UI state
source), CoreConfigContextBuilder (the snapshot capture point),
GetPreSocksItem (called during snapshot construction, self-consistent),
and AppManager.StatePort2 (transient mid-reload skew only, self-heals
after reload).
2026-07-27 21:13:28 +08:00
2dust dc216c2b02 Rename TunIp to TunIP 2026-07-26 21:07:36 +08:00
2dust b01476d147 Fix tun inbound dns setting 2026-07-26 10:29:35 +08:00
2dust cd77f1d882 Code clean 2026-07-24 16:57:19 +08:00
2dust e749b81ecf Add configurable TUN IPv4/IPv6 addresses
https://github.com/2dust/v2rayN/issues/9810
2026-07-24 10:13:08 +08:00
DHR60 a37772f12b Fakeip (#9786)
* Add fakeip range

* Xray fakedns
2026-07-18 17:47:14 +08:00
DHR60 4584ecc5c9 Add HappyEyeballs (#9772)
* Add HappyEyeballs

* Clean up the code

* Fix
2026-07-17 09:12:50 +08:00
DHR60 f55d8b2565 Sync xray (#9708)
* Sync xray fragment

* Sync xray freedom domainStrategy

* Add Strategy4ProxyDial
2026-07-16 18:55:06 +08:00
DHR60 09ea4890a7 Fix (#9771) 2026-07-16 17:37:17 +08:00
DHR60 e615314582 Xray tun route only (#9759) 2026-07-15 19:12:34 +08:00
DHR60 74ab7ad097 Add ProtectCoreTypeList (#9756)
* Add ProtectCoreTypeList

* Add process path restrictions
2026-07-15 17:32:07 +08:00
2dust 994bc1ca6a Code clean 2026-07-11 17:43:32 +08:00
DHR60 a0bd8f9934 Remove fallbackTag (#9728) 2026-07-11 15:18:16 +08:00
006lpand2dust 88d59488fd feat: support custom headers for Xray HTTP outbounds (#9690)
* feat: support custom headers for Xray HTTP outbounds

* feat: simplify HTTP outbound headers input

* feat: validate JSON syntax in HTTP headers

  Keep HTTP outbound headers stored as raw text, while validating
  header names and values against RFC 9110/9112 syntax. Support string
  arrays for multi-value headers, reject duplicate JSON header keys, and
  clarify the invalid header JSON message.

* feat: refactor HTTP header parsing into utility

* Simplify code

* Simplify code

* Update CoreConfigV2rayServiceTests.cs

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-07-11 14:31:17 +08:00
DHR60 2c70b018ce Revert "Fix" (#9727)
* Revert "Fix"

This reverts commit 45ab7503e3.

* Fix
2026-07-11 14:02:12 +08:00
2dust 45ab7503e3 Fix
https://github.com/2dust/v2rayN/issues/9699
2026-07-11 11:20:36 +08:00
DHR60 31e32f174e Fix (#9648) 2026-07-02 09:20:14 +08:00
dr mike bf376a8fac fix(hysteria2): emit https server_url for sing-box realm outbound (#9642)
sing-box requires realm.server_url as a full URL (https://host:port).
Bare host:port caused "missing host in realm server_url" on import.
Also forward stun_servers and clear ResolveRealm success message.

Fixes #9635
2026-06-28 11:05:41 +08:00
DHR60 ef46f4e7e6 Hysteria Realm & Gecko (#9516)
* Hysteria Realm

* Core config

* Fix

* Fix

* Add Gecko support
2026-06-22 20:52:47 +08:00
Enqvyand2dust 81c118c9b2 customizable packet fragmentation settings (#9597)
* first changes

* fix: use ItemsSource for fragment packets ComboBox so value saves correctly

* feat: add customizable packet fragmentation for Xray-core

- Add fragment settings in Core tab: Packets (dropdown), Length (range), Interval (range), MaxSplit (0-10000)
- Support both 'from-to' (e.g., 50-100) and single value (e.g., 50) formats for Length, Interval, and MaxSplit
- Validation with shortened error message: 'Invalid range format. Use from-to (e.g., 50-100).'
- UI in PopupBox (materialDesign) visible only when EnableFragment is checked
- Only Xray-core supported (Mihomo/sing-box fragment code removed)
- Localization updated for 8 languages

* fix: address 2dust review feedback

- Move FragmentPacketsOptions to Global class
- Remove default values from Fragment4RayItem model (set in ConfigHandler)
- Fix Avalonia bindings: move ItemsSource and SelectedItem to code-behind
- Update ViewModel to use Global.FragmentPacketsOptions
- Remove defaults from model properties

* Adjust ui

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-06-22 16:00:13 +08:00
DHR60 ce380b861c Node check (#9603) 2026-06-20 10:09:27 +08:00
2dust 00903d3531 Verify if sendThrough is a local address.
https://github.com/2dust/v2rayN/issues/9562
2026-06-19 18:09:18 +08:00
DHR60 3d4f202cd7 Metrics listen directly (#9533) 2026-06-12 09:47:59 +08:00
DHR60 e6d08c2db1 Code clean (#9482) 2026-06-06 11:20:06 +08:00
DHR60 27b8f889fe Tail Fragmentation (#9476) 2026-06-05 19:45:49 +08:00
DHR60and2dust 0d5169e4cd Remove global AllowInsecure and MuxEnabled (#9473)
* Remove global AllowInsecure

* Remove global MuxEnabled

* Fix core config

* Centralize AllowInsecure handling

* Warn insecure configuration

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-06-05 15:31:23 +08:00
DHR60 abcdd9497c Support new kcp config (#9477) 2026-06-05 15:08:57 +08:00
DHR60and2dust b6cfce069a Xray Route Exclude Address (#9469)
* Add IPNetwork2 package

* Xray Route Exclude Address

---------

Co-authored-by: 2dust <31833384+2dust@users.noreply.github.com>
2026-06-05 09:54:57 +08:00
2dust ce8caa89a4 Add Route Exclude Address setting and UI for sing-box tun
https://github.com/2dust/v2rayN/issues/9456
2026-06-04 15:55:09 +08:00
2dust b2bbc865af Add VerifyPeerCertByName support
https://github.com/2dust/v2rayN/issues/9427
2026-06-03 09:56:34 +08:00
2dust 1e59344074 Add balancer fallbackTag
https://github.com/2dust/v2rayN/issues/9401
2026-05-29 09:55:59 +08:00