tun: replace ip command with syscall
This commit is contained in:
parent
b11ce8a71c
commit
81ac55a019
2
go.mod
2
go.mod
@ -10,6 +10,7 @@ require (
|
|||||||
github.com/bifurcation/mint v0.0.0-20181105071958-a14404e9a861 // indirect
|
github.com/bifurcation/mint v0.0.0-20181105071958-a14404e9a861 // indirect
|
||||||
github.com/cheekybits/genny v1.0.0 // indirect
|
github.com/cheekybits/genny v1.0.0 // indirect
|
||||||
github.com/dchest/siphash v1.2.1 // indirect
|
github.com/dchest/siphash v1.2.1 // indirect
|
||||||
|
github.com/docker/libcontainer v2.2.1+incompatible // indirect
|
||||||
github.com/ginuerzh/gosocks4 v0.0.1
|
github.com/ginuerzh/gosocks4 v0.0.1
|
||||||
github.com/ginuerzh/gosocks5 v0.2.0
|
github.com/ginuerzh/gosocks5 v0.2.0
|
||||||
github.com/ginuerzh/tls-dissector v0.0.1
|
github.com/ginuerzh/tls-dissector v0.0.1
|
||||||
@ -25,6 +26,7 @@ require (
|
|||||||
github.com/lucas-clemente/quic-go v0.10.0
|
github.com/lucas-clemente/quic-go v0.10.0
|
||||||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced // indirect
|
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced // indirect
|
||||||
github.com/miekg/dns v1.1.3
|
github.com/miekg/dns v1.1.3
|
||||||
|
github.com/milosgajdos83/tenus v0.0.0-20190415114537-1f3ed00ae7d8
|
||||||
github.com/onsi/ginkgo v1.7.0 // indirect
|
github.com/onsi/ginkgo v1.7.0 // indirect
|
||||||
github.com/onsi/gomega v1.4.3 // indirect
|
github.com/onsi/gomega v1.4.3 // indirect
|
||||||
github.com/pkg/errors v0.8.1 // indirect
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
|
4
go.sum
4
go.sum
@ -16,6 +16,8 @@ github.com/dchest/siphash v1.2.0 h1:YWOShuhvg0GqbQpMa60QlCGtEyf7O7HC1Jf0VjdQ60M=
|
|||||||
github.com/dchest/siphash v1.2.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
github.com/dchest/siphash v1.2.0/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
||||||
github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
|
github.com/dchest/siphash v1.2.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
|
||||||
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
github.com/dchest/siphash v1.2.1/go.mod h1:q+IRvb2gOSrUnYoPqHiyHXS0FOBBOdl6tONBlVnOnt4=
|
||||||
|
github.com/docker/libcontainer v2.2.1+incompatible h1:++SbbkCw+X8vAd4j2gOCzZ2Nn7s2xFALTf7LZKmM1/0=
|
||||||
|
github.com/docker/libcontainer v2.2.1+incompatible/go.mod h1:osvj61pYsqhNCMLGX31xr7klUBhHb/ZBuXS0o1Fvwbw=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
github.com/ginuerzh/gosocks4 v0.0.1 h1:ojDKUyz+uaEeRm2usY1cyQiXTqJqrKxfeE6SVBXq4m0=
|
github.com/ginuerzh/gosocks4 v0.0.1 h1:ojDKUyz+uaEeRm2usY1cyQiXTqJqrKxfeE6SVBXq4m0=
|
||||||
@ -52,6 +54,8 @@ github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cce
|
|||||||
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
|
github.com/lucas-clemente/quic-go-certificates v0.0.0-20160823095156-d2f86524cced/go.mod h1:NCcRLrOTZbzhZvixZLlERbJtDtYsmMw8Jc4vS8Z0g58=
|
||||||
github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
|
github.com/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
|
||||||
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.1.3/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
|
github.com/milosgajdos83/tenus v0.0.0-20190415114537-1f3ed00ae7d8 h1:4WFQEfEJ7zaHYViIVM2Cd6tnQOOhiEHbmQtlcV7aOpc=
|
||||||
|
github.com/milosgajdos83/tenus v0.0.0-20190415114537-1f3ed00ae7d8/go.mod h1:G95Wwn625/q6JCCytI4VR/a5VtPwrtI0B+Q1Gi38QLA=
|
||||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
github.com/onsi/ginkgo v1.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
51
tun.go
51
tun.go
@ -5,8 +5,6 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -26,6 +24,7 @@ type TunConfig struct {
|
|||||||
type tunHandler struct {
|
type tunHandler struct {
|
||||||
raddr string
|
raddr string
|
||||||
options *HandlerOptions
|
options *HandlerOptions
|
||||||
|
ipNet *net.IPNet
|
||||||
}
|
}
|
||||||
|
|
||||||
// TunHandler creates a handler for tun tunnel.
|
// TunHandler creates a handler for tun tunnel.
|
||||||
@ -92,52 +91,10 @@ func (h *tunHandler) Handle(conn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h *tunHandler) createTun() (conn net.Conn, err error) {
|
func (h *tunHandler) createTun() (conn net.Conn, err error) {
|
||||||
cfg := h.options.TunConfig
|
conn, h.ipNet, err = createTun(h.options.TunConfig)
|
||||||
|
|
||||||
ip, _, err := net.ParseCIDR(cfg.Addr)
|
|
||||||
if err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ifce, err := water.New(water.Config{
|
|
||||||
DeviceType: water.TUN,
|
|
||||||
PlatformSpecificParams: water.PlatformSpecificParams{
|
|
||||||
Name: cfg.Name,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
setup := func(args ...string) error {
|
|
||||||
cmd := exec.Command("/sbin/ip", args...)
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
mtu := cfg.MTU
|
|
||||||
if mtu <= 0 {
|
|
||||||
mtu = DefaultMTU
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = setup("link", "set", "dev", ifce.Name(), "mtu", strconv.Itoa(mtu)); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = setup("addr", "add", cfg.Addr, "dev", ifce.Name()); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err = setup("link", "set", "dev", ifce.Name(), "up"); err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tc := &tunConn{
|
|
||||||
ifce: ifce,
|
|
||||||
addr: &net.IPAddr{IP: ip},
|
|
||||||
}
|
|
||||||
return tc, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tunHandler) transportTun(tun net.Conn, conn net.PacketConn, raddr net.Addr) error {
|
func (h *tunHandler) transportTun(tun net.Conn, conn net.PacketConn, raddr net.Addr) error {
|
||||||
var routes sync.Map
|
var routes sync.Map
|
||||||
errc := make(chan error, 1)
|
errc := make(chan error, 1)
|
||||||
@ -223,10 +180,12 @@ func (h *tunHandler) transportTun(tun net.Conn, conn net.PacketConn, raddr net.A
|
|||||||
header.Len, header.TotalLen, header.ID, header.Flags, header.Protocol)
|
header.Len, header.TotalLen, header.ID, header.Flags, header.Protocol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if h.ipNet != nil && h.ipNet.Contains(header.Src) {
|
||||||
if actual, loaded := routes.LoadOrStore(header.Src.String(), addr); loaded {
|
if actual, loaded := routes.LoadOrStore(header.Src.String(), addr); loaded {
|
||||||
if actual.(net.Addr).String() != addr.String() {
|
if actual.(net.Addr).String() != addr.String() {
|
||||||
log.Logf("[tun] %s <- %s: unexpected address mapping %s -> %s(actual %s)",
|
log.Logf("[tun] %s <- %s: unexpected address mapping %s -> %s(actual %s)",
|
||||||
tun.LocalAddr(), addr, header.Dst.String(), addr, actual.(net.Addr).String())
|
tun.LocalAddr(), addr, header.Dst, addr, actual.(net.Addr))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
44
tun_darwin.go
Normal file
44
tun_darwin.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// +build darwin
|
||||||
|
|
||||||
|
package gost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"os/exec"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/songgao/water"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
|
||||||
|
ip, ipNet, err := net.ParseCIDR(cfg.Addr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ifce, err := water.New(water.Config{
|
||||||
|
DeviceType: water.TUN,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mtu := cfg.MTU
|
||||||
|
if mtu <= 0 {
|
||||||
|
mtu = DefaultMTU
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = exec.Command(
|
||||||
|
"ifconfig", ifce.Name(),
|
||||||
|
"inet", cfg.Addr,
|
||||||
|
"mtu", strconv.Itoa(mtu),
|
||||||
|
"up").Run(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = &tunConn{
|
||||||
|
ifce: ifce,
|
||||||
|
addr: &net.IPAddr{IP: ip},
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
52
tun_linux.go
Normal file
52
tun_linux.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// +build linux
|
||||||
|
|
||||||
|
package gost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
"github.com/milosgajdos83/tenus"
|
||||||
|
"github.com/songgao/water"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
|
||||||
|
ip, ipNet, err := net.ParseCIDR(cfg.Addr)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ifce, err := water.New(water.Config{
|
||||||
|
DeviceType: water.TUN,
|
||||||
|
PlatformSpecificParams: water.PlatformSpecificParams{
|
||||||
|
Name: cfg.Name,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
link, err := tenus.NewLinkFrom(ifce.Name())
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
mtu := cfg.MTU
|
||||||
|
if mtu <= 0 {
|
||||||
|
mtu = DefaultMTU
|
||||||
|
}
|
||||||
|
if err = link.SetLinkMTU(mtu); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = link.SetLinkIp(ip, ipNet); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err = link.SetLinkUp(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
conn = &tunConn{
|
||||||
|
ifce: ifce,
|
||||||
|
addr: &net.IPAddr{IP: ip},
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
13
tun_win.go
Normal file
13
tun_win.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// +build windows
|
||||||
|
|
||||||
|
package gost
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createTun(cfg TunConfig) (conn net.Conn, ipNet *net.IPNet, err error) {
|
||||||
|
err = errors.New("tun is not supported on Windows")
|
||||||
|
return
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user