Add create tun from file descriptor

This commit is contained in:
世界 2023-02-26 16:58:07 +08:00
parent 8cb63dbb54
commit 0cdb0eed74
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
8 changed files with 67 additions and 49 deletions

View file

@ -1,11 +1,11 @@
fmt:
@gofumpt -l -w .
@gofmt -s -w .
@gci write -s "standard,prefix(github.com/sagernet/),default" .
@gci write --custom-order -s "standard,prefix(github.com/sagernet/),default" .
fmt_install:
go install -v mvdan.cc/gofumpt@latest
go install -v github.com/daixiang0/gci@v0.4.0
go install -v github.com/daixiang0/gci@latest
lint:
GOOS=linux golangci-lint run .

6
go.mod
View file

@ -6,9 +6,9 @@ require (
github.com/fsnotify/fsnotify v1.6.0
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
github.com/sagernet/sing v0.1.2
golang.org/x/net v0.4.0
golang.org/x/sys v0.3.0
github.com/sagernet/sing v0.1.7
golang.org/x/net v0.7.0
golang.org/x/sys v0.5.0
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c
)

14
go.sum
View file

@ -2,24 +2,22 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA=
github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e h1:5CFRo8FJbCuf5s/eTBdZpmMbn8Fe2eSMLNAYfKanA34=
github.com/sagernet/abx-go v0.0.0-20220819185957-dba1257d738e/go.mod h1:qbt0dWObotCfcjAJJ9AxtFPNSDUfZF+6dCpgKEOBn/g=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 h1:5+m7c6AkmAylhauulqN/c5dnh8/KssrE9c93TQrXldA=
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61/go.mod h1:QUQ4RRHD6hGGHdFMEtR8T2P6GS6R3D/CXKdaYHKKXms=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/sing v0.0.0-20220817130738-ce854cda8522/go.mod h1:QVsS5L/ZA2Q5UhQwLrn0Trw+msNd/NPGEhBKR/ioWiY=
github.com/sagernet/sing v0.1.2 h1:rp5AqY23P0klk2IaLEI0/WJsD8FTVlv9TaI2QSL6TDA=
github.com/sagernet/sing v0.1.2/go.mod h1:bvmen56QnVbMrWy+nr5nsbz7U5MUPuY0L0S/XfhCsTs=
github.com/sagernet/sing v0.1.7 h1:g4vjr3q8SUlBZSx97Emz5OBfSMBxxW5Q8C2PfdoSo08=
github.com/sagernet/sing v0.1.7/go.mod h1:jt1w2u7lJQFFSGLiRrRIs5YWmx4kAPfWuOejuDW9qMk=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
gvisor.dev/gvisor v0.0.0-20220901235040-6ca97ef2ce1c h1:m5lcgWnL3OElQNVyp3qcncItJ2c0sQlSGjYK2+nJTA4=

1
tun.go
View file

@ -46,6 +46,7 @@ type Options struct {
ExcludePackage []string
InterfaceMonitor DefaultInterfaceMonitor
TableIndex int
FileDescriptor int
}
func CalculateInterfaceName(name string) (tunName string) {

View file

@ -28,23 +28,29 @@ type NativeTun struct {
inet6Address string
}
func Open(options Options) (Tun, error) {
ifIndex := -1
_, err := fmt.Sscanf(options.Name, "utun%d", &ifIndex)
if err != nil {
return nil, E.New("bad tun name: ", options.Name)
func New(options Options) (Tun, error) {
var tunFd int
if options.FileDescriptor == 0 {
ifIndex := -1
_, err := fmt.Sscanf(options.Name, "utun%d", &ifIndex)
if err != nil {
return nil, E.New("bad tun name: ", options.Name)
}
tunFd, err = unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2)
if err != nil {
return nil, err
}
err = configure(tunFd, ifIndex, options.Name, options)
if err != nil {
unix.Close(tunFd)
return nil, err
}
} else {
tunFd = options.FileDescriptor
}
tunFd, err := unix.Socket(unix.AF_SYSTEM, unix.SOCK_DGRAM, 2)
if err != nil {
return nil, err
}
err = configure(tunFd, ifIndex, options.Name, options)
if err != nil {
unix.Close(tunFd)
return nil, err
}
nativeTun := &NativeTun{
tunFile: os.NewFile(uintptr(tunFd), "utun"),
mtu: options.MTU,

View file

@ -25,26 +25,36 @@ type NativeTun struct {
ruleIndex6 []int
}
func Open(options Options) (Tun, error) {
tunFd, err := open(options.Name)
if err != nil {
return nil, err
func New(options Options) (Tun, error) {
if options.FileDescriptor == 0 {
tunFd, err := open(options.Name)
if err != nil {
return nil, err
}
tunLink, err := netlink.LinkByName(options.Name)
if err != nil {
return nil, E.Errors(err, unix.Close(tunFd))
}
nativeTun := &NativeTun{
tunFd: tunFd,
tunFile: os.NewFile(uintptr(tunFd), "tun"),
options: options,
}
runtime.SetFinalizer(nativeTun.tunFile, nil)
err = nativeTun.configure(tunLink)
if err != nil {
return nil, E.Errors(err, unix.Close(tunFd))
}
return nativeTun, nil
} else {
nativeTun := &NativeTun{
tunFd: options.FileDescriptor,
tunFile: os.NewFile(uintptr(options.FileDescriptor), "tun"),
options: options,
}
runtime.SetFinalizer(nativeTun.tunFile, nil)
return nativeTun, nil
}
tunLink, err := netlink.LinkByName(options.Name)
if err != nil {
return nil, E.Errors(err, unix.Close(tunFd))
}
nativeTun := &NativeTun{
tunFd: tunFd,
tunFile: os.NewFile(uintptr(tunFd), "tun"),
options: options,
}
runtime.SetFinalizer(nativeTun.tunFile, nil)
err = nativeTun.configure(tunLink)
if err != nil {
return nil, E.Errors(err, unix.Close(tunFd))
}
return nativeTun, nil
}
func (t *NativeTun) Read(p []byte) (n int, err error) {

View file

@ -6,6 +6,6 @@ import (
"os"
)
func Open(config Options) (Tun, error) {
func New(config Options) (Tun, error) {
return nil, os.ErrInvalid
}

View file

@ -36,7 +36,10 @@ type NativeTun struct {
fwpmSession uintptr
}
func Open(options Options) (WinTun, error) {
func New(options Options) (WinTun, error) {
if options.FileDescriptor != 0 {
return nil, os.ErrInvalid
}
adapter, err := wintun.CreateAdapter(options.Name, TunnelType, generateGUIDByDeviceName(options.Name))
if err != nil {
return nil, err