mirror of
https://github.com/SagerNet/sing.git
synced 2025-04-04 20:37:40 +03:00
43 lines
1 KiB
Go
43 lines
1 KiB
Go
//go:build (go1.19 && unix) || (!go1.19 && (linux || darwin))
|
|
|
|
package control
|
|
|
|
import (
|
|
"syscall"
|
|
|
|
E "github.com/sagernet/sing/common/exceptions"
|
|
)
|
|
|
|
func sendAncillaryFileDescriptors(protectPath string, fileDescriptors []int) error {
|
|
socket, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM, 0)
|
|
if err != nil {
|
|
return E.Cause(err, "open protect socket")
|
|
}
|
|
defer syscall.Close(socket)
|
|
err = syscall.Connect(socket, &syscall.SockaddrUnix{Name: protectPath})
|
|
if err != nil {
|
|
return E.Cause(err, "connect protect path")
|
|
}
|
|
oob := syscall.UnixRights(fileDescriptors...)
|
|
dummy := []byte{1}
|
|
err = syscall.Sendmsg(socket, dummy, oob, nil, 0)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
n, err := syscall.Read(socket, dummy)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if n != 1 {
|
|
return E.New("failed to protect fd")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ProtectPath(protectPath string) Func {
|
|
return func(network, address string, conn syscall.RawConn) error {
|
|
return Raw(conn, func(fd uintptr) error {
|
|
return sendAncillaryFileDescriptors(protectPath, []int{int(fd)})
|
|
})
|
|
}
|
|
}
|