Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

修复sockopt对UDP无效的问题 #3002

Merged
merged 1 commit into from
Feb 6, 2024
Merged

修复sockopt对UDP无效的问题 #3002

merged 1 commit into from
Feb 6, 2024

Conversation

Fangliding
Copy link
Member

@Fangliding Fangliding commented Feb 6, 2024

发去warp再也不用打mark了 为了整洁的路由表而战!

@yuhan6665
Copy link
Member

感谢!大佬你觉得有可能跟底下tcp的逻辑写成一样的吗?虽然我也搞不懂这个control

@Fangliding
Copy link
Member Author

@yuhan6665 我也想 下面那个是go自己的dialer tcp走的是这个 sockopt也是在这个时候把配置应用到连接 但是udp不知道为什么这里搓了一个土制的 就跳过了这一部分
我翻了一下这段代码的历史还得追溯到xray出现之前 可以改成和下面一样也走dialer.DialContext 我自己初步测试可以通 但是test会报错 不知道这上面还叠了什么乱七八糟的 我也不敢乱搞 只能在这个土制上的再堆了

@yuhan6665 yuhan6665 merged commit 303beff into XTLS:main Feb 6, 2024
34 checks passed
@yuhan6665
Copy link
Member

可以的 目前先小堆一点 以后有机会搞懂了再推

@dyhkwong
Copy link
Contributor

On Windows, the File method of UDPConn is not implemented, so this change will break things. Please take a look.

@Fangliding
Copy link
Member Author

On Windows, the File method of UDPConn is not implemented, so this change will break things. Please take a look.

Sure? What error did you encounter.

@Fangliding
Copy link
Member Author

rns syscall.EWINDOWS.
https://github.com/golang/g

You are right. I found a way to fix this , but the xray code is a little.... odd, I'm worried about disrupting other functions. This bug will only affect specifying interfaces on Windows, and I don't think much people be using this option on Windows, I think it's best to do so. Maybe report this to golang?

@yuhan6665
Copy link
Member

实在不行先给 windows 关掉这个新功能
可以加个选项也行 默认开启 遇到问题的人可以关

@Fangliding
Copy link
Member Author

@yuhan6665 这不是新功能是修bug()

Windows上这个小问题并不会导致连不上炸掉 只是还是会像之前那样漏udp而已 实际上在sockopt里对Windows上的udp生效的也就interface这个选项 应该没人闲到在Windows上指interface 我觉得影响不大 而且在Windows上失效的选项可不止这一个()

@yuhan6665
Copy link
Member

哦 哦 那先这样也行

@dyhkwong
Copy link
Contributor

dyhkwong commented Feb 11, 2024

Windows上这个小问题并不会导致连不上炸掉 只是还是会像之前那样漏udp而已 实际上在sockopt里对Windows上的udp生效的也就interface这个选项

只要 outbound sockopt 不为空(包括设置了其他不是给 udp 用的选项),该 outbound udp 就会“连不上炸掉“

@yuhan6665
Copy link
Member

在 windows 上暂时先关掉了 bf02392

@yichya
Copy link
Contributor

yichya commented Feb 21, 2024

This seems to cause some goroutines to stuck forever:

goroutine 287 [syscall, 8 minutes]:
syscall.Syscall6(0x0?, 0x0?, 0xc0004ce9f0?, 0x4183e8?, 0x0?, 0x0?, 0x0?)
	syscall/syscall_linux.go:91 +0x30
syscall.recvfrom(0xc0004cea80?, {0xc0024ba000?, 0xc001b0d900?, 0x0?}, 0x4a3?, 0xc0004cea10?, 0x419573?)
	syscall/zsyscall_linux_amd64.go:1541 +0x54
syscall.recvfromInet6(0xc000ac1f00?, {0xc0024ba000?, 0xc0004cea00?, 0x419968?}, 0x43474a?, 0xc0004ceb98)
	syscall/syscall_unix.go:345 +0x6d
internal/poll.(*FD).ReadFromInet6(0xc000ac1f00, {0xc0024ba000, 0x2000, 0x2000}, 0x410725?)
	internal/poll/fd_unix.go:267 +0x18c
