Sockopt: Fix Darwin (macOS, iOS...) UDP interface bind#4530
Conversation
|
测试过了吗? |
|
yep |
|
|
|
|
|
我记得之前试过 这个PacketConnWrapper有用的 随便绕会导致核心里有的东西炸掉 就是ListenSystemPacket传进来的conn然后对fd进行操作 wrapper一下怎么会炸呢 有问题也是ListenSystemPacket传进来的packetconn的问题吧 |
|
|
|
删掉bind部分试试? |
|
Xray-core/transport/internet/sockopt_darwin.go Lines 227 to 228 in 29e37e8 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 |
|
我先修复一下Test的问题
会炸 |
|
Thanks for your work, do you have any suggestions for this PR. |
|
|
|
看了下代码,这个 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?好奇怪。。。 |
…etConnWrapper struct #4530 (comment)
|
基于 8b89abc rebase 一下,你们试一下 FullCone 没问题的话就行,底层 dialer 这块代码以后还得继续简化 |
|
Done |
a3f3fba to
a048d01
Compare
|
8b89abc 的 test 炸了很多,感觉是还有哪个地方要改,@Fangliding 你看看? |
|
我看到了,use of WriteTo with pre-connected connection,不知道是 Golang 的限制还是操作系统的限制 绕不过的话还是得先 Listen,但是不能用 ListenSystemPacket(),而要用带 applyOutboundSocketOptions() 的代码 |
|
dial出去的连接和远端地址绑定的 write to 会炸 |
|
还是回滚回去吧 这样改肯定是不行的 |
|
没办法提供真机给你远程 亚马逊有个EC2 Mac,白嫖个学生优惠去试试? |
|
Anyway,现有代码 dial UDP 时调用的却是入站的 ListenSystemPacket(),导致涉及到 controllers、applyInboundSocketOptions()、setReusePort(fd) 等入站专属的东西,过于劣质了,我先把这个改掉,试试 applyOutboundSocketOptions() 放 lc.Control 里 |
|
这样会把Android客户端搞坏 还是得listensystempacket出去 用点其他东西标记来自inbound还是outbound然后在getControlFunc识别比较好 |
|
|
这 ListenSystemPacket() 是个函数,effectiveListener 是未导出的变量,第三方调用者都改不了,只有 controllers 能加料进去吧 |
|
Linux 上出入站 sockopt UDP 相关代码的差距也就入站多了 ReceiveOriginalDestAddress 和 V6Only,出站多了 Interface 如果仍想要这两项,应当把它们加到出站的代码,而不是出站 dial UDP 去调用入站 ListenSystemPacket() 的劣质行为 |
有一个 UseAlternativeSystemDialer 啊 |
这是 effectiveSystemDialer,不是 effectiveListener,后者我看了代码里没地方改它,只有往 controllers 加料的可能 |
|
@92613hjh 你试下能用了吗 |
|
8284a0e 经过测试,darwin可以绑定 |
interface bind
|
感谢 PR 与测试!我盲猜最开始是 applyOutboundSocketOptions() 前面有 setReusePort(fd) 的锅,你测试一下 |
在原版去掉getControlFunc()中的setReusePort(fd)还是无法bind |
话说我看只有 Darwin 上的 inbound 有绑 interface, |
|
好像是祖传代码,不过似乎并不能在入站起过滤效果 |
|
打破 #4504 |
XTLS#4530 (comment) (cherry picked from commit 8284a0e)
fix #4007