Skip to content

Conversation

92613hjh
Copy link
Contributor

fix #4007

@Fangliding
Copy link
Member

测试过了吗?

@92613hjh
Copy link
Contributor Author

yep

@Fangliding
Copy link
Member

Fangliding commented Mar 22, 2025

if dest.Network == net.Network_UDP && !hasBindAddr(sockopt) && sockopt.Interface == ""
为什么要在这加上 sockopt.Interface 为空才往下处理? 这不是会让 sockopt.Interface 都不会对udp连接生效?

@92613hjh
Copy link
Contributor Author

92613hjh commented Mar 22, 2025

这个土制的 PacketConnWrapper会导致 IP_BOUND_IF 设置失败
逻辑同 BindAddress一致, 没设置就走PacketConnWrapper,设置就走下面
https://github.com/XTLS/Xray-core/pull/4530/files#diff-fffd9eea78d4a3cf715aa4d82845bf5e54711bd5f314aadccb4049014e198149R112-R123

@Fangliding
Copy link
Member

我记得之前试过 这个PacketConnWrapper有用的 随便绕会导致核心里有的东西炸掉 就是ListenSystemPacket传进来的conn然后对fd进行操作 wrapper一下怎么会炸呢 有问题也是ListenSystemPacket传进来的packetconn的问题吧

@92613hjh
Copy link
Contributor Author

92613hjh commented Mar 22, 2025

有问题也是ListenSystemPacket传进来的packetconn的问题吧

对,应该是 https://github.com/XTLS/Xray-core/pull/4530/files#diff-fffd9eea78d4a3cf715aa4d82845bf5e54711bd5f314aadccb4049014e198149R55-R61 的问题

@RPRX RPRX requested a review from Fangliding March 23, 2025 11:29
@RPRX
Copy link
Member

RPRX commented Mar 24, 2025

这个 PR 有进展吗

@Fangliding
Copy link
Member

Fangliding commented Mar 24, 2025

有问题也是ListenSystemPacket传进来的packetconn的问题吧

对,应该是 https://github.com/XTLS/Xray-core/pull/4530/files#diff-fffd9eea78d4a3cf715aa4d82845bf5e54711bd5f314aadccb4049014e198149R55-R61 的问题

删掉bind部分试试?

@hossinasaadi
Copy link
Contributor

hossinasaadi commented Mar 26, 2025

