mirror of
https://github.com/openp2p-cn/openp2p.git
synced 2026-04-22 15:37:25 +08:00
139 lines
2.8 KiB
Go
139 lines
2.8 KiB
Go
//go:build !android
|
|
// +build !android
|
|
|
|
// optun_linux.go
|
|
package openp2p
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
|
|
"github.com/openp2p-cn/wireguard-go/tun"
|
|
"github.com/vishvananda/netlink"
|
|
)
|
|
|
|
const (
|
|
tunIfaceName = "optun"
|
|
PIHeaderSize = 0
|
|
// sdwan
|
|
ReadTunBuffSize = 2048
|
|
ReadTunBuffNum = 16
|
|
)
|
|
|
|
var previousIP = ""
|
|
|
|
func (t *optun) Start(localAddr string, detail *SDWANInfo) error {
|
|
var err error
|
|
t.tunName = tunIfaceName
|
|
t.dev, err = tun.CreateTUN(t.tunName, int(detail.Mtu))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile("/proc/sys/net/ipv4/ip_forward", []byte("1"), 0644)
|
|
if err != nil {
|
|
gLog.e("write ip_forward error:%s", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (t *optun) Read(bufs [][]byte, sizes []int, offset int) (n int, err error) {
|
|
return t.dev.Read(bufs, sizes, offset)
|
|
}
|
|
|
|
func (t *optun) Write(bufs [][]byte, offset int) (int, error) {
|
|
return t.dev.Write(bufs, offset)
|
|
}
|
|
|
|
func setTunAddr(ifname, localAddr, remoteAddr string, wintun interface{}) error {
|
|
ifce, err := netlink.LinkByName(ifname)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
netlink.LinkSetMTU(ifce, int(gConf.getSDWAN().Mtu))
|
|
netlink.LinkSetTxQLen(ifce, 1000)
|
|
netlink.LinkSetUp(ifce)
|
|
|
|
ln, err := netlink.ParseIPNet(localAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ln.Mask = net.CIDRMask(32, 32)
|
|
rn, err := netlink.ParseIPNet(remoteAddr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
rn.Mask = net.CIDRMask(32, 32)
|
|
|
|
addr := &netlink.Addr{
|
|
IPNet: ln,
|
|
Peer: rn,
|
|
}
|
|
if previousIP != "" {
|
|
lnDel, err := netlink.ParseIPNet(previousIP)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
lnDel.Mask = net.CIDRMask(32, 32)
|
|
|
|
addrDel := &netlink.Addr{
|
|
IPNet: lnDel,
|
|
Peer: rn,
|
|
}
|
|
netlink.AddrDel(ifce, addrDel)
|
|
}
|
|
previousIP = localAddr
|
|
return netlink.AddrAdd(ifce, addr)
|
|
}
|
|
|
|
func addRoute(dst, gw, ifname string) error {
|
|
_, networkid, err := net.ParseCIDR(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ipGW := net.ParseIP(gw)
|
|
if ipGW == nil {
|
|
return fmt.Errorf("parse gateway %s failed", gw)
|
|
}
|
|
route := &netlink.Route{
|
|
Dst: networkid,
|
|
Gw: ipGW,
|
|
}
|
|
return netlink.RouteAdd(route)
|
|
}
|
|
|
|
func delRoute(dst, gw string) error {
|
|
_, networkid, err := net.ParseCIDR(dst)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
route := &netlink.Route{
|
|
Dst: networkid,
|
|
}
|
|
return netlink.RouteDel(route)
|
|
}
|
|
|
|
func delRoutesByGateway(gateway string) error {
|
|
ipGW := net.ParseIP(gateway)
|
|
if ipGW == nil {
|
|
return fmt.Errorf("invalid gateway IP: %s", gateway)
|
|
}
|
|
|
|
routes, err := netlink.RouteList(nil, netlink.FAMILY_V4)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to list routes: %v", err)
|
|
}
|
|
|
|
for _, route := range routes {
|
|
if route.Gw != nil && route.Gw.Equal(ipGW) || (route.Dst != nil && route.Dst.IP.Equal(ipGW)) {
|
|
err := netlink.RouteDel(&route)
|
|
if err != nil {
|
|
gLog.e("Failed to delete route: %v, error: %v", route, err)
|
|
continue
|
|
}
|
|
gLog.i("Deleted route: %v", route)
|
|
}
|
|
}
|
|
return nil
|
|
}
|