From 58cb7e09a8265cff793732bd07a818e555ba2429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=BA=90=E6=96=87=E9=9B=A8?= <41315874+fumiama@users.noreply.github.com> Date: Wed, 17 Jul 2024 14:08:59 +0900 Subject: [PATCH] optimize(lower): nic route setting --- lower/nic.go | 30 +++++++++++++++++++----------- lower/tun_darwin.go | 13 ++++++++++--- lower/tun_linux.go | 4 +--- lower/tun_windows.go | 9 ++------- upper/services/wg/wg.go | 8 ++++++-- 5 files changed, 38 insertions(+), 26 deletions(-) diff --git a/lower/nic.go b/lower/nic.go index c9d416b..2d0f1c2 100644 --- a/lower/nic.go +++ b/lower/nic.go @@ -2,8 +2,10 @@ package lower import ( "io" + "net" "os" "os/exec" + "strconv" "github.com/fumiama/water" "github.com/sirupsen/logrus" @@ -17,29 +19,35 @@ type NICIO interface { // NIC 虚拟网卡 type NIC struct { - ifce *water.Interface - ip string - subnet string - mtu string - cidrs []string + ifce *water.Interface + ip net.IP + subnet *net.IPNet + rawipnet string + mtu string + cidrs []string } // NewNIC 新建 TUN 网络接口卡 // 网卡地址为 ip, 所属子网为 subnet // 以本网卡为下一跳的所有子网为 cidrs // cidrs 不包括本网卡 subnet -func NewNIC(ip, subnet, mtu string, cidrs ...string) NICIO { +func NewNIC(ip net.IP, subnet *net.IPNet, mtu string, cidrs ...string) NICIO { ifce, err := water.New(water.Config{DeviceType: water.TUN}) if err != nil { logrus.Error(err) os.Exit(1) } + subn, bitsn := subnet.Mask.Size() + if bitsn != 32 { + panic("mask len " + strconv.Itoa(bitsn) + " is not supported") + } n := &NIC{ - ifce: ifce, - ip: ip, - subnet: subnet, - mtu: mtu, - cidrs: cidrs, + ifce: ifce, + ip: ip, + subnet: subnet, + rawipnet: ip.String() + "/" + strconv.Itoa(subn), + mtu: mtu, + cidrs: cidrs, } return n } diff --git a/lower/tun_darwin.go b/lower/tun_darwin.go index 776ff67..9a72df4 100644 --- a/lower/tun_darwin.go +++ b/lower/tun_darwin.go @@ -3,17 +3,24 @@ package lower +import "net" + func (n *NIC) Up() { execute("ifconfig", n.ifce.Name(), "mtu", n.mtu) // max: 9159 - execute("ifconfig", n.ifce.Name(), "inet", n.ip, n.ip, "up") - execute("route", "add", n.subnet, "-interface", n.ifce.Name()) + execute( + "ifconfig", n.ifce.Name(), + "inet", n.ip.String(), n.ip.String(), + "netmask", (net.IP)(n.subnet.Mask).String(), + "up", + ) + execute("route", "add", n.subnet.String(), "-interface", n.ifce.Name()) for _, c := range n.cidrs { execute("route", "add", c, "-interface", n.ifce.Name()) } } func (n *NIC) Down() { - execute("route", "delete", n.subnet, "-interface", n.ifce.Name()) + execute("route", "delete", n.subnet.String(), "-interface", n.ifce.Name()) for _, c := range n.cidrs { execute("route", "delete", c, "-interface", n.ifce.Name()) } diff --git a/lower/tun_linux.go b/lower/tun_linux.go index 3dad251..145ecd1 100644 --- a/lower/tun_linux.go +++ b/lower/tun_linux.go @@ -5,16 +5,14 @@ package lower func (n *NIC) Up() { execute("/sbin/ip", "link", "set", "dev", n.ifce.Name(), "mtu", n.mtu) - execute("/sbin/ip", "addr", "add", n.ip, "dev", n.ifce.Name()) + execute("/sbin/ip", "addr", "add", n.rawipnet, "dev", n.ifce.Name()) execute("/sbin/ip", "link", "set", "dev", n.ifce.Name(), "up") - execute("/sbin/ip", "route", "add", n.subnet, "dev", n.ifce.Name()) for _, c := range n.cidrs { execute("/sbin/ip", "route", "add", c, "dev", n.ifce.Name()) } } func (n *NIC) Down() { - execute("/sbin/ip", "route", "del", n.subnet, "dev", n.ifce.Name()) for _, c := range n.cidrs { execute("/sbin/ip", "route", "del", c, "dev", n.ifce.Name()) } diff --git a/lower/tun_windows.go b/lower/tun_windows.go index bdbb625..f9a2851 100644 --- a/lower/tun_windows.go +++ b/lower/tun_windows.go @@ -6,19 +6,14 @@ package lower import "net" func (n *NIC) Up() { - // execute("netsh", "interface", "set", "interface", n.ifce.Name(), "enabled") - _, ipn, err := net.ParseCIDR(n.subnet) - if err != nil { - panic(err) - } - execute("cmd", "/c", "netsh interface ip set address name=\""+n.ifce.Name()+"\" source=static addr=\""+n.ip+"\" mask=\""+(net.IP)(ipn.Mask).String()+"\" gateway=none") + execute("cmd", "/c", "netsh interface ip set address name=\""+n.ifce.Name()+"\" source=static addr=\""+n.ip.String()+"\" mask=\""+(net.IP)(n.subnet.Mask).String()+"\" gateway=none") execute("cmd", "/c", "netsh interface ipv4 set subinterface \""+n.ifce.Name()+"\" mtu="+n.mtu) for _, c := range n.cidrs { ip, cidr, err := net.ParseCIDR(c) if err != nil { panic(err) } - execute("cmd", "/c", "route ADD "+ip.String()+" MASK "+(net.IP)(cidr.Mask).String()+" "+n.ip) + execute("cmd", "/c", "route ADD "+ip.String()+" MASK "+(net.IP)(cidr.Mask).String()+" "+n.ip.String()) } } diff --git a/upper/services/wg/wg.go b/upper/services/wg/wg.go index 29de02b..b3fb9db 100644 --- a/upper/services/wg/wg.go +++ b/upper/services/wg/wg.go @@ -72,6 +72,10 @@ func (wg *WG) init(srcport, dstport uint16) { if err != nil { panic(err) } + myip := net.ParseIP(wg.c.IP) + if myip == nil { + panic("invalid ip " + wg.c.IP) + } for _, p := range wg.c.Peers { for _, ip := range p.AllowedIPs { if len(ip) == 0 || ip[0] == 'x' { @@ -94,11 +98,11 @@ func (wg *WG) init(srcport, dstport uint16) { } wg.me = link.NewMe(&link.MyConfig{ - MyIPwithMask: wg.c.IP + "/32", + MyIPwithMask: myip.String() + "/32", MyEndpoint: wg.c.EndPoint, Network: wg.c.Network, PrivateKey: &wg.key, - NIC: lower.NewNIC(wg.c.IP, wg.c.SubNet, strconv.FormatInt(wg.c.MTU, 10), cidrs...), + NIC: lower.NewNIC(myip, mysubnet, strconv.FormatInt(wg.c.MTU, 10), cidrs...), SrcPort: srcport, DstPort: dstport, MTU: uint16(wg.c.MTU),