diff --git a/Makefile b/Makefile index fe590063..2f686b12 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ BUILDDIR=$(shell pwd)/build CMDDIR=$(shell pwd)/cmd/tun2socks PROGRAM=tun2socks GOOS:=$(strip $(shell go env GOOS)) -GOARCH:=$(strip $(shell go env GOARCH)) +GOARCHs:=$(strip $(shell go env GOARCH)) ifeq "$(GOOS)" "windows" SUFFIX=.exe @@ -20,7 +20,7 @@ endif all: fmt build build: - $(GOBUILD) -ldflags $(RELEASE_LDFLAGS) -o $(BUILDDIR)/$(PROGRAM)_$(GOOS)_$(GOARCH)$(SUFFIX) -v -tags '$(BUILD_TAGS)' $(CMDDIR) + $(foreach GOARCH,$(GOARCHs),$(shell GOARCH=$(GOARCH) $(GOBUILD) -ldflags $(RELEASE_LDFLAGS) -o $(BUILDDIR)/$(PROGRAM)_$(GOOS)_$(GOARCH)$(SUFFIX) -v -tags '$(BUILD_TAGS)' $(CMDDIR))) fmt: gofmt -w -s . diff --git a/cmd/tun2socks/main.go b/cmd/tun2socks/main.go index 645180ef..cef8abfa 100644 --- a/cmd/tun2socks/main.go +++ b/cmd/tun2socks/main.go @@ -5,6 +5,7 @@ import ( "flag" "fmt" "io" + "net" "os" "os/signal" "runtime" @@ -12,17 +13,19 @@ import ( "syscall" "time" + "github.com/kayrus/tuncfg/log" + _ "github.com/kayrus/tuncfg/log/simple" // Register a simple logger. + "github.com/kayrus/tuncfg/resolv" + "github.com/kayrus/tuncfg/route" + "github.com/kayrus/tuncfg/tun" + "github.com/eycorsican/go-tun2socks/common/dns/blocker" - "github.com/eycorsican/go-tun2socks/common/log" - _ "github.com/eycorsican/go-tun2socks/common/log/simple" // Register a simple logger. "github.com/eycorsican/go-tun2socks/core" - "github.com/eycorsican/go-tun2socks/routes" - "github.com/eycorsican/go-tun2socks/tun" ) var version = "undefined" -var handlerCreater = make(map[string]func(), 0) +var handlerCreater = make(map[string]func()) func registerHandlerCreater(name string, creater func()) { handlerCreater[name] = creater @@ -80,12 +83,6 @@ func (a *CmdArgs) addFlag(f cmdFlag) { } } -var args = new(CmdArgs) - -const ( - maxMTU = 65535 -) - func fatal(err interface{}) { if runtime.GOOS == "windows" { // Escalated privileges in windows opens a new terminal, and if there is an @@ -102,6 +99,16 @@ func fatal(err interface{}) { } } +func splitFunc(c rune) bool { + return c == ',' || c == ' ' +} + +var args = new(CmdArgs) + +const ( + maxMTU = 65535 +) + func main() { // linux and darwin pick up the tun index automatically // windows requires the exact tun name @@ -110,7 +117,7 @@ func main() { case "darwin": defaultTunName = "utun" case "windows": - defaultTunName = "socks2tun" + defaultTunName = "tun2socks" } args.TunName = flag.String("tunName", defaultTunName, "TUN interface name") @@ -118,7 +125,7 @@ func main() { args.TunAddr = flag.String("tunAddr", "10.255.0.2", "TUN interface address") args.TunGw = flag.String("tunGw", "10.255.0.1", "TUN interface gateway") args.TunMask = flag.String("tunMask", "255.255.255.255", "TUN interface netmask, it should be a prefixlen (a number) for IPv6 address") - args.TunDns = flag.String("tunDns", "8.8.8.8,8.8.4.4", "DNS resolvers for TUN interface (only need on Windows)") + args.TunDns = flag.String("tunDns", "", "DNS resolvers for TUN interface (only need on Windows)") args.TunMTU = flag.Int("tunMTU", 1300, "TUN interface MTU") args.BlockOutsideDns = flag.Bool("blockOutsideDns", false, "Prevent DNS leaks by blocking plaintext DNS queries going out through non-TUN interface (may require admin privileges) (Windows only) ") args.ProxyType = flag.String("proxyType", "socks", "Proxy handler type") @@ -162,7 +169,7 @@ func main() { case "none": log.SetLevel(log.NONE) default: - panic("unsupport logging level") + fatal(fmt.Errorf("unsupport logging level")) } err := run() @@ -171,27 +178,89 @@ func main() { } } +func parseAddresses(localAddr, netMask, nextHop string) (*net.IPNet, *net.IPNet, error) { + local := net.ParseIP(localAddr) + if local == nil { + return nil, nil, fmt.Errorf("invalid local IP address") + } + + mask := net.ParseIP(netMask) + if mask == nil { + return nil, nil, fmt.Errorf("invalid local IP mask") + } + + gw := net.ParseIP(nextHop) + if gw == nil { + return nil, nil, fmt.Errorf("invalid gateway IP address") + } + + loc := &net.IPNet{ + IP: local.To4(), + Mask: net.IPMask(mask.To4()), + } + rem := &net.IPNet{ + IP: gw.To4(), + Mask: net.CIDRMask(32, 32), + } + + return loc, rem, nil +} + func run() error { - tunGw, tunRoutes, err := routes.Get(*args.Routes, *args.Exclude, *args.TunAddr, *args.TunGw, *args.TunMask) + local, gw, err := parseAddresses(*args.TunAddr, *args.TunMask, *args.TunGw) + if err != nil { + return err + } + + tunRoutes, err := route.Build(local, gw, *args.Routes, *args.Exclude) if err != nil { return fmt.Errorf("cannot parse config values: %v", err) } + var dnsServers []net.IP + for _, v := range strings.FieldsFunc(*args.TunDns, splitFunc) { + if v := net.ParseIP(v); v != nil { + if v := v.To4(); v != nil { + dnsServers = append(dnsServers, v) + } + } + } + // Open the tun device. - dnsServers := strings.Split(*args.TunDns, ",") - tunDev, err := tun.OpenTunDevice(*args.TunName, *args.TunAddr, *args.TunGw, *args.TunMask, *args.TunMTU, dnsServers) + tunDev, err := tun.OpenTunDevice(local, gw, *args.TunName, *args.TunMTU) if err != nil { return fmt.Errorf("failed to open tun device: %v", err) } + name, err := tunDev.Name() + if err != nil { + return fmt.Errorf("failed to get tun name: %v", err) + } + + // configure DNS + resolv, err := resolv.New(name, dnsServers, nil, false) + if err != nil { + return fmt.Errorf("failed to create tun device DNS handler: %v", err) + } + err = resolv.Set() + if err != nil { + return fmt.Errorf("failed manage tun device DNS options: %v", err) + } + + defer resolv.Restore() // close the tun device defer tunDev.Close() + routes, err := route.New(name, tunRoutes, gw.IP, 0) + if err != nil { + return err + } + // unset routes on exit, when provided - defer routes.Unset(*args.TunName, tunGw, tunRoutes) + defer routes.Del() // set routes, when provided - routes.Set(*args.TunName, tunGw, tunRoutes) + routes.Add() if runtime.GOOS == "windows" && *args.BlockOutsideDns { if err := blocker.BlockOutsideDns(*args.TunName); err != nil { @@ -218,23 +287,24 @@ func run() error { } } + var tunRW io.ReadWriter = &tun.Tunnel{NativeTun: tunDev} + // Register an output callback to write packets output from lwip stack to tun // device, output function should be set before input any packets. core.RegisterOutputFn(func(data []byte) (int, error) { - return tunDev.Write(data) + return tunRW.Write(data) }) // Copy packets from tun device to lwip stack, it's the main loop. errChan := make(chan error, 1) go func() { - _, err := io.CopyBuffer(lwipWriter, tunDev, make([]byte, maxMTU)) + _, err := io.CopyBuffer(lwipWriter, tunRW, make([]byte, *args.TunMTU+tun.Offset)) if err != nil { errChan <- fmt.Errorf("copying data failed: %v", err) } }() log.Infof("Running tun2socks") - osSignals := make(chan os.Signal, 1) signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM, syscall.SIGHUP) diff --git a/cmd/tun2socks/main_socks.go b/cmd/tun2socks/main_socks.go index 2f0463e0..7fae86b7 100644 --- a/cmd/tun2socks/main_socks.go +++ b/cmd/tun2socks/main_socks.go @@ -5,7 +5,8 @@ package main import ( "net" - "github.com/eycorsican/go-tun2socks/common/log" + "github.com/kayrus/tuncfg/log" + "github.com/eycorsican/go-tun2socks/core" "github.com/eycorsican/go-tun2socks/proxy/socks" ) diff --git a/common/dns/blocker/blocker_windows.go b/common/dns/blocker/blocker_windows.go index e9b44836..77c757d1 100644 --- a/common/dns/blocker/blocker_windows.go +++ b/common/dns/blocker/blocker_windows.go @@ -8,9 +8,8 @@ import ( "net" "unsafe" + "github.com/kayrus/tuncfg/log" "golang.org/x/sys/windows" - - "github.com/eycorsican/go-tun2socks/common/log" ) func BlockOutsideDns(tunName string) error { diff --git a/common/log/log.go b/common/log/log.go deleted file mode 100644 index 93e492fd..00000000 --- a/common/log/log.go +++ /dev/null @@ -1,43 +0,0 @@ -package log - -var logger Logger - -func RegisterLogger(l Logger) { - logger = l -} - -func SetLevel(level LogLevel) { - if logger != nil { - logger.SetLevel(level) - } -} - -func Debugf(msg string, args ...interface{}) { - if logger != nil { - logger.Debugf(msg, args...) - } -} - -func Infof(msg string, args ...interface{}) { - if logger != nil { - logger.Infof(msg, args...) - } -} - -func Warnf(msg string, args ...interface{}) { - if logger != nil { - logger.Warnf(msg, args...) - } -} - -func Errorf(msg string, args ...interface{}) { - if logger != nil { - logger.Errorf(msg, args...) - } -} - -func Fatalf(msg string, args ...interface{}) { - if logger != nil { - logger.Fatalf(msg, args...) - } -} diff --git a/common/log/logger.go b/common/log/logger.go deleted file mode 100644 index 02168afa..00000000 --- a/common/log/logger.go +++ /dev/null @@ -1,20 +0,0 @@ -package log - -type LogLevel uint8 - -const ( - DEBUG LogLevel = iota - INFO - WARN - ERROR - NONE -) - -type Logger interface { - SetLevel(level LogLevel) - Debugf(msg string, args ...interface{}) - Infof(msg string, args ...interface{}) - Warnf(msg string, args ...interface{}) - Errorf(msg string, args ...interface{}) - Fatalf(msg string, args ...interface{}) -} diff --git a/common/log/simple/logger.go b/common/log/simple/logger.go deleted file mode 100644 index bc51b436..00000000 --- a/common/log/simple/logger.go +++ /dev/null @@ -1,55 +0,0 @@ -package simple - -import ( - golog "log" - - "github.com/eycorsican/go-tun2socks/common/log" -) - -type simpleLogger struct { - level log.LogLevel -} - -func NewSimpleLogger() log.Logger { - return &simpleLogger{log.INFO} -} - -func (l *simpleLogger) SetLevel(level log.LogLevel) { - l.level = level -} - -func (l *simpleLogger) Debugf(msg string, args ...interface{}) { - if l.level <= log.DEBUG { - l.output(msg, args...) - } -} - -func (l *simpleLogger) Infof(msg string, args ...interface{}) { - if l.level <= log.INFO { - l.output(msg, args...) - } -} - -func (l *simpleLogger) Warnf(msg string, args ...interface{}) { - if l.level <= log.WARN { - l.output(msg, args...) - } -} - -func (l *simpleLogger) Errorf(msg string, args ...interface{}) { - if l.level <= log.ERROR { - l.output(msg, args...) - } -} - -func (l *simpleLogger) Fatalf(msg string, args ...interface{}) { - golog.Fatalf(msg, args...) -} - -func (l *simpleLogger) output(msg string, args ...interface{}) { - golog.Printf(msg, args...) -} - -func init() { - log.RegisterLogger(NewSimpleLogger()) -} diff --git a/go.mod b/go.mod index aa6ace41..7a8f1047 100644 --- a/go.mod +++ b/go.mod @@ -3,13 +3,13 @@ module github.com/eycorsican/go-tun2socks go 1.15 require ( - github.com/IBM/netaddr v1.4.0 - github.com/stretchr/testify v1.6.1 // indirect - github.com/vishvananda/netlink v1.1.0 + github.com/kayrus/tuncfg v0.0.0-20210306071952-3921bb103b0a golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 - golang.org/x/sys v0.0.0-20210225014209-683adc9d29d7 - golang.zx2c4.com/wireguard v0.0.0-20210225140808-70b7b7158fc9 + golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 ) // a fork with a FreeBSD default tun name patch replace golang.zx2c4.com/wireguard v0.0.0-20210225140808-70b7b7158fc9 => github.com/kayrus/wireguard v0.0.0-20210228102730-04afc3c4c795 + +// a fork with a Windows convertInterfaceIndexToLUID +replace golang.zx2c4.com/wireguard/windows v0.3.8 => github.com/kayrus/wireguard-windows v0.0.0-20210303100507-540e87897140 diff --git a/go.sum b/go.sum index 675f5603..14858cfa 100644 --- a/go.sum +++ b/go.sum @@ -2,13 +2,19 @@ github.com/IBM/netaddr v1.4.0 h1:6T+fAXurIdgA9+nVlehOOkhhxmzU2MTxtok7qNldDVo= github.com/IBM/netaddr v1.4.0/go.mod h1:eXOsTXDZemcAXuuddrfHcWdA0on76PJwaH37JnS5PKE= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kayrus/tuncfg v0.0.0-20210306071952-3921bb103b0a h1:oJOHsKTS7O/gpr5kg/dXv+sVinDDY7yIuFaIETCksA0= +github.com/kayrus/tuncfg v0.0.0-20210306071952-3921bb103b0a/go.mod h1:jsqmbtu62UH+IsDm4w7CE7rF8IwalDsyEjCw2cvvd6o= github.com/kayrus/wireguard v0.0.0-20210228102730-04afc3c4c795 h1:jssAOd/ifYICiV/LWyQt1TG0KOu8513mYLuLxfdqLR8= github.com/kayrus/wireguard v0.0.0-20210228102730-04afc3c4c795/go.mod h1:39ZQQ95hUxDxT7opsWy/rtfgvXXc8s30qfZ02df69Fo= +github.com/kayrus/wireguard-windows v0.0.0-20210303100507-540e87897140 h1:1oafBZsdZsjmG5PMYlEpP3bfquhaq6yGGYHHGNcVS7k= +github.com/kayrus/wireguard-windows v0.0.0-20210303100507-540e87897140/go.mod h1:lm7dxHcBuzMNq706Ge1tZKZKw4+19vG9dLOhoDX05HQ= +github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ= +github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/vishvananda/netlink v1.1.0 h1:1iyaYNBLmP6L0220aDnYQpo1QEV4t4hJ+xEEhhJH8j0= github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df h1:OviZH7qLw/7ZovXvuNyL3XQl8UFofeikI1NW1Gypu7k= @@ -21,13 +27,17 @@ golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225014209-683adc9d29d7 h1:pk3Y+QnSKjMLfO/HIqzn/Zvv3/IHjRPhwblrmUuodzw= golang.org/x/sys v0.0.0-20210225014209-683adc9d29d7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04 h1:cEhElsAv9LUt9ZUUocxzWe05oFLVd+AA2nstydTeI8g= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6-0.20210220033129-8f690f22cf1c/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/proxy/redirect/tcp.go b/proxy/redirect/tcp.go index 8b092517..104718a3 100644 --- a/proxy/redirect/tcp.go +++ b/proxy/redirect/tcp.go @@ -4,7 +4,8 @@ import ( "io" "net" - "github.com/eycorsican/go-tun2socks/common/log" + "github.com/kayrus/tuncfg/log" + "github.com/eycorsican/go-tun2socks/core" ) diff --git a/proxy/redirect/udp.go b/proxy/redirect/udp.go index 817d5131..d31f15bd 100644 --- a/proxy/redirect/udp.go +++ b/proxy/redirect/udp.go @@ -7,7 +7,8 @@ import ( "sync" "time" - "github.com/eycorsican/go-tun2socks/common/log" + "github.com/kayrus/tuncfg/log" + "github.com/eycorsican/go-tun2socks/core" ) diff --git a/proxy/socks/tcp.go b/proxy/socks/tcp.go index f2cbf051..6013e132 100644 --- a/proxy/socks/tcp.go +++ b/proxy/socks/tcp.go @@ -5,9 +5,9 @@ import ( "net" "sync" + "github.com/kayrus/tuncfg/log" "golang.org/x/net/proxy" - "github.com/eycorsican/go-tun2socks/common/log" "github.com/eycorsican/go-tun2socks/core" ) diff --git a/proxy/socks/udp.go b/proxy/socks/udp.go index 36903043..7c517860 100644 --- a/proxy/socks/udp.go +++ b/proxy/socks/udp.go @@ -8,7 +8,8 @@ import ( "sync" "time" - "github.com/eycorsican/go-tun2socks/common/log" + "github.com/kayrus/tuncfg/log" + "github.com/eycorsican/go-tun2socks/core" ) diff --git a/routes/routes.go b/routes/routes.go deleted file mode 100644 index de8a7d37..00000000 --- a/routes/routes.go +++ /dev/null @@ -1,129 +0,0 @@ -package routes - -import ( - "fmt" - "net" - "strings" - - "github.com/IBM/netaddr" - "github.com/eycorsican/go-tun2socks/common/log" -) - -func splitFunc(c rune) bool { - return c == ',' || c == ' ' -} - -func getNet(v interface{}) *net.IPNet { - switch v := v.(type) { - case net.IP: - return &net.IPNet{IP: v, Mask: net.CIDRMask(32, 32)} - case *net.IPNet: - return v - } - return nil -} - -func Get(routes, excludeRoutes, addr, gw, mask string) (net.IP, []*net.IPNet, error) { - excludeAddrs, err := ParseAddresses(addr, gw, mask) - if err != nil { - return nil, nil, fmt.Errorf("invalid addresses: %v", err) - } - - res := &netaddr.IPSet{} - for _, cidr := range strings.FieldsFunc(routes, splitFunc) { - if v := net.ParseIP(cidr).To4(); v != nil { - res.InsertNet(getNet(v)) - log.Debugf("including %s to routes", v) - continue - } - - _, v, err := net.ParseCIDR(cidr) - if err != nil { - // trying to lookup a hostname - if ips, err := net.LookupIP(cidr); err == nil { - for _, v := range ips { - if v := v.To4(); v != nil { - log.Debugf("including %s (%s) to routes", cidr, v) - res.InsertNet(getNet(v)) - } - } - continue - } else { - return nil, nil, fmt.Errorf("failed to resolve %q: %v", cidr, err) - } - return nil, nil, fmt.Errorf("failed to parse %s CIDR: %v", cidr, err) - } - log.Debugf("including %s to routes", v) - res.InsertNet(v) - } - - for _, cidr := range strings.FieldsFunc(excludeRoutes, splitFunc) { - if v := net.ParseIP(cidr).To4(); v != nil { - res.RemoveNet(getNet(v)) - log.Debugf("excluding %s from routes", v) - continue - } - - _, v, err := net.ParseCIDR(cidr) - if err != nil { - // trying to lookup a hostname - if ips, err := net.LookupIP(cidr); err == nil { - for _, v := range ips { - if v := v.To4(); v != nil { - log.Debugf("excluding %s (%s) from routes", cidr, v) - res.RemoveNet(getNet(v)) - } - } - continue - } else { - return nil, nil, fmt.Errorf("failed to resolve %q: %v", cidr, err) - } - return nil, nil, fmt.Errorf("failed to parse %s CIDR: %v", cidr, err) - } - log.Debugf("excluding %s from routes", v) - res.RemoveNet(v) - } - - for _, cidr := range excludeAddrs { - res.RemoveNet(cidr) - } - - gateway := excludeAddrs[1] - return gateway.IP, res.GetNetworks(), nil -} - -func Set(name string, gw net.IP, routes []*net.IPNet) { - for _, cidr := range routes { - if err := routeAdd(cidr, gw, 0, name); err != nil { - log.Errorf("failed to set %s routes: %v", name, err) - } - } -} - -func Unset(name string, gw net.IP, routes []*net.IPNet) { - for _, cidr := range routes { - if err := routeDel(cidr, gw, 0, name); err != nil { - log.Errorf("failed to unset %s routes: %v", name, err) - } - } -} - -func ParseAddresses(addr, gw, mask string) ([]*net.IPNet, error) { - local := net.ParseIP(addr) - if local == nil { - return nil, fmt.Errorf("invalid local IP address") - } - remote := net.ParseIP(gw) - if remote == nil { - return nil, fmt.Errorf("invalid server IP address") - } - remoteMask := net.ParseIP(mask) - if remoteMask == nil { - return nil, fmt.Errorf("invalid server IP mask") - } - - return []*net.IPNet{ - getNet(local), - {IP: remote, Mask: net.IPMask(remoteMask.To4())}, - }, nil -} diff --git a/routes/routes_linux.go b/routes/routes_linux.go deleted file mode 100644 index b198e02f..00000000 --- a/routes/routes_linux.go +++ /dev/null @@ -1,46 +0,0 @@ -package routes - -import ( - "fmt" - "net" - - "github.com/vishvananda/netlink" -) - -func routeAdd(dst interface{}, gw net.IP, priority int, name string) error { - route := netlink.Route{ - Dst: getNet(dst), - Priority: priority, - Gw: gw, - } - if gw == nil { - link, err := netlink.LinkByName(name) - if err != nil { - return fmt.Errorf("failed to get %q interface by name: %s", name, err) - } - route.LinkIndex = link.Attrs().Index - } - if err := netlink.RouteReplace(&route); err != nil { - return fmt.Errorf("failed to add %s route to %q interface: %s", dst, name, err) - } - return nil -} - -func routeDel(dst interface{}, gw net.IP, priority int, name string) error { - route := netlink.Route{ - Dst: getNet(dst), - Priority: priority, - Gw: gw, - } - if gw == nil { - link, err := netlink.LinkByName(name) - if err != nil { - return fmt.Errorf("failed to get %q interface by name: %s", name, err) - } - route.LinkIndex = link.Attrs().Index - } - if err := netlink.RouteDel(&route); err != nil { - return fmt.Errorf("failed to delete %s route from %q interface: %s", dst, name, err) - } - return nil -} diff --git a/routes/routes_unix.go b/routes/routes_unix.go deleted file mode 100644 index fc5c6a03..00000000 --- a/routes/routes_unix.go +++ /dev/null @@ -1,49 +0,0 @@ -// +build darwin freebsd - -package routes - -import ( - "fmt" - "net" - "os/exec" -) - -func routeAdd(dst interface{}, gw net.IP, priority int, name string) error { - // an implementation of "replace" - routeDel(dst, gw, priority, name) - args := []string{ - "-n", - "add", - "-net", - getNet(dst).String(), - } - if gw == nil { - args = append(args, "-interface", name) - } else { - args = append(args, gw.String()) - } - v, err := exec.Command("route", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to add %s route to %s interface: %s: %s: %s", dst, name, args, v, err) - } - return nil -} - -func routeDel(dst interface{}, gw net.IP, priority int, name string) error { - args := []string{ - "-n", - "delete", - "-net", - getNet(dst).String(), - } - if gw == nil { - args = append(args, "-interface", name) - } else { - args = append(args, gw.String()) - } - v, err := exec.Command("route", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to delete %s route from %s interface: %s: %s: %s", dst, name, args, v, err) - } - return nil -} diff --git a/routes/routes_windows.go b/routes/routes_windows.go deleted file mode 100644 index 08015c2f..00000000 --- a/routes/routes_windows.go +++ /dev/null @@ -1,68 +0,0 @@ -package routes - -import ( - "fmt" - "net" - "os/exec" -) - -var ifIndex int - -func getIfID(name string) error { - iface, err := net.InterfaceByName(name) - if err != nil { - return fmt.Errorf("failed to find a %q interface index: %s", name, err) - } - - ifIndex = iface.Index - - return nil -} - -func routeAdd(dst interface{}, gw net.IP, priority int, name string) error { - if ifIndex == 0 { - if err := getIfID(name); err != nil { - return err - } - } - - // an implementation of "replace" - routeDel(dst, gw, priority, name) - d := getNet(dst) - args := []string{ - "add", - d.IP.String(), - "mask", - net.IP(d.Mask).To4().String(), - gw.String(), - "metric", - fmt.Sprintf("%d", priority+1), - "if", - fmt.Sprintf("%d", ifIndex), - } - v, err := exec.Command("route.exe", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to add %s route to %s interface: %s: %s: %s", dst, name, args, v, err) - } - return nil -} - -func routeDel(dst interface{}, gw net.IP, priority int, name string) error { - d := getNet(dst) - args := []string{ - "delete", - d.IP.String(), - "mask", - net.IP(d.Mask).To4().String(), - gw.String(), - "metric", - fmt.Sprintf("%d", priority+1), - "if", - fmt.Sprintf("%d", ifIndex), - } - v, err := exec.Command("route.exe", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to delete %s route from %s interface: %s: %s: %s", dst, name, args, v, err) - } - return nil -} diff --git a/tun/tun.go b/tun/tun.go deleted file mode 100644 index 7e4c2624..00000000 --- a/tun/tun.go +++ /dev/null @@ -1,21 +0,0 @@ -package tun - -import ( - "io" - - "golang.zx2c4.com/wireguard/tun" -) - -func OpenTunDevice(name, addr, gw, mask string, mtu int, dnsServers []string) (io.ReadWriteCloser, error) { - tunDev, err := tun.CreateTUN(name, mtu) - if err != nil { - return nil, err - } - - getName, err := tunDev.Name() - if err != nil { - return nil, err - } - - return &tunnel{Device: tunDev}, setInterface(getName, addr, gw, mask, mtu, tunDev.(*tun.NativeTun)) -} diff --git a/tun/tun_default.go b/tun/tun_default.go deleted file mode 100644 index a4abfdbb..00000000 --- a/tun/tun_default.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build !windows - -package tun - -import ( - "golang.zx2c4.com/wireguard/tun" -) - -type tunnel struct { - tun.Device -} - -func (t *tunnel) Read(b []byte) (int, error) { - // unix.IFF_NO_PI is not set, therefore we receive packet information - n, err := t.Device.File().Read(b) - if n < 4 { - return 0, err - } - // shift slice to the left - return copy(b[:n-4], b[4:n]), nil -} - -func (t *tunnel) Write(b []byte) (int, error) { - return t.Device.Write(append(make([]byte, 4), b...), 4) -} - -func (t *tunnel) Close() error { - return t.Device.Close() -} diff --git a/tun/tun_linux.go b/tun/tun_linux.go deleted file mode 100644 index ba3985e2..00000000 --- a/tun/tun_linux.go +++ /dev/null @@ -1,42 +0,0 @@ -package tun - -import ( - "fmt" - - "github.com/eycorsican/go-tun2socks/routes" - "github.com/vishvananda/netlink" - "golang.zx2c4.com/wireguard/tun" -) - -func setInterface(name, addr, gw, mask string, mtu int, tun *tun.NativeTun) error { - link, err := netlink.LinkByName(name) - if err != nil { - return fmt.Errorf("failed to detect %s interface: %s", name, err) - } - - err = netlink.LinkSetMTU(link, mtu) - if err != nil { - return fmt.Errorf("failed to set MTU on %s interface: %s", name, err) - } - - addrs, err := routes.ParseAddresses(addr, gw, mask) - if err != nil { - return err - } - - ipv4Addr := &netlink.Addr{ - IPNet: addrs[0], - Peer: addrs[1], - } - err = netlink.AddrAdd(link, ipv4Addr) - if err != nil { - return fmt.Errorf("failed to set peer address on %s interface: %s", name, err) - } - - err = netlink.LinkSetUp(link) - if err != nil { - return fmt.Errorf("failed to set %s interface up: %s", name, err) - } - - return nil -} diff --git a/tun/tun_unix.go b/tun/tun_unix.go deleted file mode 100644 index 6c11a1be..00000000 --- a/tun/tun_unix.go +++ /dev/null @@ -1,48 +0,0 @@ -// +build darwin freebsd - -package tun - -import ( - "fmt" - "os/exec" - - "github.com/eycorsican/go-tun2socks/routes" - "golang.zx2c4.com/wireguard/tun" -) - -func setInterface(name, addr, gw, mask string, mtu int, tun *tun.NativeTun) error { - addrs, err := routes.ParseAddresses(addr, gw, mask) - if err != nil { - return err - } - - args := []string{ - name, - "mtu", - fmt.Sprintf("%d", mtu), - } - v, err := exec.Command("ifconfig", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to set MTU: %s: %s: %s", args, v, err) - } - args = []string{ - name, - "inet", - addrs[0].String(), - addrs[1].IP.String(), - } - v, err = exec.Command("ifconfig", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to set ip addr: %s: %s: %s", args, v, err) - } - args = []string{ - name, - "up", - } - v, err = exec.Command("ifconfig", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to bring up interface: %s: %s: %s", args, v, err) - } - - return nil -} diff --git a/tun/tun_windows.go b/tun/tun_windows.go deleted file mode 100644 index 2d42c155..00000000 --- a/tun/tun_windows.go +++ /dev/null @@ -1,63 +0,0 @@ -package tun - -import ( - "fmt" - "net" - "os/exec" - - "github.com/eycorsican/go-tun2socks/routes" - "golang.zx2c4.com/wireguard/tun" -) - -type tunnel struct { - tun.Device -} - -func (t *tunnel) Read(b []byte) (int, error) { - return t.Device.Read(b, 0) -} - -func (t *tunnel) Write(b []byte) (int, error) { - return t.Device.Write(b, 0) -} - -func (t *tunnel) Close() error { - return t.Device.Close() -} - -func setInterface(name, addr, gw, mask string, mtu int, tun *tun.NativeTun) error { - args := []string{ - "interface", - "ipv4", - "set", - "subinterface", - name, - fmt.Sprintf("mtu=%d", mtu), - "store=persistent", - } - v, err := exec.Command("netsh.exe", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to set MTU on %s interface: %s: %s: %s", name, args, v, err) - } - - addrs, err := routes.ParseAddresses(addr, gw, mask) - if err != nil { - return err - } - args = []string{ - "interface", - "ipv4", - "set", - "address", - "name=" + name, - "static", - addrs[0].IP.String(), - net.IP(addrs[1].Mask).To4().String(), - } - v, err = exec.Command("netsh.exe", args...).CombinedOutput() - if err != nil { - return fmt.Errorf("failed to set tun interface: %s: %s: %s", args, v, err) - } - - return nil -}