Skip to content

fix(config): apply ipv4_only IPv6 mode so TUN doesn't hijack the default IPv6 route#140

Open
zZZTeJleTTy3uKZZz wants to merge 1 commit into
hiddify:mainfrom
zZZTeJleTTy3uKZZz:fix/ipv4-only-ipv6-mode
Open

fix(config): apply ipv4_only IPv6 mode so TUN doesn't hijack the default IPv6 route#140
zZZTeJleTTy3uKZZz wants to merge 1 commit into
hiddify:mainfrom
zZZTeJleTTy3uKZZz:fix/ipv4-only-ipv6-mode

Conversation

@zZZTeJleTTy3uKZZz

@zZZTeJleTTy3uKZZz zZZTeJleTTy3uKZZz commented Jul 15, 2026

Copy link
Copy Markdown

Problem

ipv6-mode: ipv4_only is parsed but never applied. Selecting "IPv4 only" has no effect on the generated sing-box config.

Root cause

In v2/config/builder.go, setInbound() derives IPv6 usage from isIPv6Supported() instead of the user's IPv6Mode. The code that would apply IPv6Mode is commented out (lines ~434-439 and ~459-469).

isIPv6Supported() only resolves the IPv6 loopback:

_, err := net.ResolveIPAddr("ip6", "::1")
return err == nil

which succeeds on virtually any host — even one with no global IPv6. So ipv6Enable is effectively always true: the TUN always receives an IPv6 address, auto_route captures the default IPv6 route, and inbounds bind to :: — regardless of the IPv4-only choice.

On hosts without global IPv6, browsers try AAAA first (Happy Eyeballs); packets enter the TUN but egress has no usable IPv6, so the TLS handshake is dropped (ERR_CONNECTION_CLOSED). Example: yandex.ru (routed .ru -> direct) fails over IPv6 while curl -4 succeeds. The only workaround is disabling IPv6 OS-wide.

Fix

ipv6Enable := isIPv6Supported() &&
    hopt.IPv6Mode != option.DomainStrategy(C.DomainStrategyIPv4Only)

Same conversion pattern already used in hiddify_option.go.

Verified (built and tested, not just theory)

Built this patch into hiddify-core.dll (from the v4.1.0 tree, Windows/amd64) and ran it under the installed Hiddify 4.1.1 on Windows 11, with ipv6-mode: ipv4_only and TUN enabled.

Before (stock core) — generated current-config.json:

"address": ["172.19.0.1/28", "fdfe:dcba:9876::1/126"],   // TUN takes an IPv6 address
"listen": "::"                                            // inbound binds IPv6

After (patched core) — same settings:

"address": "172.19.0.1/28",   // IPv4 only, as requested
"listen": "0.0.0.0"

Result: sites with AAAA records (e.g. yandex.ru) now load correctly over IPv4 through the TUN, with no OS-level IPv6 workaround needed.

Bonus: this also fixes failed to start background core on hosts where IPv6 is disabled OS-wide — the core no longer tries to bind :: or assign an IPv6 address to the TUN.

Notes

  • The same commented-out block also disables resolve-destination — worth restoring separately.
  • For hosts that do have global IPv6, a follow-up could also set dns.strategy: ipv4_only; getDNSServerOptions currently hardcodes prefer_ipv4, which does not drop AAAA.

Related: hiddify/hiddify-app#2172 (same symptom — same version, same ipv4_only, sites failing in VPN mode — reported without the IPv6 diagnosis).

…ult IPv6 route

The ipv6-mode: ipv4_only option was parsed but never applied. setInbound() used
isIPv6Supported() - which only resolves the IPv6 loopback and therefore succeeds
on virtually any host - instead of the user's IPv6Mode. As a result the TUN always
received an IPv6 address and auto_route captured the default IPv6 route, and
inbounds bound to ::, regardless of the IPv4-only choice.

On hosts without global IPv6 this black-holes every AAAA-first connection
(e.g. yandex.ru fails while curl -4 works).

Verified by building the patched core and running it under Hiddify 4.1.1: with
ipv4_only the TUN is now generated IPv4-only and AAAA sites load correctly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@zZZTeJleTTy3uKZZz
zZZTeJleTTy3uKZZz force-pushed the fix/ipv4-only-ipv6-mode branch from 061f87b to 275cde0 Compare July 16, 2026 11:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant