mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-03 20:07:38 +03:00
Improve control
This commit is contained in:
parent
6795d518e1
commit
6910a8c5ce
13 changed files with 60 additions and 68 deletions
|
@ -11,11 +11,11 @@ type BindManager interface {
|
|||
Update() error
|
||||
}
|
||||
|
||||
type simpleBindManager struct {
|
||||
type myBindManager struct {
|
||||
interfaceIndexByName map[string]int
|
||||
}
|
||||
|
||||
func (m *simpleBindManager) IndexByName(name string) (int, error) {
|
||||
func (m *myBindManager) IndexByName(name string) (int, error) {
|
||||
if index, loaded := m.interfaceIndexByName[name]; loaded {
|
||||
return index, nil
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ func (m *simpleBindManager) IndexByName(name string) (int, error) {
|
|||
return 0, E.New("interface ", name, " not found")
|
||||
}
|
||||
|
||||
func (m *simpleBindManager) Update() error {
|
||||
func (m *myBindManager) Update() error {
|
||||
interfaces, err := net.Interfaces()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -2,8 +2,6 @@ package control
|
|||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func NewBindManager() BindManager {
|
||||
|
@ -12,11 +10,9 @@ func NewBindManager() BindManager {
|
|||
|
||||
func BindToInterface(manager BindManager, interfaceName string) Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
innerErr = syscall.BindToDevice(int(fd), interfaceName)
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
return syscall.BindToDevice(int(fd), interfaceName)
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,11 +22,9 @@ func BindToInterfaceFunc(manager BindManager, interfaceNameFunc func() string) F
|
|||
if interfaceName == "" {
|
||||
return nil
|
||||
}
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
innerErr = syscall.BindToDevice(int(fd), interfaceName)
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
return syscall.BindToDevice(int(fd), interfaceName)
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
"net/netip"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -16,7 +14,7 @@ const (
|
|||
)
|
||||
|
||||
func NewBindManager() BindManager {
|
||||
return &simpleBindManager{
|
||||
return &myBindManager{
|
||||
interfaceIndexByName: make(map[string]int),
|
||||
}
|
||||
}
|
||||
|
@ -39,28 +37,25 @@ func bindInterfaceIndex(network string, address string, conn syscall.RawConn, in
|
|||
return err
|
||||
}
|
||||
}
|
||||
var innerErr error
|
||||
err = conn.Control(func(fd uintptr) {
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
handle := syscall.Handle(fd)
|
||||
// handle ip empty, e.g. net.Listen("udp", ":0")
|
||||
if ipStr == "" {
|
||||
innerErr = bind4(handle, interfaceIndex)
|
||||
if innerErr != nil {
|
||||
return
|
||||
err = bind4(handle, interfaceIndex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// try bind ipv6, if failed, ignore. it's a workaround for windows disable interface ipv6
|
||||
bind6(handle, interfaceIndex)
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
switch network {
|
||||
case "tcp4", "udp4", "ip4":
|
||||
innerErr = bind4(handle, interfaceIndex)
|
||||
case "tcp6", "udp6":
|
||||
innerErr = bind6(handle, interfaceIndex)
|
||||
return bind4(handle, interfaceIndex)
|
||||
default:
|
||||
return bind6(handle, interfaceIndex)
|
||||
}
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
|
||||
func BindToInterface(manager BindManager, interfaceName string) Func {
|
||||
|
|
|
@ -2,6 +2,8 @@ package control
|
|||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
type Func = func(network, address string, conn syscall.RawConn) error
|
||||
|
@ -19,3 +21,11 @@ func Append(oldFunc Func, newFunc Func) Func {
|
|||
return newFunc(network, address, conn)
|
||||
}
|
||||
}
|
||||
|
||||
func Control(conn syscall.RawConn, block func(fd uintptr) error) error {
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
innerErr = block(fd)
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
|
|
|
@ -2,16 +2,12 @@ package control
|
|||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func RoutingMark(mark int) Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
innerErr = syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark)
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
return syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_MARK, mark)
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
//go:build linux
|
||||
|
||||
package control
|
||||
|
||||
import (
|
||||
|
@ -36,10 +34,8 @@ func sendAncillaryFileDescriptors(protectPath string, fileDescriptors []int) err
|
|||
|
||||
func ProtectPath(protectPath string) Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
innerErr = sendAncillaryFileDescriptors(protectPath, []int{int(fd)})
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
return sendAncillaryFileDescriptors(protectPath, []int{int(fd)})
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//go:build !linux
|
||||
//go:build !android
|
||||
|
||||
package control
|
||||
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func ReuseAddr() Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
const SO_REUSEPORT = 0xf
|
||||
innerErr = E.Errors(
|
||||
syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1),
|
||||
syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, SO_REUSEPORT, 1),
|
||||
)
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//go:build !linux && !windows
|
||||
//go:build !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd && !solaris && !windows
|
||||
|
||||
package control
|
||||
|
||||
|
|
22
common/control/reuse_unix.go
Normal file
22
common/control/reuse_unix.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris
|
||||
|
||||
package control
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
func ReuseAddr() Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
return E.Errors(
|
||||
unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEADDR, 1),
|
||||
unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -2,16 +2,12 @@ package control
|
|||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
)
|
||||
|
||||
func ReuseAddr() Func {
|
||||
return func(network, address string, conn syscall.RawConn) error {
|
||||
var innerErr error
|
||||
err := conn.Control(func(fd uintptr) {
|
||||
innerErr = syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||
return Control(conn, func(fd uintptr) error {
|
||||
return syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_REUSEADDR, 1)
|
||||
})
|
||||
return E.Errors(innerErr, err)
|
||||
}
|
||||
}
|
||||
|
|
2
go.mod
2
go.mod
|
@ -1,3 +1,5 @@
|
|||
module github.com/sagernet/sing
|
||||
|
||||
go 1.18
|
||||
|
||||
require golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8
|
||||
|
|
2
go.sum
2
go.sum
|
@ -0,0 +1,2 @@
|
|||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
Loading…
Add table
Add a link
Reference in a new issue