Browse Source

Support unsafe_routes on Windows (#184)

* Support unsafe_routes on Windows

* Full path to route executable

* Escape string properly
Sebastien Bariteau 5 years ago
parent
commit
4d1928f1e3
1 changed files with 23 additions and 8 deletions
  1. 23 8
      tun_windows.go

+ 23 - 8
tun_windows.go

@@ -4,14 +4,16 @@ import (
 	"fmt"
 	"fmt"
 	"net"
 	"net"
 	"os/exec"
 	"os/exec"
+	"strconv"
 
 
 	"github.com/songgao/water"
 	"github.com/songgao/water"
 )
 )
 
 
 type Tun struct {
 type Tun struct {
-	Device string
-	Cidr   *net.IPNet
-	MTU    int
+	Device       string
+	Cidr         *net.IPNet
+	MTU          int
+	UnsafeRoutes []route
 
 
 	*water.Interface
 	*water.Interface
 }
 }
@@ -20,13 +22,12 @@ func newTun(deviceName string, cidr *net.IPNet, defaultMTU int, routes []route,
 	if len(routes) > 0 {
 	if len(routes) > 0 {
 		return nil, fmt.Errorf("Route MTU not supported in Windows")
 		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()
 	// NOTE: You cannot set the deviceName under Windows, so you must check tun.Device after calling .Activate()
 	return &Tun{
 	return &Tun{
-		Cidr: cidr,
-		MTU:  defaultMTU,
+		Cidr:         cidr,
+		MTU:          defaultMTU,
+		UnsafeRoutes: unsafeRoutes,
 	}, nil
 	}, nil
 }
 }
 
 
@@ -66,6 +67,20 @@ func (c *Tun) Activate() error {
 		return fmt.Errorf("failed to run 'netsh' to set MTU: %s", err)
 		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
 	return nil
 }
 }