Skip to content

Direct/Freedom outbound: Better Compatibility#6058

Open
Meo597 wants to merge 8 commits into
mainfrom
finalrules
Open

Direct/Freedom outbound: Better Compatibility#6058
Meo597 wants to merge 8 commits into
mainfrom
finalrules

Conversation

@Meo597
Copy link
Copy Markdown
Collaborator

@Meo597 Meo597 commented May 2, 2026

按照下面的讨论,现在是这样的:

freedom.domainStrategy 已经干掉了,自动兼容旧配置并提醒用户

  • 有 proxySettings.tag 时,且 targetStrategy 为 AsIs 则旧配置自动覆写为 targetStrategy
  • 旧配置默认覆写为 sockopt.domainStrategy

freedom 新增选项 privacyGuard,它有三种状态:未设置、显式 true、显式 false

  • 未设置时,盾尽量开启,除非 targetStrategy/sockopt.domainStrategy 是非 AsIs
    翻译下就是“用户有策略听用户的,否则 v4 优先”
  • 显式 true 时,一旦 targetStrategy/sockopt.domainStrategy 不是 v4 优先,会警告并强制覆写为 UseIPv4v6
    翻译下就是“一旦显式设置,必须保证 v4 优先”
  • 显式 false 不覆写,因此 sockopt.domainStrategy 的 AsIs 可以生效

finalRules 现在不会覆写 IP,而且 freedom 也不允许覆写 IP,都是偷看 sockopt 策略,解析出来判所有 IP

  • 如果是 SRV/TXT 则会漏一个 SYN
  • 如果有 dialerProxy 之类的东西,只能尽力而为,因为就算改写成 IP 他们也可以嗅探了再重新解析,毫无意义

意思是在 freedom 真的是最终出站时绝对有效,但若还有 sockopt.dialerProxy、proxySettings.tag、sockopt.addressPortStrategy 时则尽力而为

UDP domain 有更好的兼容性不再偏好 v4,无论用户设了哪个 strategy 都会和 TCP 行为完全一致

@Meo597

This comment was marked as outdated.

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

必须狠狠教育一下了,发版在即,不要把尚需大量讨论的新变动和 bug fix 放一个 PR 里,不然怎么发版,甚至还是个 draft

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

6. UDP 发包那块 `b.UDP == nil` 时会漏掉过滤,给补上了
   不清楚什么情况会走到这里,但我看本来就有原样发出去的行为

这种情况有几种可能,比如 VLESS 没走 XUDP,就不会赋值 b.UDP,之前 ipsBlocked 是没问题的,现在 dial 那里放过了 UDP

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 2, 2026

怕耽误发版标记为 draft
这个 PR 主要目的是恢复一些 finalrules 破坏掉的的兼容性
凭感觉写的我还没测

#6027 (comment)
#6027 (comment)
#6027 (comment)
#6027 (comment)
#6027 (comment)
#6027 (comment)

之前说了一大堆 0 人在意

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 2, 2026

主要是想兼容老哥的 happyeyeballs
虽然我不用,但看着难受。。。

这些边角的 BUG 早就存在了
没人反馈过 XTLS/Xray-docs-next#781 (comment)

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

还有其它一些情况会导致序号 6,但我看了下代码倒是又发现了别的问题,如果 UDP 那里

