From 4d1928f1e3a4d2279d118c03426d8c17ef5724d0 Mon Sep 17 00:00:00 2001 From: Sebastien Bariteau Date: Wed, 26 Feb 2020 15:23:16 -0500 Subject: [PATCH] Support unsafe_routes on Windows (#184) * Support unsafe_routes on Windows * Full path to route executable * Escape string properly --- tun_windows.go | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/tun_windows.go b/tun_windows.go index ada043a..b15c1fc 100644 --- a/tun_windows.go +++ b/tun_windows.go @@ -4,14 +4,16 @@ import ( "fmt" "net" "os/exec" + "strconv" "github.com/songgao/water" ) type Tun struct { - Device string - Cidr *net.IPNet - MTU int + Device string + Cidr *net.IPNet + MTU int + UnsafeRoutes []route *water.Interface } @@ -20,13 +22,12 @@ func newTun(deviceName string, cidr *net.IPNet, defaultMTU int, routes []route, if len(routes) > 0 { return nil, fmt.Errorf("Route MTU not supported in Windows") } - if len(unsafeRoutes) > 0 { - return nil, fmt.Errorf("unsafeRoutes not supported in Windows") - } + // NOTE: You cannot set the deviceName under Windows, so you must check tun.Device after calling .Activate() return &Tun{ - Cidr: cidr, - MTU: defaultMTU, + Cidr: cidr, + MTU: defaultMTU, + UnsafeRoutes: unsafeRoutes, }, nil } @@ -66,6 +67,20 @@ func (c *Tun) Activate() error { return fmt.Errorf("failed to run 'netsh' to set MTU: %s", err) } + iface, err := net.InterfaceByName(c.Device) + if err != nil { + return fmt.Errorf("failed to find interface named %s: %v", c.Device, err) + } + + for _, r := range c.UnsafeRoutes { + err = exec.Command( + "C:\\Windows\\System32\\route.exe", "add", r.route.String(), r.via.String(), "IF", strconv.Itoa(iface.Index), + ).Run() + if err != nil { + return fmt.Errorf("failed to add the unsafe_route %s: %v", r.route.String(), err) + } + } + return nil }