net.(*netFD).readFromInet6(0xc000ac1f00, {0xc0024ba000?, 0x7faa12529fe8?, 0xc0004cebb8?}, 0xc0004ceb70?)
	net/fd_posix.go:72 +0x25
net.(*UDPConn).readFrom(0x30?, {0xc0024ba000?, 0xc00163ede0?, 0x0?}, 0xc00163ede0)
	net/udpsock_posix.go:59 +0x79
net.(*UDPConn).readFromUDP(0xc0000616e0, {0xc0024ba000?, 0x410725?, 0x8?}, 0x2000?)
	net/udpsock.go:149 +0x30
net.(*UDPConn).ReadFrom(0xc000203558?, {0xc0024ba000, 0x2000, 0x2000})
	net/udpsock.go:158 +0x4a
github.com/xtls/xray-core/transport/internet.(*PacketConnWrapper).ReadFrom(...)
	github.com/xtls/xray-core/transport/internet/system_dialer.go:160
github.com/xtls/xray-core/proxy/freedom.(*PacketReader).ReadMultiBuffer(0xc0005081f8)
	github.com/xtls/xray-core/proxy/freedom/freedom.go:272 +0x88
github.com/xtls/xray-core/common/buf.copyInternal({0x14fd960, 0xc0005081f8}, {0x14fc8a0, 0xc0000616c0}, 0xc000508210)
	github.com/xtls/xray-core/common/buf/copy.go:93 +0x5b
github.com/xtls/xray-core/common/buf.Copy({0x14fd960, 0xc0005081f8}, {0x14fc8a0, 0xc0000616c0}, {0xc0001eded8, 0x1, 0x0?})
	github.com/xtls/xray-core/common/buf/copy.go:116 +0x98
github.com/xtls/xray-core/proxy/freedom.(*Handler).Process.func4()
	github.com/xtls/xray-core/proxy/freedom/freedom.go:228 +0x447
github.com/xtls/xray-core/proxy/freedom.(*Handler).Process.OnSuccess.func7()
	github.com/xtls/xray-core/common/task/task.go:12 +0x22
github.com/xtls/xray-core/common/task.Run.func1(0xc001855970?)
	github.com/xtls/xray-core/common/task/task.go:28 +0x28
created by github.com/xtls/xray-core/common/task.Run in goroutine 284
	github.com/xtls/xray-core/common/task/task.go:27 +0xdb

I'm still figuring it out but please consider making it possible to disable this feature via a switch.

@yuhan6665
Copy link
Member

看来这个改动较大。。加个 env var,先默认关掉?

@yichya
Copy link
Contributor

yichya commented Feb 21, 2024

看来这个改动较大。。加个 env var,先默认关掉?

我觉得是可以的,把前面那个 OS 的判断直接换成一个环境变量来控制就好

@chise0713
Copy link
Contributor

感觉专门给 linux 生成个 iproute2 规则进行 "绑定" 也好

@Fangliding
Copy link
Member Author

This seems to cause some goroutines to stuck forever:

goroutine 287 [syscall, 8 minutes]:
syscall.Syscall6(0x0?, 0x0?, 0xc0004ce9f0?, 0x4183e8?, 0x0?, 0x0?, 0x0?)
	syscall/syscall_linux.go:91 +0x30
syscall.recvfrom(0xc0004cea80?, {0xc0024ba000?, 0xc001b0d900?, 0x0?}, 0x4a3?, 0xc0004cea10?, 0x419573?)
	syscall/zsyscall_linux_amd64.go:1541 +0x54
syscall.recvfromInet6(0xc000ac1f00?, {0xc0024ba000?, 0xc0004cea00?, 0x419968?}, 0x43474a?, 0xc0004ceb98)
	syscall/syscall_unix.go:345 +0x6d
internal/poll.(*FD).ReadFromInet6(0xc000ac1f00, {0xc0024ba000, 0x2000, 0x2000}, 0x410725?)
	internal/poll/fd_unix.go:267 +0x18c
net.(*netFD).readFromInet6(0xc000ac1f00, {0xc0024ba000?, 0x7faa12529fe8?, 0xc0004cebb8?}, 0xc0004ceb70?)
	net/fd_posix.go:72 +0x25