if c, ok := iConn.(*internet.PacketConnWrapper); ok {

这个断言失败,就不会走到自定义的 PacketReader/Writer,而是 buf.PacketReader/buf.SequentialWriter,绕过了过滤逻辑

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 2, 2026

那再包一层,我开个 PR 单独修这几项呗

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

你开个 PR,这样吧:

  1. 这种服务端的封锁,为了避免客户端重试 dial TCP 或发包 UDP,只要第一个 dest 命中 block,随机 30-90s 后关闭连接
    finalRules 加个 blockDelay 允许配置随机多少秒,Block/Blackhole outbound: Better blocking UDP #6057 要不要改以后再讨论
  2. 针对刚刚说的 Direct/Freedom outbound: Better Compatibility #6058 (comment) 再包一层
  3. 想到除了 Direct/Freedom 出站,DNS 出站也可能把 DNS 漏到 CN IP,以后再说吧,毕竟那个默认是 hijack

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

#6058 (comment) 基本上只是因为 NG 自定义 dialer,然后又出现了域名的问题,还是先不管它吧,你先把上面的 1 给 PR 了

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 2, 2026

blockDelay 感觉又堆砌了个选项进来
要不先给默认了缓解下这个问题,我感觉这块以后还会长成现在这个 PR 的样子

毕竟这些 feature 理论上不该冲突,只是得益于屎山代码。。。

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

并非“理论上不该冲突”,这里的一些东西它理论上就是冲突的,因为 finalRules 要求在 freedom 这步就解析出 IP,这必然要跳过 sockopt 的 domainStrategy 和 happyEyeballs;就算这俩能读取,你要配置 dialerProxy 的话那还是控制不了它最终实际上 dial 到哪,此时 finalRules 可能根本就没意义;NG 自定义 dialer 可能有自定义域名解析策略等,这就更不该提前解析出 IP 了

并非“屎山”而是可能的用法太多了,我的意思是这个特性目前只针对服务端,先不考虑客户端的那些情况

blockDelay 并非堆砌选项而是服务端 block 就该有的东西,不然客户端 dial TCP 重试五次,GFW 看到五个立马关闭的连接

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 2, 2026

ok 明白了

漏掉了 TCP 那个客户端行为在墙眼里是什么样

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

漏掉了 TCP 那个客户端行为在墙眼里是什么样

那取决于被代理的应用了,代理层 dial 是成功了不会 retry,但应用层可能发现一发数据就被关连接,所以可能会重试几次

@RPRX
Copy link
Copy Markdown
Member

RPRX commented May 2, 2026

根据 #6060 更新下文档然后 rebase 一下,剩下的讨论在这里进行

其实也没那么复杂,#6058 (comment) 都列举清楚了,区分服务端/客户端后就清晰很多

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 3, 2026

文档改好了,UDP 断言失败不会逐包过滤暂时没提

@patterniha
Copy link
Copy Markdown
Collaborator

patterniha commented May 4, 2026

I still don't know why we need multi-domain-udp-cone, if I were the decision maker, I would remove multi-domain-udp-cone-support and also remove freedom-domainStrategy (which coexistence with sockopt-domainStrategy causes confusion), then move finalRules-code to dialer and enable xray-happyEyeballs by default and use "localhost-dns" for "AsIs", then all the problems would be solved!

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 4, 2026

只有 freedom 才需要最终过滤
目的是控制用户出站流量,而非所有连接

@patterniha
Copy link
Copy Markdown
Collaborator

patterniha commented May 4, 2026

@Meo597 @RPRX

addrs, err := net.DefaultResolver.LookupIPAddr(ctx, dialDest.Address.Domain())
if err != nil {
errors.LogInfoInner(ctx, err, "failed to get IP address for domain ", dialDest.Address.Domain())
} else if len(addrs) > 0 {
if addr := net.IPAddress(addrs[dice.Roll(len(addrs))].IP); addr != nil {
dialDest.Address = addr
errors.LogInfo(ctx, "dialing to ", dialDest)
}
}

this code disable both xray and go happyEyeballs, also net.DefaultResolver.LookupIPAddr returns both v4 and v6 ips (even our server has ipv4 only),

so it is possible that an ipv6 is selected but our server has ipv4 only.

so we should filter IPs before we choose one at random (use "queryStrategy": "UseSystem" code here)

///

but it is still possible that our server has an inactive ipv6 interface or one ip type is disabled at target-side, so disabling happyEyeballs is not good idea at all.

so finalRules should filter ips, and then pass the filtered-ips to xray-happyEyeballs, and we should also enable xray-happyEyeballs by default.

@patterniha
Copy link
Copy Markdown
Collaborator

只有 freedom 才需要最终过滤 目的是控制用户出站流量,而非所有连接

if outboundName == "freedom" && dest.Network == net.Network_UDP && origTargetAddr != nil && src == nil {

we can check outboundName == "freedom" in dialer, i also used this for another problem.

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 4, 2026

为了让你的 udpdomain 和 happyeyeballs 行为一致
就必须得在 freedom 偷看 sockopt
跟是否删掉 freedom.domainstrategy 无关

既然已经偷看了,那就没必要改 dialer 让能传递多个 dest 下去

@patterniha
Copy link
Copy Markdown
Collaborator

patterniha commented May 4, 2026

???
you select ipv6 for ipv4-only-server, this is critical problem and should be solve quickly.

you can prioritize ipv4 when selecting ip, but most of the time ipv6 has better performance and it is not future-proof.

I don't understand your resistance to using xray-happyEyeballs (this is not about the properties of happyEyeballs-v2, this is about the essential properties of happyEyeballs-v1)

///

I still think we should remove multiple-domain-udp-cone support, anyway we can keep it and have duplicate finalRules-code in freedom (or keep finalRules-code in freedom and just pass the filtered-ips via ctx)

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 4, 2026

I still think we should remove multiple-domain-udp-cone support

不能因为你的两个功能互相打架就把其中之一删掉

finalrules udpdomain 都和 happyeyeballs 冲突
现在不就是为它擦屁股吗
不宜做更广泛的改动

以及 ipv6 跨国路由绝大多数情况下都比 ipv4 烂

@patterniha
Copy link
Copy Markdown
Collaborator

patterniha commented May 4, 2026

finalRules should act as a filter for tcp and then pass the filtered-ips via ctx to dialer-happyEyeballs, otherwise choosing only one ipv4 will definitely weaken the performance of Xray-core.
@RPRX i can open a simple PR for that, anyway, even if you don't agree, you can just prioritize ipv4 when selecting ip for finalRules and release the new version, this is important problem and should be fixed soon.

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 4, 2026

首先你这玩意也就客户端用
其次我不提根本没人在意这个兼容性

就别为这个东西再大肆破坏现有结构了

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 4, 2026

再多 thumbs down 你的 udpdomain 还是和 happyeyeballs 打架
自己的 PR 应该自己负责,至少不应该冲突

@patterniha
Copy link
Copy Markdown
Collaborator

it seems prefect.

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 6, 2026

thx

@patterniha
Copy link
Copy Markdown
Collaborator

patterniha commented May 7, 2026

@Meo597

I couldn't convince @RPRX to use Xray-happyEyeballs for finalRules in the end.

so rebase this PR base on d9fa5b4.

this is also important PR because it solve udpDomain-happyEyeballs-conflict and some other problems.

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 7, 2026

回头等讨论出结果我再 rebase

@KobeArthurScofield
Copy link
Copy Markdown
Contributor

现在是 Direct/Freedom 除了直接转发之外还干了路由和 Block/Blackhole 的活

这样的话,不如:

  1. 把 Direct/Freedom 的 DomainStrategy 去掉,进来是什么传给 dialer 就是什么,不做额外覆写。就这个出站有两个地方写 DomainStrategy 本来就是个令人迷惑烂主意,一不小心就有可能写出前后矛盾的配置,而且 dialer 这边除了 DomainStrategy 还有 HappyEyeballv2。(它不像 WireGuard 要求传给下一个节点的时候必须是 IP 必须做单独的 DomainStrategy)
  2. 初始化的时候偷看 SockOpt 的 DomainStrategy,然后根据情况决定怎么在 FinalRules 查询 IP(用 Go 自己查询还是用内置 DNS 服务器);
  3. 查出来命中禁止 IP CIDR 就导向给 Block/Blackhole 或者就断开,什么都不要传给 dialer;要是查询出问题尽量重试,重试几次不行 就看平常是怎么兜底的 看怎么做更合理。

Direct/Freedom 能写两个地方的 DomainStrategy 这个迷惑设计没能在上次统一 DomainStrategy 的时候处理掉也算是问题的来源

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 7, 2026

@RPRX 想要 DomainStrategy AsIs 服务器端时 v4 优先

是不是单给 freedom 开个选项好点。比如 privacy true 时覆盖 sockopt 使服务端、客户端有不同的行为

@Meo597 Meo597 force-pushed the finalrules branch 2 times, most recently from a2c3f75 to d39965f Compare May 18, 2026 23:37
@Meo597

This comment was marked as outdated.

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 19, 2026

这样 @RPRX 想要的 v4 优先不会和 finalRules 耦合在一起

然后绝大部分 AsIs 的用户本就没要求,现在静默走了 v4
小部分就是想要吃 go happyeyeballs 的用户可以显式关闭 privacyGuard 即可

服务端和客户端都是一样的行为,以前的版本客户端 direct 也不会 v4 优先

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 19, 2026

review 的时候意识到还有个 targetStrategy... 唉

@patterniha
Copy link
Copy Markdown
Collaborator

During the review, I realized there was also a targetStrategy... Sigh.

This is basically for non-freedom outbounds, you can restrict it to non-freedom outbounds.

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented May 19, 2026

This is basically for non-freedom outbounds, you can restrict it to non-freedom outbounds.

proxySettings.tag 会绕过传输层导致 sockopt.domainStrategy 无效,因此不能这样做

现在针对 targetStrategy 也处理好兼容了


此 PR 之前,实际上有 3 套策略来源:freedom.domainStrategy、targetStrategy、sockopt.domainStrategy
当 UDP 里目标是 domain 时尤其容易打架

现在把 freedom 自己那套废掉,只保留两套:targetStrategy 和 sockopt.domainStrategy


在兼容旧 freedom.domainStrategy 时:

有 proxySettings.tag 且不是 transportLayer,则迁到 targetStrategy
否则迁到 sockopt.domainStrategy
sockopt 更好,因为还可以兼容 SRV/TXT、HappyEyeballs 等


UDP domain 现在统一走 ResolveStrategy()

先看 targetStrategy
再看 sockopt.domainStrategy
所以无论用户配的是哪个 strategy,UDP domain 的解析都会和 TCP 一致


RPRX 要的 v4 优先,设计成了 privacyGuard,它也是类似的策略

有 proxySettings.tag,改 targetStrategy
否则改 sockopt.domainStrategy
如果没显式开 privacyGuard,但用户已经在当前那一侧给了非 AsIs,就尊重用户,不再覆盖

@KobeArthurScofield
Copy link
Copy Markdown
Contributor

没有异议的话这个应该可以放到正式版里了

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented Jun 1, 2026

文档也准备好了
除了兼容性更好外,客户端也 v4 优先

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Jun 3, 2026

proxySettings 删了吧,GUI 都没这选项

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Jun 3, 2026

对于 Freedom 来说其实更应该只看 targetStrategy,而不是 sockopt.domainStrategy

@RPRX
Copy link
Copy Markdown
Member

RPRX commented Jun 3, 2026

addressPortStrategy 这东西本来也不是设计给 Freedom 用的,只有 HappyEyeballs 是

@Meo597
Copy link
Copy Markdown
Collaborator Author

Meo597 commented Jun 3, 2026

proxySettings 删了吧,GUI 都没这选项

这玩意是挺迷的估计历史遗留产物,文档以前也没说清楚,以前一直不知道“底层传输”到底是啥翻源码才知道
但一搜好多教程还用这个,特别是透明代理 dns 出站包括我也在用,要不转译一下标个弃用?

对于 Freedom 来说其实更应该只看 targetStrategy,而不是 sockopt.domainStrategy

要兼容老哥的眼球就只能看 sockopt.domainStrategy 了

addressPortStrategy 这东西本来也不是设计给 Freedom 用的,只有 HappyEyeballs 是

也不是故意写的,纯粹是代码写成这样自然兼容了它,需要显式屏蔽吗?

Maolaohei added a commit to Maolaohei/Bray-Core that referenced this pull request Jun 4, 2026
…(freedom compatibility)

XTLS#6261 — Handle ECH H2C query correctly (Fangliding)
- dnsQuery: h2c scheme → https,修复 ECH 配置查询

XTLS#6254 — brutal finalmask (LjhAUMEM)
- 新增 force-brutal finalmask 类型,配合 tcp-brutal 内核模块
- 7 文件新增,全新增模块

XTLS#6058 — Direct/Freedom Better Compatibility (Meo597)
- strategy 类型从 [][]byte → [11][3]byte 更安全
- freedom 出站新增 DomainStrategy / targetStrategy 支持
- 兼容旧的 freedom.domainStrategy 配置
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.

5 participants