From bff5acf292d8ce6109321065586c7e8551e89ca3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 29 Sep 2026 23:28:17 +0800 Subject: [PATCH] Handle connected UDP EOF on BSD --- common/dialer/default.go | 9 +++++++ common/dialer/udp_conn.go | 53 +++++++++++++++++++++++++++++++++++++++ go.mod | 6 ++--- go.sum | 12 ++++----- 4 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 common/dialer/udp_conn.go diff --git a/common/dialer/default.go b/common/dialer/default.go index 25b264ff..f202283c 100644 --- a/common/dialer/default.go +++ b/common/dialer/default.go @@ -423,6 +423,15 @@ func (d *DefaultDialer) trackConn(ctx context.Context, destination M.Socksaddr, if err != nil { return conn, err } + if nativeConn, isUDPConn := conn.(*net.UDPConn); isUDPConn { + var rawConn syscall.RawConn + rawConn, err = nativeConn.SyscallConn() + if err != nil { + conn.Close() + return nil, err + } + conn = &udpConn{Conn: conn, rawConn: rawConn} + } if d.connectionManager != nil { conn = d.connectionManager.TrackConn(conn) } diff --git a/common/dialer/udp_conn.go b/common/dialer/udp_conn.go new file mode 100644 index 00000000..e3dc5e41 --- /dev/null +++ b/common/dialer/udp_conn.go @@ -0,0 +1,53 @@ +package dialer + +import ( + "io" + "net" + "syscall" + + "github.com/sagernet/sing/common" + "github.com/sagernet/sing/common/control" + N "github.com/sagernet/sing/common/network" +) + +type udpConn struct { + net.Conn + rawConn syscall.RawConn +} + +func (c *udpConn) Read(b []byte) (n int, err error) { + n, err = c.Conn.Read(b) + if n == 0 && err == nil { + var isEOF bool + c.rawConn.Control(func(fd uintptr) { + isEOF = control.IsUDPEOF(fd) + }) + if isEOF { + err = io.EOF + } + } + return +} + +func (c *udpConn) SyscallConn() (syscall.RawConn, error) { + return c.rawConn, nil +} + +func (c *udpConn) Upstream() any { + return c.Conn +} + +func (c *udpConn) ReaderReplaceable() bool { + return true +} + +func (c *udpConn) WriterReplaceable() bool { + return true +} + +var ( + _ syscall.Conn = (*udpConn)(nil) + _ common.WithUpstream = (*udpConn)(nil) + _ N.ReaderWithUpstream = (*udpConn)(nil) + _ N.WriterWithUpstream = (*udpConn)(nil) +) diff --git a/go.mod b/go.mod index 56567a99..35df2eae 100644 --- a/go.mod +++ b/go.mod @@ -44,8 +44,8 @@ require ( github.com/sagernet/gvisor v0.0.0-20260727.0-sing-box-mod.1 github.com/sagernet/netlink v0.0.0-20260814022025-64455d367bbf github.com/sagernet/nftables v0.3.0-mod.4 - github.com/sagernet/quic-go v0.61.0-sing-box-mod.7 - github.com/sagernet/sing v0.9.7-0.20260929145605-8d939df03478 + github.com/sagernet/quic-go v0.61.0-sing-box-mod.9 + github.com/sagernet/sing v0.9.7-0.20260929150544-0ad23b637bd4 github.com/sagernet/sing-cloudflared v0.1.4-0.20260929150702-b3a1e8f3018c github.com/sagernet/sing-mux v0.3.10-0.20260929204512-caf09fe32475 github.com/sagernet/sing-openconnect v0.1.1-0.20260929151225-cbd68c45de58 @@ -60,7 +60,7 @@ require ( github.com/sagernet/sing-vmess v0.2.9-0.20260929152519-9b95ab8c9478 github.com/sagernet/smux v1.5.50-sing-box-mod.1 github.com/sagernet/tailscale v1.102.1-sing-box-1.14-mod.5 - github.com/sagernet/wireguard-go v0.0.7 + github.com/sagernet/wireguard-go v0.0.8-0.20260929150556-6731c7387c81 github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 github.com/spf13/cobra v1.10.2 github.com/stretchr/testify v1.12.0 diff --git a/go.sum b/go.sum index 7988d55b..481f6c6a 100644 --- a/go.sum +++ b/go.sum @@ -316,10 +316,10 @@ github.com/sagernet/netlink v0.0.0-20260814022025-64455d367bbf h1:b/3rm+KvxzuYRc github.com/sagernet/netlink v0.0.0-20260814022025-64455d367bbf/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM= github.com/sagernet/nftables v0.3.0-mod.4 h1:vnOtcDYeSXv2e5RoRuGH0lrpttQFJ8iC4ICS2nhlDSo= github.com/sagernet/nftables v0.3.0-mod.4/go.mod h1:8kslHG4VvYNihcco+i6uxIX7qbT8A56T0y5q7U44ZaQ= -github.com/sagernet/quic-go v0.61.0-sing-box-mod.7 h1:sW2O+DoNF+my1PGlSZ3zG2N+fdxLR3DC0l4sXCM0lBE= -github.com/sagernet/quic-go v0.61.0-sing-box-mod.7/go.mod h1:hmLC8GJPp+BrpBgrgJnacvI4fZGIhasuy1ROJJ8GR4E= -github.com/sagernet/sing v0.9.7-0.20260929145605-8d939df03478 h1:c3Jpk13MOAc516zCuqAGBr7ok9UcpGjCjgWWOQslL0w= -github.com/sagernet/sing v0.9.7-0.20260929145605-8d939df03478/go.mod h1:K3Owt3xPhHugvlnlPPxZJ/exXdaJfEPOTNorGk4AXjo= +github.com/sagernet/quic-go v0.61.0-sing-box-mod.9 h1:Lojx77uC63TxZO38Z1OSo6aOoBSXY+ueH0/IKKeTZuI= +github.com/sagernet/quic-go v0.61.0-sing-box-mod.9/go.mod h1:hmLC8GJPp+BrpBgrgJnacvI4fZGIhasuy1ROJJ8GR4E= +github.com/sagernet/sing v0.9.7-0.20260929150544-0ad23b637bd4 h1:d4WT3KO4zhp9qzPHUZCKqCP+ZmP1GXBsAmReqlnE4zA= +github.com/sagernet/sing v0.9.7-0.20260929150544-0ad23b637bd4/go.mod h1:K3Owt3xPhHugvlnlPPxZJ/exXdaJfEPOTNorGk4AXjo= github.com/sagernet/sing-cloudflared v0.1.4-0.20260929150702-b3a1e8f3018c h1:36zXD/qnDk7sh/J4zSEJsnHf4W3TYNCbmjo9MNIlrE4= github.com/sagernet/sing-cloudflared v0.1.4-0.20260929150702-b3a1e8f3018c/go.mod h1:XEqEDYRCAYLaoPjZ1ifVWJg5iWAJHL2gOAXe/PM28Cg= github.com/sagernet/sing-mux v0.3.10-0.20260929204512-caf09fe32475 h1:aG0DqHEOjax7DyfE1GTAXZotOg3QGVCz3/8rCSua2kg= @@ -348,8 +348,8 @@ github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1h github.com/sagernet/smux v1.5.50-sing-box-mod.1/go.mod h1:NjhsCEWedJm7eFLyhuBgIEzwfhRmytrUoiLluxs5Sk8= github.com/sagernet/tailscale v1.102.1-sing-box-1.14-mod.5 h1:mGLWVgj2Pl2NlgE1+sEUIDIMB42JdWEPwYmxTnVWg44= github.com/sagernet/tailscale v1.102.1-sing-box-1.14-mod.5/go.mod h1:WLUSOPmTcf7VN9gLCe01qUSIvD+/cKC177neENyZPkI= -github.com/sagernet/wireguard-go v0.0.7 h1:FmP7QY5OcFlhKtDVB81Xd+uoBv4BjW5GORBTUYwpuu0= -github.com/sagernet/wireguard-go v0.0.7/go.mod h1:er10sELpmzLXq7S7Pbc1Zsbyapcr+/gxNAHKTo6fzVA= +github.com/sagernet/wireguard-go v0.0.8-0.20260929150556-6731c7387c81 h1:VsrjoaljEz7jQ1LWbrNyf/scQSQIkVVp7v4nSDrPJ+I= +github.com/sagernet/wireguard-go v0.0.8-0.20260929150556-6731c7387c81/go.mod h1:er10sELpmzLXq7S7Pbc1Zsbyapcr+/gxNAHKTo6fzVA= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854 h1:6uUiZcDRnZSAegryaUGwPC/Fj13JSHwiTftrXhMmYOc= github.com/sagernet/ws v0.0.0-20231204124109-acfe8907c854/go.mod h1:LtfoSK3+NG57tvnVEHgcuBW9ujgE8enPSgzgwStwCAA= github.com/smallstep/pkcs7 v0.1.1 h1:x+rPdt2W088V9Vkjho4KtoggyktZJlMduZAtRHm68LU=