func getInterfaceIndexByName(name string) int {
ifaces, err := network.Interfaces()

While I was working on macOS/iOS sockopt, remember that I used this function to get interface index by reason, but don't really remember the reason. BTW
Maybe changing that leads to other issues.

#2582

@92613hjh
Copy link
Contributor Author

我先修复一下Test的问题

删掉bind部分试试?

会炸

@92613hjh
Copy link
Contributor Author

92613hjh commented Mar 28, 2025

#2582

Thanks for your work, do you have any suggestions for this PR.

@RPRX
Copy link
Member

RPRX commented Mar 29, 2025

#4568 (comment)

@92613hjh
Copy link
Contributor Author

IP_BOUND_IF 对组播生效,已测试

@RPRX
Copy link
Member

RPRX commented Mar 30, 2025

看了下代码,这个 PacketConnWrapper 是 *ray 为了把 net.PacketConn 包装成 net.Conn,绕过的话一些断言相关的代码会炸

至于要绕过 ListenSystemPacket 才能 bind 成功,大概是因为 bind 哪个 interface 必须在它 listen 时指定,而 ListenSystemPacket() -> effectiveListener.ListenPacket() -> getControlFunc() 内调用的只有 applyInboundSocketOptions,而没有 outbound

但是说实话吧我觉得既然是 dial 就别调用 ListenSystemPacket 了,这东西是 inbound 用的,正确做法是把上面关于 UDP 的整块代码删掉,而最后 return 的那个系统 dialer.DialContext 返回的 net.Conn 其实是 net.UDPConn,不需要 PacketConnWrapper

所以为啥 Xray 一开始 fork 来的代码,dial UDP 就是 ListenSystemPacket+PacketConnWrapper?好奇怪。。。

RPRX added a commit that referenced this pull request Mar 30, 2025
@RPRX
Copy link
Member

RPRX commented Mar 30, 2025

基于 8b89abc rebase 一下,你们试一下 FullCone 没问题的话就行,底层 dialer 这块代码以后还得继续简化

@92613hjh
Copy link
Contributor Author

Done

@92613hjh 92613hjh force-pushed the main branch 2 times, most recently from a3f3fba to a048d01 Compare March 31, 2025 00:33
@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

8b89abc 的 test 炸了很多,感觉是还有哪个地方要改,@Fangliding 你看看?

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

我看到了,use of WriteTo with pre-connected connection,不知道是 Golang 的限制还是操作系统的限制

绕不过的话还是得先 Listen,但是不能用 ListenSystemPacket(),而要用带 applyOutboundSocketOptions() 的代码

@Fangliding
Copy link
Member

dial出去的连接和远端地址绑定的 write to 会炸
糊出来的syscallconn操作fd道理上不应该有问题 我不觉得塞进 lc.Control 可以解决问题 要不就是mac的什么乱七八糟的行为
说白了还是mac没人用 手头没机器测也测不了

@Fangliding
Copy link
Member

还是回滚回去吧 这样改肯定是不行的

@Meo597
Copy link
Contributor

Meo597 commented Mar 31, 2025

没办法提供真机给你远程
怕被开盒
我敢给你也不敢用

亚马逊有个EC2 Mac,白嫖个学生优惠去试试?

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

Anyway,现有代码 dial UDP 时调用的却是入站的 ListenSystemPacket(),导致涉及到 controllers、applyInboundSocketOptions()、setReusePort(fd) 等入站专属的东西,过于劣质了,我先把这个改掉,试试 applyOutboundSocketOptions() 放 lc.Control 里

@Fangliding
Copy link
Member

这样会把Android客户端搞坏 还是得listensystempacket出去 用点其他东西标记来自inbound还是outbound然后在getControlFunc识别比较好

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

基于 8284a0e rebase 一下,试试能不能 bind interface @92613hjh

我看了ListenSystemPacket() 调用到的 applyInboundSocketOptions() 和 setReusePort(),前者在 Win 和 macOS 上都只针对 TCP,实际无影响,但后者在 Win 上没有代码、在 macOS 上有,所以可能是它的锅,而不是是否放在 lc.Control 的问题?你可以测试下

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

这样会把Android客户端搞坏

安卓客户端加了什么料吗

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

这 ListenSystemPacket() 是个函数,effectiveListener 是未导出的变量,第三方调用者都改不了,只有 controllers 能加料进去吧

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

Linux 上出入站 sockopt UDP 相关代码的差距也就入站多了 ReceiveOriginalDestAddress 和 V6Only,出站多了 Interface

如果仍想要这两项,应当把它们加到出站的代码,而不是出站 dial UDP 去调用入站 ListenSystemPacket() 的劣质行为

@Fangliding
Copy link
Member

这 ListenSystemPacket() 是个函数,effectiveListener 是未导出的变量,第三方调用者都改不了,只有 controllers 能加料进去吧

有一个 UseAlternativeSystemDialer 啊

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

有一个 UseAlternativeSystemDialer 啊

这是 effectiveSystemDialer,不是 effectiveListener,后者我看了代码里没地方改它,只有往 controllers 加料的可能

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

@92613hjh 你试下能用了吗

@92613hjh
Copy link
Contributor Author

8284a0e 经过测试,darwin可以绑定

@RPRX RPRX changed the title Make sockopt.interface work with UDP on Darwin Sockopt: Fix Darwin (macOS, iOS...) UDP interface bind Mar 31, 2025
@RPRX RPRX merged commit 63eb053 into XTLS:main Mar 31, 2025
35 checks passed
@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

感谢 PR 与测试!我盲猜最开始是 applyOutboundSocketOptions() 前面有 setReusePort(fd) 的锅,你测试一下

@92613hjh
Copy link
Contributor Author

setReusePort(fd) 的锅,你测试一下

在原版去掉getControlFunc()中的setReusePort(fd)还是无法bind

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

setReusePort(fd) 的锅,你测试一下

在原版去掉getControlFunc()中的setReusePort(fd)还是无法bind

那大概只能放 lc.Control

话说我看只有 Darwin 上的 inbound 有绑 interface,这东西绑 listen 上的效果是只接收来自某个网卡的请求吗

@92613hjh
Copy link
Contributor Author

好像是祖传代码,不过似乎并不能在入站起过滤效果

@RPRX
Copy link
Member

RPRX commented Mar 31, 2025

好像是祖传代码,不过似乎并不能在入站起过滤效果

暂时留着吧,你可以在 Linux 和 Windows 上试试

@xqzr
Copy link
Contributor

xqzr commented Apr 3, 2025

Anyway,现有代码 dial UDP 时调用的却是入站的 ListenSystemPacket(),导致涉及到 controllers、applyInboundSocketOptions()、setReusePort(fd) 等入站专属的东西,过于劣质了,我先把这个改掉,试试 applyOutboundSocketOptions() 放 lc.Control 里

打破 #4504

maoxikun pushed a commit to maoxikun/Xray-core that referenced this pull request Aug 23, 2025
maoxikun pushed a commit to maoxikun/Xray-core that referenced this pull request Aug 23, 2025
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.

[BUG] sockopt.interface 在Darwin平台未对UDP生效
6 participants