fix: 修复 Windows 端 IPv6 无法下行的问题
根因: netsh interface ipv6 命令参数名用错 - configureIPv6Addr: name= → interface=,IPv6 地址未实际分配到适配器 - SetMTU IPv6: name= → interface= 路由修复: - cidrToV6Prefix: 用 Mask.Size() 取前缀长度,修复 fmt.Sprintf(%d, mask) 输出字节切片的 bug - addRoute6/deleteRoute6: netsh → route -6,用 :: 作 on-link gateway - addRouteVia6/deleteRouteVia6: 加 -6 flag - defaultGateway6: route -6 print :: → route -6 print(避免过滤掉 ::/0) - applyFull: IPv6 bypass 路由失败不再阻断全隧道路由
This commit is contained in:
@@ -138,12 +138,14 @@ func (m *Manager) applyFull() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Bypass: server's public IPv6 via the original v6 gateway.
|
// Bypass: server's public IPv6 via the original v6 gateway.
|
||||||
|
// Non-fatal: if this fails, full-tunnel routes are still added.
|
||||||
if v6 != "" && gw6 != "" {
|
if v6 != "" && gw6 != "" {
|
||||||
bypassSpec := v6 + "/128"
|
bypassSpec := v6 + "/128"
|
||||||
if err := addRouteVia6(bypassSpec, gw6); err != nil {
|
if err := addRouteVia6(bypassSpec, gw6); err != nil {
|
||||||
return fmt.Errorf("add server bypass6 route: %w", err)
|
m.serverBypass6 = false
|
||||||
|
} else {
|
||||||
|
m.serverBypass6 = true
|
||||||
}
|
}
|
||||||
m.serverBypass6 = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two /1 routes cover the entire IPv4 space and are more specific
|
// Two /1 routes cover the entire IPv4 space and are more specific
|
||||||
|
|||||||
@@ -75,7 +75,8 @@ func cidrToV6Prefix(cidr string) (network, prefix string, err error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", err
|
return "", "", err
|
||||||
}
|
}
|
||||||
return ipNet.IP.String(), fmt.Sprintf("%d", ipNet.Mask), nil
|
ones, _ := ipNet.Mask.Size()
|
||||||
|
return ipNet.IP.String(), fmt.Sprintf("%d", ones), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRoute6(cidr, iface string) error {
|
func addRoute6(cidr, iface string) error {
|
||||||
@@ -87,8 +88,8 @@ func addRoute6(cidr, iface string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return runCmd("netsh", "interface", "ipv6", "add", "route",
|
return runCmd("route", "-6", "add", network+"/"+prefix, "::",
|
||||||
network+"/"+prefix, "interface="+fmt.Sprintf("%d", idx), "metric=1")
|
"if", fmt.Sprintf("%d", idx), "metric", "1")
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteRoute6(cidr, iface string) error {
|
func deleteRoute6(cidr, iface string) error {
|
||||||
@@ -96,12 +97,7 @@ func deleteRoute6(cidr, iface string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
idx, err := ifaceIndex(iface)
|
return runCmd("route", "-6", "delete", network+"/"+prefix, "::")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return runCmd("netsh", "interface", "ipv6", "delete", "route",
|
|
||||||
network+"/"+prefix, "interface="+fmt.Sprintf("%d", idx))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func addRouteVia6(cidr, gateway string) error {
|
func addRouteVia6(cidr, gateway string) error {
|
||||||
@@ -109,8 +105,7 @@ func addRouteVia6(cidr, gateway string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return runCmd("netsh", "interface", "ipv6", "add", "route",
|
return runCmd("route", "-6", "add", network+"/"+prefix, gateway, "metric", "1")
|
||||||
network+"/"+prefix, gateway, "metric=1")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteRouteVia6(cidr, gateway string) error {
|
func deleteRouteVia6(cidr, gateway string) error {
|
||||||
@@ -118,8 +113,7 @@ func deleteRouteVia6(cidr, gateway string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return runCmd("netsh", "interface", "ipv6", "delete", "route",
|
return runCmd("route", "-6", "delete", network+"/"+prefix, gateway)
|
||||||
network+"/"+prefix, gateway)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- Default gateway ---
|
// --- Default gateway ---
|
||||||
@@ -133,7 +127,7 @@ func defaultGateway() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func defaultGateway6() (string, error) {
|
func defaultGateway6() (string, error) {
|
||||||
out, err := exec.Command("route", "-6", "print", "::").Output()
|
out, err := exec.Command("route", "-6", "print").Output()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,12 +116,16 @@ func (d *wintunDevice) ConfigureIPv6(localIP6 net.IP, prefix6 int) error {
|
|||||||
func (d *wintunDevice) configureIPv6Addr(ip net.IP, prefix int) error {
|
func (d *wintunDevice) configureIPv6Addr(ip net.IP, prefix int) error {
|
||||||
addr := fmt.Sprintf("%s/%d", ip.String(), prefix)
|
addr := fmt.Sprintf("%s/%d", ip.String(), prefix)
|
||||||
return execCmd("netsh", "interface", "ipv6", "add", "address",
|
return execCmd("netsh", "interface", "ipv6", "add", "address",
|
||||||
"name="+d.name, "address="+addr)
|
"interface="+d.name, "address="+addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *wintunDevice) SetMTU(mtu int) error {
|
func (d *wintunDevice) SetMTU(mtu int) error {
|
||||||
return execCmd("netsh", "interface", "ipv4", "set", "subinterface",
|
if err := execCmd("netsh", "interface", "ipv4", "set", "subinterface",
|
||||||
"name="+d.name, fmt.Sprintf("mtu=%d", mtu))
|
"name="+d.name, fmt.Sprintf("mtu=%d", mtu)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return execCmd("netsh", "interface", "ipv6", "set", "subinterface",
|
||||||
|
"interface="+d.name, fmt.Sprintf("mtu=%d", mtu))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ensureWintunDLL extracts the embedded wintun.dll to the executable's
|
// ensureWintunDLL extracts the embedded wintun.dll to the executable's
|
||||||
|
|||||||
Reference in New Issue
Block a user