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/cheekybits/genny v1.0.0 // 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/gosocks5 v0.2.0
|
||||
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-certificates v0.0.0-20160823095156-d2f86524cced // indirect
|
||||
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/gomega v1.4.3 // 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.1 h1:4cLinnzVJDKxTCl9B01807Yiy+W7ZzVHj/KIroQRvT4=
|
||||
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/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
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/miekg/dns v1.1.3 h1:1g0r1IvskvgL8rR+AcHzUA+oFmGcQlaIm4IqakufeMM=
|
||||
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.7.0 h1:WSHQ+IS43OoUrWtD1/bbclrwK8TTH5hzp+umCiuxHgs=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
|
59
tun.go
59
tun.go
@ -5,8 +5,6 @@ import (
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@ -26,6 +24,7 @@ type TunConfig struct {
|
||||
type tunHandler struct {
|
||||
raddr string
|
||||
options *HandlerOptions
|
||||
ipNet *net.IPNet
|
||||
}
|
||||
|
||||
// TunHandler creates a handler for tun tunnel.
|
||||
@ -92,50 +91,8 @@ func (h *tunHandler) Handle(conn net.Conn) {
|
||||
}
|
||||
|
||||
func (h *tunHandler) createTun() (conn net.Conn, err error) {
|
||||
cfg := h.options.TunConfig
|
||||
|
||||
ip, _, 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
|
||||
}
|
||||
|
||||
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
|
||||
conn, h.ipNet, err = createTun(h.options.TunConfig)
|
||||
return
|
||||
}
|
||||
|
||||
func (h *tunHandler) transportTun(tun net.Conn, conn net.PacketConn, raddr net.Addr) error {
|
||||
@ -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)
|
||||
}
|
||||
|
||||
if actual, loaded := routes.LoadOrStore(header.Src.String(), addr); loaded {
|
||||
if actual.(net.Addr).String() != addr.String() {
|
||||
log.Logf("[tun] %s <- %s: unexpected address mapping %s -> %s(actual %s)",
|
||||
tun.LocalAddr(), addr, header.Dst.String(), addr, actual.(net.Addr).String())
|
||||
if h.ipNet != nil && h.ipNet.Contains(header.Src) {
|
||||
if actual, loaded := routes.LoadOrStore(header.Src.String(), addr); loaded {
|
||||
if actual.(net.Addr).String() != addr.String() {
|
||||
log.Logf("[tun] %s <- %s: unexpected address mapping %s -> %s(actual %s)",
|
||||
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