net.(*UDPConn).readFrom(0x30?, {0xc0024ba000?, 0xc00163ede0?, 0x0?}, 0xc00163ede0)
	net/udpsock_posix.go:59 +0x79
net.(*UDPConn).readFromUDP(0xc0000616e0, {0xc0024ba000?, 0x410725?, 0x8?}, 0x2000?)
	net/udpsock.go:149 +0x30
net.(*UDPConn).ReadFrom(0xc000203558?, {0xc0024ba000, 0x2000, 0x2000})
	net/udpsock.go:158 +0x4a
github.com/xtls/xray-core/transport/internet.(*PacketConnWrapper).ReadFrom(...)
	github.com/xtls/xray-core/transport/internet/system_dialer.go:160
github.com/xtls/xray-core/proxy/freedom.(*PacketReader).ReadMultiBuffer(0xc0005081f8)
	github.com/xtls/xray-core/proxy/freedom/freedom.go:272 +0x88
github.com/xtls/xray-core/common/buf.copyInternal({0x14fd960, 0xc0005081f8}, {0x14fc8a0, 0xc0000616c0}, 0xc000508210)
	github.com/xtls/xray-core/common/buf/copy.go:93 +0x5b
github.com/xtls/xray-core/common/buf.Copy({0x14fd960, 0xc0005081f8}, {0x14fc8a0, 0xc0000616c0}, {0xc0001eded8, 0x1, 0x0?})
	github.com/xtls/xray-core/common/buf/copy.go:116 +0x98
github.com/xtls/xray-core/proxy/freedom.(*Handler).Process.func4()
	github.com/xtls/xray-core/proxy/freedom/freedom.go:228 +0x447
github.com/xtls/xray-core/proxy/freedom.(*Handler).Process.OnSuccess.func7()
	github.com/xtls/xray-core/common/task/task.go:12 +0x22
github.com/xtls/xray-core/common/task.Run.func1(0xc001855970?)
	github.com/xtls/xray-core/common/task/task.go:28 +0x28
created by github.com/xtls/xray-core/common/task.Run in goroutine 284
	github.com/xtls/xray-core/common/task/task.go:27 +0xdb

I'm still figuring it out but please consider making it possible to disable this feature via a switch.

What's your OS and config?

@yichya
Copy link
Contributor

yichya commented Feb 21, 2024

What's your OS and config?

openwrt/openwrt@4883e4c04f + yichya/luci-app-xray@b5e4393

The configuration generated is massive. I'll try to post a minimal configuration for this later.

@yichya
Copy link
Contributor

yichya commented Feb 22, 2024

I'll try to post a minimal configuration for this later.

This seems enough:

{
  "inbounds": [
    {
      "listen": "127.0.0.53",
      "port": 5300,
      "protocol": "dokodemo-door",
      "settings": {
        "address": "1.1.1.1",
        "port": 53,
        "network": "tcp,udp"
      }
    }
  ],
  "outbounds": [
    {
      "protocol": "freedom",
      "tag": "direct",
      "settings": {
        "domainStrategy": "UseIPv4",
        "redirect": ""
      },
      "streamSettings": {
        "sockopt": {
          "mark": 252
        }
      }
    }
  ]
}

Run dig -p 5300 @127.0.0.53 www.bing.com several times, then catch a goroutine dump and find Syscall6:

image

@yichya
Copy link
Contributor

yichya commented Feb 22, 2024

It is not even necessary to have anything in sockopt to reproduce:

image

@dyhkwong
Copy link
Contributor

dyhkwong commented Feb 22, 2024

May be related to golang/go#29277. Try replacing File() with SyscallConn() and then rawConn.Control(func(fd uintptr)). And SyscallConn() should work on Windows too.

@yichya
Copy link
Contributor

yichya commented Feb 22, 2024

Try replacing File() with SyscallConn() and then rawConn.Control(func(fd uintptr)).

Tried this and seems solved the issue. @yuhan6665 @Fangliding please confirm as well

@yuhan6665
Copy link
Member

I just push a quick patch 3778a36 so all can test it..

@yichya
Copy link
Contributor

yichya commented Feb 23, 2024

Tried 3778a36 and it is working well.

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