|
@@ -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
|
|
}
|
|
}
|
|
|
|
|