diff --git a/Makefile b/Makefile index 57c2360..01cc64e 100644 --- a/Makefile +++ b/Makefile @@ -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 . diff --git a/go.mod b/go.mod index 7ef6fb9..3cef29a 100644 --- a/go.mod +++ b/go.mod @@ -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 ) diff --git a/go.sum b/go.sum index 10bc530..f45cbfe 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/tun.go b/tun.go index 067607a..57df563 100644 --- a/tun.go +++ b/tun.go @@ -46,6 +46,7 @@ type Options struct { ExcludePackage []string InterfaceMonitor DefaultInterfaceMonitor TableIndex int + FileDescriptor int } func CalculateInterfaceName(name string) (tunName string) { diff --git a/tun_darwin.go b/tun_darwin.go index e849bec..4c33161 100644 --- a/tun_darwin.go +++ b/tun_darwin.go @@ -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 - } + 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 + err = configure(tunFd, ifIndex, options.Name, options) + if err != nil { + unix.Close(tunFd) + return nil, err + } + } else { + tunFd = options.FileDescriptor } + nativeTun := &NativeTun{ tunFile: os.NewFile(uintptr(tunFd), "utun"), mtu: options.MTU, diff --git a/tun_linux.go b/tun_linux.go index be78840..ca582a5 100644 --- a/tun_linux.go +++ b/tun_linux.go @@ -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 - } - 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)) +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 } - return nativeTun, nil } func (t *NativeTun) Read(p []byte) (n int, err error) { diff --git a/tun_other.go b/tun_other.go index b38fe6a..1db48f9 100644 --- a/tun_other.go +++ b/tun_other.go @@ -6,6 +6,6 @@ import ( "os" ) -func Open(config Options) (Tun, error) { +func New(config Options) (Tun, error) { return nil, os.ErrInvalid } diff --git a/tun_windows.go b/tun_windows.go index e73264d..8396444 100644 --- a/tun_windows.go +++ b/tun_windows.go @@ -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