Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions adapter/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type NetworkManager interface {
DefaultOptions() NetworkOptions
RegisterAutoRedirectOutputMark(mark uint32) error
AutoRedirectOutputMark() uint32
AutoRedirectMarkMask() uint32
AutoRedirectOutputMarkFunc() control.Func
NetworkMonitor() tun.NetworkUpdateMonitor
InterfaceMonitor() tun.DefaultInterfaceMonitor
Expand Down
17 changes: 12 additions & 5 deletions common/dialer/default.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,19 @@ func setMarkWrapper(networkManager adapter.NetworkManager, mark uint32, isDefaul
return control.RoutingMark(mark)
}
return func(network, address string, conn syscall.RawConn) error {
if networkManager.AutoRedirectOutputMark() != 0 {
if isDefault {
return E.New("`route.default_mark` is conflict with `tun.auto_redirect`")
} else {
return E.New("`routing_mark` is conflict with `tun.auto_redirect`")
autoMark := networkManager.AutoRedirectOutputMark()
if autoMark != 0 {
maskReserved := networkManager.AutoRedirectMarkMask()
if mark&maskReserved != 0 {
if isDefault {
return E.New("`route.default_mark` uses bits reserved for `tun.auto_redirect` (low 16 bits)")
}
return E.New("`routing_mark` uses bits reserved for `tun.auto_redirect` (low 16 bits)")
}
return control.Raw(conn, func(fd uintptr) error {
current, _ := syscall.GetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK)
return syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, current|int(mark))
})
}
return control.RoutingMark(mark)(network, address, conn)
}
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,5 @@ require (
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
)

replace github.com/sagernet/sing-tun => github.com/loncharles/sing-tun v0.0.0-20260513193456-240481b009fd
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U=
github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8=
github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4=
github.com/loncharles/sing-tun v0.0.0-20260513193456-240481b009fd h1:Fx6u/em9g9k9gPgz/5iRSt+Kt+XQV7lIqIjorRhWu2U=
github.com/loncharles/sing-tun v0.0.0-20260513193456-240481b009fd/go.mod h1:QvarqUtHfj1ULaRR+6kZOS/OoCE+pYGq67A5tyIy+dQ=
github.com/mdlayher/netlink v1.9.0 h1:G8+GLq2x3v4D4MVIqDdNUhTUC7TKiCy/6MDkmItfKco=
github.com/mdlayher/netlink v1.9.0/go.mod h1:YBnl5BXsCoRuwBjKKlZ+aYmEoq0r12FDA/3JC+94KDg=
github.com/mdlayher/socket v0.5.1 h1:VZaqt6RkGkt2OE9l3GcC6nZkqD3xKeQLyfleW/uBcos=
Expand Down Expand Up @@ -248,8 +250,6 @@ github.com/sagernet/sing-shadowsocks2 v0.2.1 h1:dWV9OXCeFPuYGHb6IRqlSptVnSzOelnq
github.com/sagernet/sing-shadowsocks2 v0.2.1/go.mod h1:RnXS0lExcDAovvDeniJ4IKa2IuChrdipolPYWBv9hWQ=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11 h1:tK+75l64tm9WvEFrYRE1t0YxoFdWQqw/h7Uhzj0vJ+w=
github.com/sagernet/sing-shadowtls v0.2.1-0.20250503051639-fcd445d33c11/go.mod h1:sWqKnGlMipCHaGsw1sTTlimyUpgzP4WP3pjhCsYt9oA=
github.com/sagernet/sing-tun v0.8.9 h1:ixFKKUGdVcJl4wb0xbL36hobiw9l6DIH497EQf5ILpM=
github.com/sagernet/sing-tun v0.8.9/go.mod h1:QvarqUtHfj1ULaRR+6kZOS/OoCE+pYGq67A5tyIy+dQ=
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1 h1:aSwUNYUkVyVvdmBSufR8/nRFonwJeKSIROxHcm5br9o=
github.com/sagernet/sing-vmess v0.2.8-0.20250909125414-3aed155119a1/go.mod h1:P11scgTxMxVVQ8dlM27yNm3Cro40mD0+gHbnqrNGDuY=
github.com/sagernet/smux v1.5.50-sing-box-mod.1 h1:XkJcivBC9V4wBjiGXIXZ229aZCU1hzcbp6kSkkyQ478=
Expand Down
11 changes: 10 additions & 1 deletion route/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type NetworkManager struct {
autoDetectInterface bool
defaultOptions adapter.NetworkOptions
autoRedirectOutputMark uint32
autoRedirectMarkMask uint32
networkMonitor tun.NetworkUpdateMonitor
interfaceMonitor tun.DefaultInterfaceMonitor
packageManager tun.PackageManager
Expand Down Expand Up @@ -385,19 +386,27 @@ func (r *NetworkManager) RegisterAutoRedirectOutputMark(mark uint32) error {
return E.New("only one auto-redirect can be configured")
}
r.autoRedirectOutputMark = mark
r.autoRedirectMarkMask = tun.AutoRedirectMarkMask
return nil
}

func (r *NetworkManager) AutoRedirectOutputMark() uint32 {
return r.autoRedirectOutputMark
}

func (r *NetworkManager) AutoRedirectMarkMask() uint32 {
return r.autoRedirectMarkMask
}

func (r *NetworkManager) AutoRedirectOutputMarkFunc() control.Func {
return func(network, address string, conn syscall.RawConn) error {
if r.autoRedirectOutputMark == 0 {
return nil
}
return control.RoutingMark(r.autoRedirectOutputMark)(network, address, conn)
return control.Raw(conn, func(fd uintptr) error {
current, _ := syscall.GetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK)
return syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, current|int(r.autoRedirectOutputMark))
})
}
}

Expand Down